ReactOS 0.4.15-dev-7788-g1ad9096
protos.h File Reference
#include "mem.h"
#include "namesup.h"
Include dependency graph for protos.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define UDF_CLOSE_NTREQFCB_DELETED   0x01
 
#define UDF_CLOSE_FCB_DELETED   0x02
 
#define UDFCloseAllDelayedInDir(Vcb, FI)    UDFCloseAllXXXDelayedInDir(Vcb,FI,FALSE);
 
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)    UDFCloseAllXXXDelayedInDir(Vcb,FI,TRUE);
 
#define UDFRemoveFromDelayedQueue(Fcb)    UDFCloseAllDelayedInDir((Fcb)->Vcb, (Fcb)->FileInfo)
 
#define UDFRemoveFromSystemDelayedQueue(Fcb)    UDFCloseAllSystemDelayedInDir((Fcb)->Vcb, (Fcb)->FileInfo)
 
#define UDFRemoveFileId__(Vcb, fi)    UDFRemoveFileId(Vcb, UDFGetNTFileId(Vcb, fi, &(fi->Fcb->FCBName->ObjectName)));
 
#define UDFZeroDataEx(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)    UDFPurgeCacheEx_(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)
 
#define UDFPurgeCacheEx(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)    UDFPurgeCacheEx_(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)
 

Functions

NTSTATUS NTAPI UDFCreate (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS UDFCommonCreate (IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
 
NTSTATUS UDFFirstOpenFile (IN PVCB Vcb, IN PFILE_OBJECT PtrNewFileObject, OUT PtrUDFFCB *PtrNewFcb, IN PUDF_FILE_INFO RelatedFileInfo, IN PUDF_FILE_INFO NewFileInfo, IN PUNICODE_STRING LocalPath, IN PUNICODE_STRING CurName)
 
NTSTATUS UDFOpenFile (IN PVCB Vcb, IN PFILE_OBJECT PtrNewFileObject, IN PtrUDFFCB PtrNewFcb)
 
NTSTATUS UDFInitializeFCB (IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
 
NTSTATUS NTAPI UDFCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonCleanup (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFCloseFileInfoChain (IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
 
NTSTATUS NTAPI UDFClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonClose (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
ULONG UDFCleanUpFcbChain (IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
 
VOID UDFCloseAllDelayed (PVCB Vcb)
 
VOID NTAPI UDFDelayedClose (PVOID unused=NULL)
 
NTSTATUS UDFCloseAllXXXDelayedInDir (IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN System)
 
NTSTATUS UDFQueueDelayedClose (PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
 
NTSTATUS NTAPI UDFDirControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI UDFCommonDirControl (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFQueryDirectory (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, PFILE_OBJECT FileObject, PtrUDFFCB Fcb, PtrUDFCCB Ccb)
 
NTSTATUS NTAPI UDFNotifyChangeDirectory (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, PFILE_OBJECT FileObject, PtrUDFFCB Fcb, PtrUDFCCB Ccb)
 
NTSTATUS NTAPI UDFDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI UDFCommonDeviceControl (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFDevIoctlCompletion (PDEVICE_OBJECT PtrDeviceObject, PIRP Irp, PVOID Context)
 
NTSTATUS NTAPI UDFHandleQueryPath (PVOID BufferPointer)
 
BOOLEAN NTAPI UDFFastIoCheckIfPossible (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible (IN PtrUDFFCB Fcb)
 
BOOLEAN NTAPI UDFFastIoQueryBasicInfo (IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI UDFFastIoQueryStdInfo (IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI UDFFastIoAcqCreateSec (IN PFILE_OBJECT FileObject)
 
VOID NTAPI UDFFastIoRelCreateSec (IN PFILE_OBJECT FileObject)
 
BOOLEAN NTAPI UDFAcqLazyWrite (IN PVOID Context, IN BOOLEAN Wait)
 
VOID NTAPI UDFRelLazyWrite (IN PVOID Context)
 
BOOLEAN NTAPI UDFAcqReadAhead (IN PVOID Context, IN BOOLEAN Wait)
 
VOID NTAPI UDFRelReadAhead (IN PVOID Context)
 
VOID NTAPI UDFDriverUnload (IN PDRIVER_OBJECT DriverObject)
 
NTSTATUS NTAPI UDFFileInfo (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonFileInfo (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFGetBasicInformation (IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
 
NTSTATUS UDFGetNetworkInformation (IN PtrUDFFCB Fcb, IN PFILE_NETWORK_OPEN_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetStandardInformation (IN PtrUDFFCB Fcb, IN PFILE_STANDARD_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetInternalInformation (PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_INTERNAL_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetEaInformation (PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PFILE_EA_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetFullNameInformation (IN PFILE_OBJECT FileObject, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetAltNameInformation (IN PtrUDFFCB Fcb, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetPositionInformation (IN PFILE_OBJECT FileObject, IN PFILE_POSITION_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFGetFileStreamInformation (IN PtrUDFFCB Fcb, IN PFILE_STREAM_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
 
NTSTATUS UDFSetBasicInformation (IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_OBJECT FileObject, IN PFILE_BASIC_INFORMATION PtrBuffer)
 
NTSTATUS UDFMarkStreamsForDeletion (IN PVCB Vcb, IN PtrUDFFCB Fcb, IN BOOLEAN ForDel)
 
NTSTATUS UDFSetDispositionInformation (IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN BOOLEAN Delete)
 
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)
 
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)
 
NTSTATUS UDFRename (IN PIO_STACK_LOCATION IrpSp, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_OBJECT FileObject, IN PFILE_RENAME_INFORMATION PtrBuffer)
 
NTSTATUS UDFStoreFileId (IN PVCB Vcb, IN PtrUDFCCB Ccb, IN PUDF_FILE_INFO fi, IN LONGLONG Id)
 
NTSTATUS UDFRemoveFileId (IN PVCB Vcb, IN LONGLONG Id)
 
VOID UDFReleaseFileIdCache (IN PVCB Vcb)
 
NTSTATUS UDFGetOpenParamsByFileId (IN PVCB Vcb, IN LONGLONG Id, OUT PUNICODE_STRING *FName, OUT BOOLEAN *CaseSens)
 
NTSTATUS UDFHardLink (IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb1, IN PtrUDFCCB Ccb1, IN PFILE_OBJECT FileObject1, IN PFILE_LINK_INFORMATION PtrBuffer)
 
NTSTATUS NTAPI UDFFlush (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonFlush (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
ULONG UDFFlushAFile (PtrUDFFCB Fcb, PtrUDFCCB Ccb, PIO_STATUS_BLOCK PtrIoStatus, IN ULONG FlushFlags=0)
 
ULONG UDFFlushADirectory (IN PVCB Vcb, IN PUDF_FILE_INFO FI, OUT PIO_STATUS_BLOCK PtrIoStatus, ULONG FlushFlags=0)
 
ULONG UDFFlushLogicalVolume (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVCB Vcb, ULONG FlushFlags=0)
 
NTSTATUS NTAPI UDFFlushCompletion (PDEVICE_OBJECT PtrDeviceObject, PIRP Irp, PVOID Context)
 
BOOLEAN UDFFlushIsBreaking (IN PVCB Vcb, IN ULONG FlushFlags=0)
 
VOID UDFFlushTryBreak (IN PVCB Vcb)
 
NTSTATUS NTAPI UDFFSControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS NTAPI UDFCommonFSControl (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFUserFsCtrlRequest (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFMountVolume (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFStartEjectWaiter (IN PVCB Vcb)
 
VOID UDFScanForDismountedVcb (IN PtrUDFIrpContext IrpContext)
 
NTSTATUS UDFCompleteMount (IN PVCB Vcb)
 
VOID UDFCloseResidual (IN PVCB Vcb)
 
VOID UDFCleanupVCB (IN PVCB Vcb)
 
NTSTATUS UDFIsVolumeMounted (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFIsVolumeDirty (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFGetStatistics (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFLockVolume (IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID=-1)
 
NTSTATUS UDFUnlockVolume (IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID=-1)
 
NTSTATUS UDFIsPathnameValid (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFDismountVolume (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFGetVolumeBitmap (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS UDFGetRetrievalPointers (IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG Special)
 
NTSTATUS UDFInvalidateVolumes (IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
 
NTSTATUS NTAPI UDFLockControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
NTSTATUS NTAPI UDFCommonLockControl (IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
 
BOOLEAN NTAPI UDFFastLock (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI UDFFastUnlockSingle (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI UDFFastUnlockAll (IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
BOOLEAN NTAPI UDFFastUnlockAllByKey (IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS UDFInitializeZones (VOID)
 
VOID UDFDestroyZones (VOID)
 
BOOLEAN __fastcall UDFIsIrpTopLevel (PIRP Irp)
 
long UDFExceptionFilter (PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
 
NTSTATUS UDFExceptionHandler (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
VOID UDFLogEvent (NTSTATUS UDFEventLogId, NTSTATUS RC)
 
PtrUDFObjectName UDFAllocateObjectName (VOID)
 
VOID __fastcall UDFReleaseObjectName (PtrUDFObjectName PtrObjectName)
 
PtrUDFCCB UDFAllocateCCB (VOID)
 
VOID __fastcall UDFReleaseCCB (PtrUDFCCB Ccb)
 
VOID __fastcall UDFCleanUpCCB (PtrUDFCCB Ccb)
 
PtrUDFFCB UDFAllocateFCB (VOID)
 
__inline VOID UDFReleaseFCB (PtrUDFFCB Fcb)
 
VOID __fastcall UDFCleanUpFCB (PtrUDFFCB Fcb)
 
PtrUDFIrpContext UDFAllocateIrpContext (PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
 
VOID UDFReleaseIrpContext (PtrUDFIrpContext PtrIrpContext)
 
NTSTATUS UDFPostRequest (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
VOID NTAPI UDFCommonDispatch (VOID *Context)
 
NTSTATUS UDFInitializeVCB (PDEVICE_OBJECT PtrVolumeDeviceObject, PDEVICE_OBJECT PtrTargetDeviceObject, PVPB PtrVPB)
 
VOID UDFReadRegKeys (PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg)
 
ULONG UDFGetRegParameter (IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue=0)
 
ULONG UDFGetCfgParameter (IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
 
VOID UDFReleaseVCB (PVCB Vcb)
 
ULONG UDFRegCheckParameterValue (IN PUNICODE_STRING RegistryPath, IN PCWSTR Name, IN PUNICODE_STRING PtrVolumePath, IN PCWSTR DefaultPath, IN ULONG DefValue=0)
 
VOID UDFInitializeIrpContextFromLite (OUT PtrUDFIrpContext *IrpContext, IN PtrUDFIrpContextLite IrpContextLite)
 
NTSTATUS UDFInitializeIrpContextLite (OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
 
NTSTATUS NTAPI UDFQuerySetEA (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
ULONG UDFIsResourceAcquired (IN PERESOURCE Resource)
 
BOOLEAN UDFAcquireResourceExclusiveWithCheck (IN PERESOURCE Resource)
 
BOOLEAN UDFAcquireResourceSharedWithCheck (IN PERESOURCE Resource)
 
NTSTATUS UDFWCacheErrorHandler (IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
 
NTSTATUS UDFPnp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
OSSTATUS NTAPI UDFRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFPostStackOverflowRead (IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PtrUDFFCB Fcb)
 
VOID NTAPI UDFStackOverflowRead (IN PVOID Context, IN PKEVENT Event)
 
NTSTATUS UDFCommonRead (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
PVOID UDFGetCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFLockCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
 
NTSTATUS UDFUnlockCallersBuffer (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
 
VOID UDFMdlComplete (PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
 
NTSTATUS UDFGetSecurity (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFSetSecurity (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonGetSecurity (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFCommonSetSecurity (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS UDFReadSecurity (IN PVCB Vcb, IN PtrUDFFCB Fcb, IN PSECURITY_DESCRIPTOR *SecurityDesc)
 
NTSTATUS UDFAssignAcl (IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PtrUDFNTRequiredFCB NtReqFcb)
 
VOID UDFDeassignAcl (IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
 
NTSTATUS UDFWriteSecurity (IN PVCB Vcb, IN PtrUDFFCB Fcb, IN PSECURITY_DESCRIPTOR *SecurityDesc)
 
NTSTATUS UDFCheckAccessRights (PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
 
NTSTATUS UDFSetAccessRights (PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
 
NTSTATUS NTAPI UDFShutdown (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonShutdown (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
BOOLEAN UDFDebugAcquireResourceSharedLite (IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line)
 
BOOLEAN UDFDebugAcquireSharedStarveExclusive (IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line)
 
BOOLEAN UDFDebugAcquireResourceExclusiveLite (IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line)
 
VOID UDFDebugReleaseResourceForThreadLite (IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line)
 
VOID UDFDebugDeleteResource (IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line)
 
NTSTATUS UDFDebugInitializeResourceLite (IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line)
 
VOID UDFDebugConvertExclusiveToSharedLite (IN PERESOURCE Resource, IN ERESOURCE_THREAD ResourceThreadId, ULONG BugCheckId, ULONG Line)
 
BOOLEAN UDFDebugAcquireSharedWaitForExclusive (IN PERESOURCE Resource, IN BOOLEAN Wait, ULONG BugCheckId, ULONG Line)
 
LONG UDFDebugInterlockedIncrement (IN PLONG addr, ULONG BugCheckId, ULONG Line)
 
LONG UDFDebugInterlockedDecrement (IN PLONG addr, ULONG BugCheckId, ULONG Line)
 
LONG UDFDebugInterlockedExchangeAdd (IN PLONG addr, IN LONG i, ULONG BugCheckId, ULONG Line)
 
NTSTATUS NTAPI DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
 
VOID NTAPI UDFInitializeFunctionPointers (PDRIVER_OBJECT DriverObject)
 
VOID NTAPI UDFFsNotification (IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FsActive)
 
BOOLEAN UDFGetInstallVersion (PULONG iVer)
 
BOOLEAN UDFGetInstallTime (PULONG iTime)
 
BOOLEAN UDFGetTrialEnd (PULONG iTrial)
 
NTSTATUS UDFVerifyVcb (IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
 
NTSTATUS UDFVerifyVolume (IN PIRP Irp)
 
NTSTATUS UDFPerformVerify (IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
 
BOOLEAN UDFCheckForDismount (IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
 
BOOLEAN UDFDismountVcb (IN PVCB Vcb, IN BOOLEAN VcbAcquired)
 
NTSTATUS UDFCompareVcb (IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
 
NTSTATUS NTAPI UDFQueryVolInfo (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonQueryVolInfo (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFSetVolInfo (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonSetVolInfo (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
NTSTATUS NTAPI UDFWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS UDFCommonWrite (PtrUDFIrpContext PtrIrpContext, PIRP Irp)
 
VOID NTAPI UDFDeferredWriteCallBack (VOID *Context1, VOID *Context2)
 
VOID UDFPurgeCacheEx_ (PtrUDFNTRequiredFCB NtReqFcb, LONGLONG Offset, LONGLONG Length, BOOLEAN CanWait, PVCB Vcb, PFILE_OBJECT FileObject)
 

Macro Definition Documentation

◆ UDF_CLOSE_FCB_DELETED

#define UDF_CLOSE_FCB_DELETED   0x02

Definition at line 81 of file protos.h.

◆ UDF_CLOSE_NTREQFCB_DELETED

#define UDF_CLOSE_NTREQFCB_DELETED   0x01

Definition at line 80 of file protos.h.

◆ UDFCloseAllDelayedInDir

#define UDFCloseAllDelayedInDir (   Vcb,
  FI 
)     UDFCloseAllXXXDelayedInDir(Vcb,FI,FALSE);

Definition at line 96 of file protos.h.

◆ UDFCloseAllSystemDelayedInDir

#define UDFCloseAllSystemDelayedInDir (   Vcb,
  FI 
)     UDFCloseAllXXXDelayedInDir(Vcb,FI,TRUE);

Definition at line 99 of file protos.h.

◆ UDFPurgeCacheEx

#define UDFPurgeCacheEx (   NtReqFcb,
  Offset,
  Length,
  CanWait,
  Vcb,
  FileObject 
)     UDFPurgeCacheEx_(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)

Definition at line 1148 of file protos.h.

◆ UDFRemoveFileId__

#define UDFRemoveFileId__ (   Vcb,
  fi 
)     UDFRemoveFileId(Vcb, UDFGetNTFileId(Vcb, fi, &(fi->Fcb->FCBName->ObjectName)));

Definition at line 407 of file protos.h.

◆ UDFRemoveFromDelayedQueue

#define UDFRemoveFromDelayedQueue (   Fcb)     UDFCloseAllDelayedInDir((Fcb)->Vcb, (Fcb)->FileInfo)

Definition at line 106 of file protos.h.

◆ UDFRemoveFromSystemDelayedQueue

#define UDFRemoveFromSystemDelayedQueue (   Fcb)     UDFCloseAllSystemDelayedInDir((Fcb)->Vcb, (Fcb)->FileInfo)

Definition at line 109 of file protos.h.

◆ UDFZeroDataEx

#define UDFZeroDataEx (   NtReqFcb,
  Offset,
  Length,
  CanWait,
  Vcb,
  FileObject 
)     UDFPurgeCacheEx_(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)

Definition at line 1146 of file protos.h.

Function Documentation

◆ DriverEntry()

NTSTATUS NTAPI DriverEntry ( PDRIVER_OBJECT  DriverObject,
PUNICODE_STRING  RegistryPath 
)

Definition at line 16 of file battc.c.

18{
19 DPRINT("Battery class driver initialized\n");
20
21 return STATUS_SUCCESS;
22}
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71

◆ UDFAcqLazyWrite()

BOOLEAN NTAPI UDFAcqLazyWrite ( IN PVOID  Context,
IN BOOLEAN  Wait 
)

Definition at line 423 of file fastio.cpp.

426{
427 // The context is whatever we passed to the Cache Manager when invoking
428 // the CcInitializeCacheMaps() function. In the case of the UDF FSD
429 // implementation, this context is a pointer to the NT_REQ_FCB structure.
431
432 MmPrint((" UDFAcqLazyWrite()\n"));
433
434 // Acquire the PagingIoResource in the NT_REQ_FCB exclusively. Then, set the
435 // lazy-writer thread id in the NT_REQ_FCB structure for identification
436 // when an actual write request is received by the FSD.
437 // Note: The lazy-writer typically always supplies WAIT set to TRUE.
438 if (!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), Wait))
439 return FALSE;
440
441 // Now, set the lazy-writer thread id.
442 ASSERT(!(NtReqFcb->LazyWriterThreadID));
443 NtReqFcb->LazyWriterThreadID = HandleToUlong(PsGetCurrentThreadId());
444
447
448 // If our FSD needs to perform some special preparations in anticipation
449 // of receving a lazy-writer request, do so now.
450 return TRUE;
451} // end UDFAcqLazyWrite()
#define HandleToUlong(h)
Definition: basetsd.h:79
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define UDFAcquireResourceExclusive(Resource, CanWait)
Definition: env_spec_w32.h:656
#define MmPrint(_x_)
Definition: env_spec_w32.h:289
#define NtReqFcb
PsGetCurrentThreadId
Definition: CrNtStubs.h:8
#define FSRTL_CACHE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:60
#define ASSERT(a)
Definition: mode.c:44
PIRP NTAPI IoGetTopLevelIrp(VOID)
Definition: irp.c:1843
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
struct _UDFNTRequiredFCB * PtrUDFNTRequiredFCB
_In_ WDFDPC _In_ BOOLEAN Wait
Definition: wdfdpc.h:170

Referenced by UDFInitializeFunctionPointers().

◆ UDFAcqReadAhead()

BOOLEAN NTAPI UDFAcqReadAhead ( IN PVOID  Context,
IN BOOLEAN  Wait 
)

Definition at line 514 of file fastio.cpp.

518{
519 // The context is whatever we passed to the Cache Manager when invoking
520 // the CcInitializeCacheMaps() function. In the case of the UDF FSD
521 // implementation, this context is a pointer to the NT_REQ_FCB structure.
522#define NtReqFcb ((PtrUDFNTRequiredFCB)Context)
523
524 MmPrint((" AcqForReadAhead()\n"));
525
526 // Acquire the MainResource in the NT_REQ_FCB shared.
527 // Note: The read-ahead thread typically always supplies WAIT set to TRUE.
529 if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait))
530 return FALSE;
531
534
535 return TRUE;
536#undef NtReqFcb
537
538} // end UDFAcqReadAhead()
#define UDFAcquireResourceShared(Resource, CanWait)
Definition: env_spec_w32.h:658
#define UDF_CHECK_PAGING_IO_RESOURCE(NTReqFCB)
Definition: udffs.h:262

Referenced by UDFInitializeFunctionPointers().

◆ UDFAcquireResourceExclusiveWithCheck()

BOOLEAN UDFAcquireResourceExclusiveWithCheck ( IN PERESOURCE  Resource)

Definition at line 2529 of file misc.cpp.

2532{
2533 ULONG ReAcqRes =
2536 if(ReAcqRes) {
2537 UDFPrint(("UDFAcquireResourceExclusiveWithCheck: ReAcqRes, %x\n", ReAcqRes));
2538 } else {
2539// BrutePoint();
2540 }
2541
2542 if(ReAcqRes == 1) {
2543 // OK
2544 } else
2545 if(ReAcqRes == 2) {
2546 UDFPrint(("UDFAcquireResourceExclusiveWithCheck: !!! Shared !!!\n"));
2547 //BrutePoint();
2548 } else {
2550 return TRUE;
2551 }
2552 return FALSE;
2553} // end UDFAcquireResourceExclusiveWithCheck()
_Acquires_exclusive_lock_ Resource _Acquires_shared_lock_ Resource _Inout_ PERESOURCE Resource
Definition: cdprocs.h:843
BOOLEAN NTAPI ExIsResourceAcquiredExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:1624
ULONG NTAPI ExIsResourceAcquiredSharedLite(IN PERESOURCE Resource)
Definition: resource.c:1663
uint32_t ULONG
Definition: typedefs.h:59
#define UDFPrint(Args)
Definition: udffs.h:225

Referenced by UDFCommonCleanup(), UDFCommonWrite(), UDFSetAllocationInformation(), UDFSetEOF(), and UDFTSendIOCTL().

◆ UDFAcquireResourceSharedWithCheck()

BOOLEAN UDFAcquireResourceSharedWithCheck ( IN PERESOURCE  Resource)

Definition at line 2556 of file misc.cpp.

2559{
2560 ULONG ReAcqRes =
2563 if(ReAcqRes) {
2564 UDFPrint(("UDFAcquireResourceSharedWithCheck: ReAcqRes, %x\n", ReAcqRes));
2565/* } else {
2566 BrutePoint();*/
2567 }
2568
2569 if(ReAcqRes == 2) {
2570 // OK
2571 } else
2572 if(ReAcqRes == 1) {
2573 UDFPrint(("UDFAcquireResourceSharedWithCheck: Exclusive\n"));
2574 //BrutePoint();
2575 } else {
2577 return TRUE;
2578 }
2579 return FALSE;
2580} // end UDFAcquireResourceSharedWithCheck()

Referenced by UDFCommonRead().

◆ UDFAllocateCCB()

PtrUDFCCB UDFAllocateCCB ( VOID  )

Definition at line 707 of file misc.cpp.

708{
710 BOOLEAN AllocatedFromZone = TRUE;
711 KIRQL CurrentIrql;
712
713 // first, __try to allocate out of the zone
714 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
715 if (!ExIsFullZone(&(UDFGlobalData.CCBZoneHeader))) {
716 // we have enough memory
717 Ccb = (PtrUDFCCB)ExAllocateFromZone(&(UDFGlobalData.CCBZoneHeader));
718
719 // release the spinlock
720 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
721 } else {
722 // release the spinlock
723 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
724
725 // if we failed to obtain from the zone, get it directly from the VMM
727 AllocatedFromZone = FALSE;
728// UDFPrint((" CCB allocated @%x\n",Ccb));
729 }
730
731 if (!Ccb) {
732 return NULL;
733 }
734
735 // zero out the allocated memory block
737
738 // set up some fields ...
739 Ccb->NodeIdentifier.NodeType = UDF_NODE_TYPE_CCB;
740 Ccb->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFCCB));
741
742
743 if (!AllocatedFromZone) {
745 }
746
747 UDFPrint(("UDFAllocateCCB: %x\n", Ccb));
748 return(Ccb);
749} // end UDFAllocateCCB()
unsigned char BOOLEAN
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:592
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define NonPagedPool
Definition: env_spec_w32.h:307
#define MyAllocatePool__(type, size)
Definition: mem_tools.h:149
#define UDF_CCB_NOT_FROM_ZONE
Definition: struct.h:175
#define UDF_NODE_TYPE_CCB
Definition: struct.h:59
struct _UDFContextControlBlock * PtrUDFCCB
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define UDFQuadAlign(Value)
Definition: udffs.h:196
#define UDFSetFlag(Flag, Value)
Definition: udffs.h:191
UDFData UDFGlobalData
Definition: udfinit.cpp:25
#define ExIsFullZone(Zone)
Definition: exfuncs.h:329

Referenced by UDFOpenFile().

◆ UDFAllocateFCB()

PtrUDFFCB UDFAllocateFCB ( VOID  )

Definition at line 854 of file misc.cpp.

855{
857
859
860 if (!Fcb) {
861 return NULL;
862 }
863
864 // zero out the allocated memory block
866
867 // set up some fields ...
868 Fcb->NodeIdentifier.NodeType = UDF_NODE_TYPE_FCB;
869 Fcb->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFFCB));
870
871 UDFPrint(("UDFAllocateFCB: %x\n", Fcb));
872 return(Fcb);
873} // end UDFAllocateFCB()
_In_ PFCB Fcb
Definition: cdprocs.h:159
struct _UDFFileControlBlock * PtrUDFFCB
#define UDF_NODE_TYPE_FCB
Definition: struct.h:60
#define UDF_FCB_MT
Definition: struct.h:241

Referenced by UDFBlankMount(), UDFCompleteMount(), and UDFFirstOpenFile().

◆ UDFAllocateIrpContext()

PtrUDFIrpContext UDFAllocateIrpContext ( PIRP  Irp,
PDEVICE_OBJECT  PtrTargetDeviceObject 
)

Definition at line 985 of file misc.cpp.

989{
990 PtrUDFIrpContext PtrIrpContext = NULL;
991 BOOLEAN AllocatedFromZone = TRUE;
992 KIRQL CurrentIrql;
994
995 // first, __try to allocate out of the zone
996 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
997 if (!ExIsFullZone(&(UDFGlobalData.IrpContextZoneHeader))) {
998 // we have enough memory
999 PtrIrpContext = (PtrUDFIrpContext)ExAllocateFromZone(&(UDFGlobalData.IrpContextZoneHeader));
1000
1001 // release the spinlock
1002 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1003 } else {
1004 // release the spinlock
1005 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1006
1007 // if we failed to obtain from the zone, get it directly from the VMM
1009 AllocatedFromZone = FALSE;
1010 }
1011
1012 // if we could not obtain the required memory, bug-check.
1013 // Do NOT do this in your commercial driver, instead handle the error gracefully ...
1014 if (!PtrIrpContext) {
1015 return NULL;
1016 }
1017
1018#ifdef UDF_DBG
1019 IrpContextCounter++;
1020#endif //UDF_DBG
1021
1022 // zero out the allocated memory block
1023 RtlZeroMemory(PtrIrpContext, UDFQuadAlign(sizeof(UDFIrpContext)));
1024
1025 // set up some fields ...
1027 PtrIrpContext->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFIrpContext));
1028
1029
1030 PtrIrpContext->Irp = Irp;
1031 PtrIrpContext->TargetDeviceObject = PtrTargetDeviceObject;
1032
1033 // copy over some fields from the IRP and set appropriate flag values
1034 if (Irp) {
1036 ASSERT(IrpSp);
1037
1038 PtrIrpContext->MajorFunction = IrpSp->MajorFunction;
1039 PtrIrpContext->MinorFunction = IrpSp->MinorFunction;
1040
1041 // Often, a FSD cannot honor a request for asynchronous processing
1042 // of certain critical requests. For example, a "close" request on
1043 // a file object can typically never be deferred. Therefore, do not
1044 // be surprised if sometimes our FSD (just like all other FSD
1045 // implementations on the Windows NT system) has to override the flag
1046 // below.
1047 if (IrpSp->FileObject == NULL) {
1049 } else {
1052 }
1053 }
1054 }
1055
1056 if (!AllocatedFromZone) {
1058 }
1059
1060 // Are we top-level ? This information is used by the dispatching code
1061 // later (and also by the FSD dispatch routine)
1062 if (IoGetTopLevelIrp() != Irp) {
1063 // We are not top-level. Note this fact in the context structure
1065 }
1066
1067 return(PtrIrpContext);
1068} // end UDFAllocateIrpContext()
_In_ PIRP Irp
Definition: csq.h:116
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
BOOLEAN NTAPI IoIsOperationSynchronous(IN PIRP Irp)
Definition: irp.c:1882
#define UDF_IRP_CONTEXT_NOT_TOP_LEVEL
Definition: struct.h:390
#define UDF_IRP_CONTEXT_CAN_BLOCK
Definition: struct.h:385
struct _UDFIrpContext * PtrUDFIrpContext
#define UDF_IRP_CONTEXT_NOT_FROM_ZONE
Definition: struct.h:399
#define UDF_NODE_TYPE_IRP_CONTEXT
Definition: struct.h:62
PFILE_OBJECT FileObject
Definition: iotypes.h:3169
uint32 NodeType
Definition: struct.h:75
uint32 NodeSize
Definition: struct.h:76
UDFIdentifier NodeIdentifier
Definition: struct.h:363
uint32 IrpContextFlags
Definition: struct.h:364
uint8 MinorFunction
Definition: struct.h:368
uint8 MajorFunction
Definition: struct.h:366
PDEVICE_OBJECT TargetDeviceObject
Definition: struct.h:374
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793

Referenced by UDFCleanup(), UDFClose(), UDFCreate(), UDFDeviceControl(), UDFDirControl(), UDFFileInfo(), UDFFlush(), UDFFSControl(), UDFInitializeIrpContextFromLite(), UDFLockControl(), UDFPnp(), UDFQueryVolInfo(), UDFRead(), UDFSetVolInfo(), UDFShutdown(), and UDFWrite().

◆ UDFAllocateObjectName()

PtrUDFObjectName UDFAllocateObjectName ( VOID  )

Definition at line 611 of file misc.cpp.

612{
613 PtrUDFObjectName PtrObjectName = NULL;
614 BOOLEAN AllocatedFromZone = TRUE;
615 KIRQL CurrentIrql;
616
617 // first, __try to allocate out of the zone
618 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
619 if (!ExIsFullZone(&(UDFGlobalData.ObjectNameZoneHeader))) {
620 // we have enough memory
621 PtrObjectName = (PtrUDFObjectName)ExAllocateFromZone(&(UDFGlobalData.ObjectNameZoneHeader));
622
623 // release the spinlock
624 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
625 } else {
626 // release the spinlock
627 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
628
629 // if we failed to obtain from the zone, get it directly from the VMM
631 AllocatedFromZone = FALSE;
632 }
633
634 if (!PtrObjectName) {
635 return NULL;
636 }
637
638 // zero out the allocated memory block
639 RtlZeroMemory(PtrObjectName, UDFQuadAlign(sizeof(UDFObjectName)));
640
641 // set up some fields ...
643 PtrObjectName->NodeIdentifier.NodeSize = UDFQuadAlign(sizeof(UDFObjectName));
644
645
646 if (!AllocatedFromZone) {
648 }
649
650 return(PtrObjectName);
651} // end UDFAllocateObjectName()
#define UDF_NODE_TYPE_OBJECT_NAME
Definition: struct.h:58
struct _UDFObjectName * PtrUDFObjectName
#define UDF_OBJ_NAME_NOT_FROM_ZONE
Definition: struct.h:97
UDFIdentifier NodeIdentifier
Definition: struct.h:91
uint32 ObjectNameFlags
Definition: struct.h:92

Referenced by UDFBlankMount(), UDFCompleteMount(), UDFFirstOpenFile(), and UDFRename().

◆ UDFAssignAcl()

NTSTATUS UDFAssignAcl ( IN PVCB  Vcb,
IN PFILE_OBJECT  FileObject,
IN PtrUDFFCB  Fcb,
IN PtrUDFNTRequiredFCB  NtReqFcb 
)

Definition at line 706 of file secursup.cpp.

712{
714#ifdef UDF_ENABLE_SECURITY
715// SECURITY_INFORMATION SecurityInformation;
716
717// UDFPrint((" UDFAssignAcl\n"));
718 if(!NtReqFcb->SecurityDesc) {
719
720 PSECURITY_DESCRIPTOR ExplicitSecurity = NULL;
721
722 if(UDFIsAStreamDir(Fcb->FileInfo) || UDFIsAStream(Fcb->FileInfo)) {
723 // Stream/SDir security
724 NtReqFcb->SecurityDesc = Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc;
725 return STATUS_SUCCESS;
726 } else
727 if(!Fcb->FileInfo) {
728 // Volume security
729 if(Vcb->RootDirFCB &&
730 Vcb->RootDirFCB->FileInfo &&
731 Vcb->RootDirFCB->FileInfo->Dloc &&
732 Vcb->RootDirFCB->FileInfo->Dloc->CommonFcb) {
733 RC = UDFInheritAcl(Vcb, &(Vcb->RootDirFCB->FileInfo->Dloc->CommonFcb->SecurityDesc), &ExplicitSecurity);
734 } else {
735 NtReqFcb->SecurityDesc = NULL;
737 }
738 return RC;
739 }
740
741 RC = UDFReadSecurity(Vcb, Fcb, &ExplicitSecurity);
743 if(!Fcb->FileInfo->ParentFile) {
744 RC = UDFBuildFullControlAcl(Vcb, &ExplicitSecurity);
745 } else {
746 RC = UDFInheritAcl(Vcb, &(Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc), &ExplicitSecurity);
747 }
748/* if(NT_SUCCESS(RC)) {
749 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_SD_MODIFIED;
750 }*/
751 }
752 if(NT_SUCCESS(RC)) {
753
754// SecurityInformation = FULL_SECURITY_INFORMATION;
755 NtReqFcb->SecurityDesc = ExplicitSecurity;
756
757/* RC = SeSetSecurityDescriptorInfo(FileObject,
758 &SecurityInformation,
759 ExplicitSecurity,
760 &(NtReqFcb->SecurityDesc),
761 NonPagedPool,
762 IoGetFileObjectGenericMapping() );*/
763
764 }
765 }
766#endif //UDF_ENABLE_SECURITY
767 return RC;
768} // end UDFAssignAcl()
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_NO_SECURITY_ON_OBJECT
Definition: ntstatus.h:451
#define Vcb
Definition: cdprocs.h:1415
NTSTATUS UDFReadSecurity(IN PVCB Vcb, IN PtrUDFFCB Fcb, IN PSECURITY_DESCRIPTOR *SecurityDesc)
Definition: secursup.cpp:420
#define UDFIsAStreamDir(FI)
Definition: udf_info.h:998
#define UDFIsAStream(FI)
Definition: udf_info.h:1002

Referenced by UDFCompleteMount(), and UDFLookUpAcl().

◆ UDFCheckAccessRights()

NTSTATUS UDFCheckAccessRights ( PFILE_OBJECT  FileObject,
PACCESS_STATE  AccessState,
PtrUDFFCB  Fcb,
PtrUDFCCB  Ccb,
ACCESS_MASK  DesiredAccess,
USHORT  ShareAccess 
)

Definition at line 927 of file secursup.cpp.

935{
936 NTSTATUS RC;
937 BOOLEAN ROCheck = FALSE;
938#ifdef UDF_ENABLE_SECURITY
939 BOOLEAN SecurityCheck;
940 PSECURITY_DESCRIPTOR SecDesc;
942 ACCESS_MASK LocalAccessMask;
943#endif //UDF_ENABLE_SECURITY
944
945 // Check attr compatibility
946 ASSERT(Fcb);
947 ASSERT(Fcb->Vcb);
948#ifdef UDF_READ_ONLY_BUILD
949 goto treat_as_ro;
950#endif //UDF_READ_ONLY_BUILD
951
952 if(Fcb->FCBFlags & UDF_FCB_READ_ONLY) {
953 ROCheck = TRUE;
954 } else
955 if((Fcb->Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) &&
956 Ccb && !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN) &&
957 (Fcb->Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO)) {
958 AdPrint(("force R/O on dirty\n"));
959 ROCheck = TRUE;
960 }
961 if(ROCheck) {
962#ifdef UDF_READ_ONLY_BUILD
963treat_as_ro:
964#endif //UDF_READ_ONLY_BUILD
965 ACCESS_MASK DesiredAccessMask = 0;
966
967 if(Fcb->Vcb->CompatFlags & UDF_VCB_IC_WRITE_IN_RO_DIR) {
968 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
969 DesiredAccessMask = (FILE_WRITE_EA |
970 DELETE);
971 } else {
972 DesiredAccessMask = (FILE_WRITE_DATA |
975 DELETE);
976 }
977 } else {
978 DesiredAccessMask = (FILE_WRITE_DATA |
984 DELETE);
985 }
986 if(DesiredAccess & DesiredAccessMask)
988 }
989#ifdef UDF_ENABLE_SECURITY
990 // Check Security
991 // NOTE: we should not perform security check if an empty DesiredAccess
992 // was specified. AFAIU, SeAccessCheck() will return FALSE in this case.
993 SecDesc = UDFLookUpAcl(Fcb->Vcb, FileObject, Fcb);
994 if(SecDesc && DesiredAccess) {
996 SecurityCheck =
997 SeAccessCheck(SecDesc,
999 FALSE,
1001 Ccb ? Ccb->PreviouslyGrantedAccess : 0,
1002 NULL,
1004 UserMode,
1005 Ccb ? &(Ccb->PreviouslyGrantedAccess) : &LocalAccessMask,
1006 &RC);
1008
1009 if(!SecurityCheck) {
1010 return RC;
1011 } else
1012#endif //UDF_ENABLE_SECURITY
1015 return STATUS_ACCESS_DENIED;
1016 Ccb->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
1017 }
1018#ifdef UDF_ENABLE_SECURITY
1019 }
1020#endif //UDF_ENABLE_SECURITY
1021 if(FileObject) {
1022 if (Fcb->OpenHandleCount) {
1023 // The FCB is currently in use by some thread.
1024 // We must check whether the requested access/share access
1025 // conflicts with the existing open operations.
1027 &(Fcb->NTRequiredFCB->FCBShareAccess), TRUE);
1028#ifndef UDF_ENABLE_SECURITY
1029 if(Ccb)
1030 Ccb->PreviouslyGrantedAccess |= DesiredAccess;
1031 IoUpdateShareAccess(FileObject, &(Fcb->NTRequiredFCB->FCBShareAccess));
1032#endif //UDF_ENABLE_SECURITY
1033 } else {
1034 IoSetShareAccess(DesiredAccess, ShareAccess, FileObject, &(Fcb->NTRequiredFCB->FCBShareAccess));
1035#ifndef UDF_ENABLE_SECURITY
1036 if(Ccb)
1037 Ccb->PreviouslyGrantedAccess = DesiredAccess;
1038#endif //UDF_ENABLE_SECURITY
1039 RC = STATUS_SUCCESS;
1040 }
1041 } else {
1042 // we get here if given file was opened for internal purposes
1043 RC = STATUS_SUCCESS;
1044 }
1045 return RC;
1046} // end UDFCheckAccessRights()
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1994
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4147
#define INTEGRITY_TYPE_OPEN
Definition: ecma_167.h:357
#define AdPrint(_x_)
Definition: env_spec_w32.h:292
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG _In_ PFLT_CALLBACK_DATA _In_opt_ PCHECK_FOR_TRAVERSE_ACCESS _In_opt_ PSECURITY_SUBJECT_CONTEXT SubjectContext
Definition: fltkernel.h:2246
#define UserMode
Definition: asm.h:35
#define FILE_WRITE_DATA
Definition: nt_native.h:631
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
#define FILE_DELETE_CHILD
Definition: nt_native.h:645
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define DELETE
Definition: nt_native.h:57
#define FILE_ADD_SUBDIRECTORY
Definition: nt_native.h:635
#define FILE_ADD_FILE
Definition: nt_native.h:632
#define FILE_WRITE_EA
Definition: nt_native.h:640
VOID NTAPI IoSetShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3517
NTSTATUS NTAPI IoCheckShareAccess(IN ACCESS_MASK DesiredAccess, IN ULONG DesiredShareAccess, IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess, IN BOOLEAN Update)
Definition: file.c:3390
PGENERIC_MAPPING NTAPI IoGetFileObjectGenericMapping(VOID)
Definition: file.c:3267
VOID NTAPI IoUpdateShareAccess(IN PFILE_OBJECT FileObject, OUT PSHARE_ACCESS ShareAccess)
Definition: file.c:3351
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
PSECURITY_DESCRIPTOR UDFLookUpAcl(IN PVCB Vcb, PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb)
Definition: secursup.cpp:915
PSE_EXPORTS SeExports
Definition: semgr.c:21
#define UDF_FCB_READ_ONLY
Definition: struct.h:312
#define UDF_CCB_VOLUME_OPEN
Definition: struct.h:166
#define UDF_FCB_DIRECTORY
Definition: struct.h:303
PVCB Vcb
Definition: cdstruc.h:933
ULONG OpenHandleCount
Definition: ntfs.h:537
LUID SeSecurityPrivilege
Definition: setypes.h:1201
VOID NTAPI SeReleaseSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Releases both the primary and client tokens of a security subject context.
Definition: subject.c:171
VOID NTAPI SeCaptureSubjectContext(_Out_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Captures the security subject context of the calling thread and calling process.
Definition: subject.c:85
#define UDF_VCB_IC_DIRTY_RO
Definition: udf_common.h:516
#define UDF_VCB_IC_WRITE_IN_RO_DIR
Definition: udf_common.h:499
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550

Referenced by UDFCommonCreate(), UDFDoesOSAllowFileToBeTargetForRename__(), UDFSetAccessRights(), and UDFSetDispositionInformation().

◆ UDFCheckForDismount()

BOOLEAN UDFCheckForDismount ( IN PtrUDFIrpContext  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  VcbAcquired 
)

Definition at line 629 of file verfysup.cpp.

634{
635 BOOLEAN VcbPresent = TRUE;
636 KIRQL SavedIrql;
637 BOOLEAN VcbAcquired;
638 ULONG ResidualReferenceCount;
639
640 UDFPrint(("UDFCheckForDismount:\n"));
641 if(!Vcb) return FALSE;
642
643 // GlobalDataResource is already acquired
644 if(!_VcbAcquired) {
645 VcbAcquired = UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE/*FALSE*/ );
646 if(!VcbAcquired)
647 return TRUE;
648 } else {
649 VcbAcquired = TRUE;
650 }
651
652 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
653 (IrpContext->TargetDeviceObject == Vcb->TargetDeviceObject)) {
654
655 ResidualReferenceCount = 2;
656
657 } else {
658
659 ResidualReferenceCount = 1;
660 }
661
662 // If the dismount is not already underway then check if the
663 // user reference count has gone to zero. If so start the teardown
664 // on the Vcb.
665 if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
666 if (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) {
667 VcbPresent = UDFDismountVcb(Vcb, VcbAcquired);
668 }
669 VcbAcquired = VcbAcquired && VcbPresent;
670
671 // If the teardown is underway and there are absolutely no references
672 // remaining then delete the Vcb. References here include the
673 // references in the Vcb and Vpb.
674 } else if (!(Vcb->VCBOpenCount)) {
675
676 IoAcquireVpbSpinLock( &SavedIrql );
677 // If there are no file objects and no reference counts in the
678 // Vpb we can delete the Vcb. Don't forget that we have the
679 // last reference in the Vpb.
680 if (Vcb->Vpb->ReferenceCount <= ResidualReferenceCount) {
681
682 IoReleaseVpbSpinLock( SavedIrql );
683 if(VcbAcquired)
684 UDFReleaseResource(&(Vcb->VCBResource));
687 VcbAcquired =
688 VcbPresent = FALSE;
689
690 } else {
691
692 IoReleaseVpbSpinLock( SavedIrql );
693 }
694 }
695
696 // Release any resources still acquired.
697 if (!_VcbAcquired && VcbAcquired) {
698 UDFReleaseResource(&(Vcb->VCBResource));
699 }
700
701 return VcbPresent;
702} // end UDFCheckForDismount()
VOID UDFReleaseVCB(PVCB Vcb)
Definition: misc.cpp:2137
#define UDFReleaseResource(Resource)
Definition: env_spec_w32.h:661
VOID NTAPI IoReleaseVpbSpinLock(IN KIRQL Irql)
Definition: volume.c:1215
VOID NTAPI IoAcquireVpbSpinLock(OUT PKIRQL Irql)
Definition: volume.c:1204
VOID UDFStopEjectWaiter(PVCB Vcb)
Definition: phys_eject.cpp:673
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define UDF_RESIDUAL_REFERENCE
Definition: struct.h:336
#define UDF_VCB_FLAGS_BEING_DISMOUNTED
Definition: udf_common.h:461
BOOLEAN UDFDismountVcb(IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:727

Referenced by UDFCommonClose(), UDFPerformVerify(), UDFPnpQueryRemove(), UDFPnpRemove(), UDFPnpSurpriseRemove(), and UDFScanForDismountedVcb().

◆ UDFCleanup()

NTSTATUS NTAPI UDFCleanup ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 43 of file cleanup.cpp.

47{
49 PtrUDFIrpContext PtrIrpContext = NULL;
50 BOOLEAN AreWeTopLevel = FALSE;
51
52 TmPrint(("UDFCleanup\n"));
53
56 ASSERT(Irp);
57
58 // If we were called with our file system device object instead of a
59 // volume device object, just complete this request with STATUS_SUCCESS
60 if (UDFIsFSDevObj(DeviceObject)) {
61 // this is a cleanup of the FSD itself
62 Irp->IoStatus.Status = RC;
63 Irp->IoStatus.Information = 0;
64
66 UDFPrint(("Deregister Autoformat\n"));
68 }
69
72 return(RC);
73 }
74
75 // set the top level context
76 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
77
78 _SEH2_TRY {
79
80 // get an IRP context structure and issue the request
81 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
82 if(PtrIrpContext) {
83 RC = UDFCommonCleanup(PtrIrpContext, Irp);
84 } else {
86 Irp->IoStatus.Status = RC;
87 Irp->IoStatus.Information = 0;
88 // complete the IRP
90 }
91
93
94 RC = UDFExceptionHandler(PtrIrpContext, Irp);
95
97 } _SEH2_END;
98
99 if (AreWeTopLevel) {
101 }
102
104
105 return(RC);
106} // end UDFCleanup()
NTSTATUS UDFCommonCleanup(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: cleanup.cpp:126
NTSTATUS UDFExceptionHandler(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: misc.cpp:358
BOOLEAN __fastcall UDFIsIrpTopLevel(PIRP Irp)
Definition: misc.cpp:228
VOID UDFLogEvent(NTSTATUS UDFEventLogId, NTSTATUS RC)
Definition: misc.cpp:575
PtrUDFIrpContext UDFAllocateIrpContext(PIRP Irp, PDEVICE_OBJECT PtrTargetDeviceObject)
Definition: misc.cpp:985
long UDFExceptionFilter(PtrUDFIrpContext PtrIrpContext, PEXCEPTION_POINTERS PtrExceptionPointers)
Definition: misc.cpp:265
#define TmPrint(_x_)
Definition: env_spec_w32.h:290
#define UDF_ERROR_INTERNAL_ERROR
Definition: errmsg.h:71
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define FsRtlEnterFileSystem
#define FsRtlExitFileSystem
#define IoCompleteRequest
Definition: irp.c:1240
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:158
PVOID AutoFormatCount
Definition: udf_common.h:629
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IO_DISK_INCREMENT
Definition: iotypes.h:600

Referenced by UDFInitializeFunctionPointers().

◆ UDFCleanUpCCB()

VOID __fastcall UDFCleanUpCCB ( PtrUDFCCB  Ccb)

Definition at line 805 of file misc.cpp.

807{
808// ASSERT(Ccb);
809 if(!Ccb) return; // probably, we havn't allocated it...
810 ASSERT(Ccb->NodeIdentifier.NodeType == UDF_NODE_TYPE_CCB);
811
812 _SEH2_TRY {
813 if(Ccb->Fcb) {
814 UDFTouch(&(Ccb->Fcb->CcbListResource));
815 UDFAcquireResourceExclusive(&(Ccb->Fcb->CcbListResource),TRUE);
816 RemoveEntryList(&(Ccb->NextCCB));
817 UDFReleaseResource(&(Ccb->Fcb->CcbListResource));
818 } else {
819 BrutePoint();
820 }
821
822 if (Ccb->DirectorySearchPattern) {
823 if (Ccb->DirectorySearchPattern->Buffer) {
824 MyFreePool__(Ccb->DirectorySearchPattern->Buffer);
825 Ccb->DirectorySearchPattern->Buffer = NULL;
826 }
827
828 MyFreePool__(Ccb->DirectorySearchPattern);
829 Ccb->DirectorySearchPattern = NULL;
830 }
831
834 BrutePoint();
835 } _SEH2_END;
836} // end UDFCleanUpCCB()
VOID __fastcall UDFReleaseCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:768
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define UDFTouch(a)
Definition: env_spec_w32.h:303
#define BrutePoint()
Definition: env_spec_w32.h:504
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define MyFreePool__(addr)
Definition: mem_tools.h:152
struct _FCB::@719::@722 Fcb

Referenced by UDFCommonClose(), and UDFCommonCreate().

◆ UDFCleanUpFCB()

VOID __fastcall UDFCleanUpFCB ( PtrUDFFCB  Fcb)

Definition at line 908 of file misc.cpp.

911{
912 UDFPrint(("UDFCleanUpFCB: %x\n", Fcb));
913 if(!Fcb) return;
914
915 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
916
917 _SEH2_TRY {
918 // Deinitialize FCBName field
919 if (Fcb->FCBName) {
920 if(Fcb->FCBName->ObjectName.Buffer) {
921 MyFreePool__(Fcb->FCBName->ObjectName.Buffer);
922 Fcb->FCBName->ObjectName.Buffer = NULL;
923#ifdef UDF_DBG
924 Fcb->FCBName->ObjectName.Length =
925 Fcb->FCBName->ObjectName.MaximumLength = 0;
926#endif
927 }
928#ifdef UDF_DBG
929 else {
930 UDFPrint(("UDF: Fcb has invalid FCBName Buffer\n"));
931 BrutePoint();
932 }
933#endif
934 UDFReleaseObjectName(Fcb->FCBName);
935 Fcb->FCBName = NULL;
936 }
937#ifdef UDF_DBG
938 else {
939 UDFPrint(("UDF: Fcb has invalid FCBName field\n"));
940 BrutePoint();
941 }
942#endif
943
944
945 // begin transaction {
946 UDFTouch(&(Fcb->Vcb->FcbListResource));
947 UDFAcquireResourceExclusive(&(Fcb->Vcb->FcbListResource), TRUE);
948 // Remove this FCB from list of all FCB in VCB
949 RemoveEntryList(&(Fcb->NextFCB));
950 UDFReleaseResource(&(Fcb->Vcb->FcbListResource));
951 // } end transaction
952
954 UDFDeleteResource(&(Fcb->CcbListResource));
955
956 // Free memory
959 BrutePoint();
960 } _SEH2_END;
961} // end UDFCleanUpFCB()
VOID __fastcall UDFReleaseObjectName(PtrUDFObjectName PtrObjectName)
Definition: misc.cpp:670
#define UDFDeleteResource(Resource)
Definition: env_spec_w32.h:663
__inline VOID UDFReleaseFCB(PtrUDFFCB Fcb)
Definition: protos.h:620
#define UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE
Definition: struct.h:316
WCHAR * ObjectName
Definition: ntfs.h:524

Referenced by UDFBlankMount(), UDFCleanUpFcbChain(), UDFCommonCreate(), and UDFCompleteMount().

◆ UDFCleanUpFcbChain()

ULONG UDFCleanUpFcbChain ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  fi,
IN ULONG  TreeLength,
IN BOOLEAN  VcbAcquired 
)

Definition at line 400 of file close.cpp.

406{
409 PUDF_FILE_INFO ParentFI;
411 ULONG CleanCode;
412 LONG RefCount, ComRefCount;
414 ULONG ret_val = 0;
415
417 AdPrint(("UDFCleanUpFcbChain\n"));
418
419 ASSERT(TreeLength);
420
421 // we can't process Tree until we can acquire Vcb
422 if(!VcbAcquired)
423 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
424
425 // cleanup parent chain (if any & unused)
426 while(fi) {
427
428 // acquire parent
429 if((ParentFI = fi->ParentFile)) {
430 ASSERT(fi->Fcb);
431 ParentFcb = fi->Fcb->ParentFcb;
433 ASSERT(ParentFcb->NTRequiredFCB);
436 } else {
437 // we get to RootDir, it has no parent
438 if(!VcbAcquired)
439 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
440 }
441 Fcb = fi->Fcb;
442 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
443
444 NtReqFcb = Fcb->NTRequiredFCB;
445 ASSERT(NtReqFcb->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
446
447 // acquire current file/dir
448 // we must assure that no more threads try to re-use this object
449#ifdef UDF_DBG
450 _SEH2_TRY {
451#endif // UDF_DBG
453 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource),TRUE);
454#ifdef UDF_DBG
456 BrutePoint();
457 if(ParentFI) {
459 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
460 } else {
461 if(!VcbAcquired)
462 UDFReleaseResource(&(Vcb->VCBResource));
463 }
464 break;
465 } _SEH2_END;
466#endif // UDF_DBG
467 ASSERT_REF((Fcb->ReferenceCount > fi->RefCount) || !TreeLength);
468 // If we haven't pass through all files opened
469 // in UDFCommonCreate before target file (TreeLength specfies
470 // the number of such files) dereference them.
471 // Otherwise we'll just check if the file has no references.
472#ifdef UDF_DBG
473 if(Fcb) {
474 if(TreeLength) {
475 ASSERT(Fcb->ReferenceCount);
476 ASSERT(NtReqFcb->CommonRefCount);
477 RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
478 ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
479 }
480 } else {
481 BrutePoint();
482 }
483 if(TreeLength)
484 TreeLength--;
485 ASSERT(Fcb->OpenHandleCount <= Fcb->ReferenceCount);
486#else
487 if(TreeLength) {
488 RefCount = UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
489 ComRefCount = UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
490 TreeLength--;
491 }
492#endif
493
494/* if(Fcb && Fcb->FCBName && Fcb->FCBName->ObjectName.Buffer) {
495 AdPrint((" %ws (%x)\n",
496 Fcb->FCBName->ObjectName.Buffer,Fcb->ReferenceCount));
497 } else if (Fcb) {
498 AdPrint((" ??? (%x)\n",Fcb->ReferenceCount));
499 } else {
500 AdPrint((" ??? (??)\n"));
501 }*/
502 // ...and delete if it has gone
503
504 if(!RefCount && !Fcb->OpenHandleCount) {
505 // no more references... current file/dir MUST DIE!!!
506 BOOLEAN AutoInherited = UDFIsAStreamDir(fi) || UDFIsAStream(fi);
507
508 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
509 // do nothing
510 } else
511#ifndef UDF_READ_ONLY_BUILD
512 if(Delete) {
513/* if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
514 // set file size to zero (for UdfInfo package)
515 // we should not do this for directories
516 UDFResizeFile__(Vcb, fi, 0);
517 }*/
519 ASSERT(Fcb->ReferenceCount < fi->RefCount);
520 UDFFlushFile__(Vcb, fi);
522 UDFCloseFile__(Vcb, fi);
523 ASSERT(Fcb->ReferenceCount == fi->RefCount);
524 Fcb->FCBFlags |= UDF_FCB_DELETED;
525 Delete = FALSE;
526 } else
527#endif //UDF_READ_ONLY_BUILD
528 if(!(Fcb->FCBFlags & UDF_FCB_DELETED)) {
529 UDFFlushFile__(Vcb, fi);
530 } else {
531// BrutePoint();
532 }
533#ifndef UDF_READ_ONLY_BUILD
534 // check if we should try to delete Parent for the next time
535 if(Fcb->FCBFlags & UDF_FCB_DELETE_PARENT)
536 Delete = TRUE;
537#endif //UDF_READ_ONLY_BUILD
538
539 // remove references to OS-specific structures
540 // to let UDF_INFO release FI & Co
541 fi->Fcb = NULL;
542 if(!ComRefCount) {
543 // CommonFcb is also completly dereferenced
544 // Kill it!
545 fi->Dloc->CommonFcb = NULL;
546 }
547
548 if((CleanCode = UDFCleanUpFile__(Vcb, fi))) {
549 // Check, if we can uninitialize & deallocate CommonFcb part
550 // kill some cross links
551 Fcb->FileInfo = NULL;
552 // release allocated resources
553 if(CleanCode & UDF_FREE_DLOC) {
554 // Obviously, it is a good time & place to release
555 // CommonFcb structure
556
557// NtReqFcb->NtReqFCBFlags &= ~UDF_NTREQ_FCB_VALID;
558 // Unitialize byte-range locks support structure
560 // Remove resources
562 UDFReleaseResource(&(NtReqFcb->MainResource));
563 if(NtReqFcb->CommonFCBHeader.Resource) {
564 UDFDeleteResource(&(NtReqFcb->MainResource));
565 UDFDeleteResource(&(NtReqFcb->PagingIoResource));
566 }
567 NtReqFcb->CommonFCBHeader.Resource =
568 NtReqFcb->CommonFCBHeader.PagingIoResource = NULL;
569 UDFDeassignAcl(NtReqFcb, AutoInherited);
570 UDFPrint(("UDFReleaseNtReqFCB: %x\n", NtReqFcb));
571#ifdef DBG
572// NtReqFcb->FileObject->FsContext2 = NULL;
573// ASSERT(NtReqFcb->FileObject);
574/* if(NtReqFcb->FileObject) {
575 ASSERT(!NtReqFcb->FileObject->FsContext2);
576 NtReqFcb->FileObject->FsContext = NULL;
577 NtReqFcb->FileObject->SectionObjectPointer = NULL;
578 }*/
579#endif //DBG
582 } else {
583 // we usually get here when the file has some opened links
585 UDFReleaseResource(&(NtReqFcb->MainResource));
586 }
587 // remove some references & free Fcb structure
588 Fcb->NTRequiredFCB = NULL;
589 Fcb->ParentFcb = NULL;
591 MyFreePool__(fi);
592 ret_val |= UDF_CLOSE_FCB_DELETED;
593 // get pointer to parent FCB
594 fi = ParentFI;
595 // free old parent's resource...
596 if(fi) {
598 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
599 } else {
600 if(!VcbAcquired)
601 UDFReleaseResource(&(Vcb->VCBResource));
602 }
603 } else {
604 // Stop cleaning up
605
606 // Restore pointers
607 fi->Fcb = Fcb;
608 fi->Dloc->CommonFcb = NtReqFcb;
609 // free all acquired resources
611 UDFReleaseResource(&(NtReqFcb->MainResource));
612 fi = ParentFI;
613 if(fi) {
615 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
616 } else {
617 if(!VcbAcquired)
618 UDFReleaseResource(&(Vcb->VCBResource));
619 }
620 // If we have dereferenced all parents 'associated'
621 // with input file & current file is still in use
622 // then it isn't worth walking down the tree
623 // 'cause in this case all the rest files are also used
624 if(!TreeLength)
625 break;
626// AdPrint(("Stop on referenced File/Dir\n"));
627 }
628 } else {
629 // we get to referenced file/dir. Stop search & release resource
631 UDFReleaseResource(&(NtReqFcb->MainResource));
632 if(ParentFI) {
634 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
635 } else {
636 if(!VcbAcquired)
637 UDFReleaseResource(&(Vcb->VCBResource));
638 }
639 Delete = FALSE;
640 if(!TreeLength)
641 break;
642 fi = ParentFI;
643 }
644 }
645 if(fi) {
646 Fcb = fi->Fcb;
647 for(;TreeLength && fi;TreeLength--) {
648 if(Fcb) {
650 ASSERT(Fcb->ReferenceCount);
651 ASSERT(Fcb->NTRequiredFCB->CommonRefCount);
652 ASSERT_REF(Fcb->ReferenceCount > fi->RefCount);
653 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
654 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
655#ifdef UDF_DBG
656 } else {
657 BrutePoint();
658#endif
659 }
660 Fcb = ParentFcb;
661 }
662 }
663 if(!VcbAcquired)
664 UDFReleaseResource(&(Vcb->VCBResource));
665 return ret_val;
666
667} // end UDFCleanUpFcbChain()
BOOL Delete(LPCTSTR ServiceName)
Definition: delete.c:12
_In_ PFCB ParentFcb
Definition: cdprocs.h:736
VOID __fastcall UDFCleanUpFCB(PtrUDFFCB Fcb)
Definition: misc.cpp:908
#define ValidateFileInfo(fi)
Definition: env_spec_w32.h:516
#define UDFInterlockedDecrement(addr)
Definition: env_spec_w32.h:677
VOID NTAPI FsRtlUninitializeFileLock(IN PFILE_LOCK FileLock)
Definition: filelock.c:1279
long LONG
Definition: pedump.c:60
VOID UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
Definition: secursup.cpp:772
#define UDF_CLOSE_NTREQFCB_DELETED
Definition: protos.h:80
#define UDF_CLOSE_FCB_DELETED
Definition: protos.h:81
#define UDF_NODE_TYPE_NT_REQ_FCB
Definition: struct.h:57
#define UDF_FCB_DELETED
Definition: struct.h:314
#define UDF_FCB_DELETE_PARENT
Definition: struct.h:319
struct _FCB * ParentFcb
Definition: cdstruc.h:940
LONG RefCount
Definition: ntfs.h:535
ERESOURCE MainResource
Definition: ntfs.h:528
int32_t * PLONG
Definition: typedefs.h:58
#define UDF_VCB_FLAGS_RAW_DISK
Definition: udf_common.h:476
#define ASSERT_REF(_a_)
Definition: udf_dbg.h:267
OSSTATUS UDFCloseFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2994
OSSTATUS UDFFlushFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN ULONG FlushFlags)
Definition: udf_info.cpp:4119
uint32 UDFCleanUpFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2276
OSSTATUS UDFUnlinkFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN BOOLEAN FreeSpace)
Definition: udf_info.cpp:1766
#define UDFReferenceFile__(fi)
Definition: udf_info.h:1043
#define UDF_FREE_DLOC
Definition: udf_info.h:650

Referenced by UDFCloseResidual(), UDFCommonClose(), UDFCommonCreate(), and UDFRename().

◆ UDFCleanupVCB()

VOID UDFCleanupVCB ( IN PVCB  Vcb)

Definition at line 1428 of file fscntrl.cpp.

1431{
1432 _SEH2_TRY {
1436 BrutePoint();
1437 } _SEH2_END;
1438
1439 if(Vcb->ShutdownRegistered && Vcb->VCBDeviceObject) {
1440 IoUnregisterShutdownNotification(Vcb->VCBDeviceObject);
1441 Vcb->ShutdownRegistered = FALSE;
1442 }
1443
1444 MyFreeMemoryAndPointer(Vcb->Partitions);
1447 MyFreeMemoryAndPointer(Vcb->SparingTable);
1448
1449 if(Vcb->FSBM_Bitmap) {
1450 DbgFreePool(Vcb->FSBM_Bitmap);
1451 Vcb->FSBM_Bitmap = NULL;
1452 }
1453 if(Vcb->ZSBM_Bitmap) {
1454 DbgFreePool(Vcb->ZSBM_Bitmap);
1455 Vcb->ZSBM_Bitmap = NULL;
1456 }
1457 if(Vcb->BSBM_Bitmap) {
1458 DbgFreePool(Vcb->BSBM_Bitmap);
1459 Vcb->BSBM_Bitmap = NULL;
1460 }
1461#ifdef UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1462 if(Vcb->FSBM_Bitmap_owners) {
1463 DbgFreePool(Vcb->FSBM_Bitmap_owners);
1464 Vcb->FSBM_Bitmap_owners = NULL;
1465 }
1466#endif //UDF_TRACK_ONDISK_ALLOCATION_OWNERS
1467 if(Vcb->FSBM_OldBitmap) {
1468 DbgFreePool(Vcb->FSBM_OldBitmap);
1469 Vcb->FSBM_OldBitmap = NULL;
1470 }
1471
1472 MyFreeMemoryAndPointer(Vcb->Statistics);
1473 MyFreeMemoryAndPointer(Vcb->NTRequiredFCB);
1474 MyFreeMemoryAndPointer(Vcb->VolIdent.Buffer);
1475 MyFreeMemoryAndPointer(Vcb->TargetDevName.Buffer);
1476
1477 if(Vcb->ZBuffer) {
1478 DbgFreePool(Vcb->ZBuffer);
1479 Vcb->ZBuffer = NULL;
1480 }
1481
1482 if(Vcb->fZBuffer) {
1483 DbgFreePool(Vcb->fZBuffer);
1484 Vcb->fZBuffer = NULL;
1485 }
1486
1488 MyFreeMemoryAndPointer(Vcb->WParams);
1490 MyFreeMemoryAndPointer(Vcb->TrackMap);
1491
1492} // end UDFCleanupVCB()
void UDFReleaseDlocList(IN PVCB Vcb)
Definition: dirtree.cpp:1396
#define DbgFreePool
Definition: env_spec_w32.h:334
VOID UDFReleaseFileIdCache(IN PVCB Vcb)
Definition: fileinfo.cpp:2456
#define MyFreeMemoryAndPointer(ptr)
Definition: mem_tools.h:13
VOID NTAPI IoUnregisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1725

Referenced by UDFReleaseVCB(), and UDFVerifyVolume().

◆ UDFClose()

NTSTATUS NTAPI UDFClose ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 62 of file close.cpp.

66{
68 PtrUDFIrpContext PtrIrpContext = NULL;
69 BOOLEAN AreWeTopLevel = FALSE;
70
71 AdPrint(("UDFClose: \n"));
72
75 ASSERT(Irp);
76
77 // If we were called with our file system device object instead of a
78 // volume device object, just complete this request with STATUS_SUCCESS
79 if (UDFIsFSDevObj(DeviceObject)) {
80 // this is a close of the FSD itself
81 Irp->IoStatus.Status = RC;
82 Irp->IoStatus.Information = 0;
83
86 return(RC);
87 }
88
89 // set the top level context
90 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
91
92 _SEH2_TRY {
93
94 // get an IRP context structure and issue the request
95 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
96 ASSERT(PtrIrpContext);
97
98 RC = UDFCommonClose(PtrIrpContext, Irp);
99
101
102 RC = UDFExceptionHandler(PtrIrpContext, Irp);
103
105 } _SEH2_END;
106
107 if (AreWeTopLevel) {
109 }
110
112
113 return(RC);
114}
NTSTATUS UDFCommonClose(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: close.cpp:137

Referenced by UDFInitializeFunctionPointers().

◆ UDFCloseAllDelayed()

VOID UDFCloseAllDelayed ( PVCB  Vcb)

◆ UDFCloseAllXXXDelayedInDir()

NTSTATUS UDFCloseAllXXXDelayedInDir ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  FileInfo,
IN BOOLEAN  System 
)

Definition at line 918 of file close.cpp.

923{
924 PUDF_FILE_INFO* PassedList = NULL;
925 ULONG PassedListSize = 0;
926 PUDF_FILE_INFO* FoundList = NULL;
927 ULONG FoundListSize = 0;
928 NTSTATUS RC;
929 ULONG i;
931 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
933 PUDF_FILE_INFO CurFileInfo;
934 PFE_LIST_ENTRY CurListPtr;
935 PFE_LIST_ENTRY* ListPtrArray = NULL;
936
937 _SEH2_TRY {
938
939 UDFPrint((" UDFCloseAllXXXDelayedInDir(): Acquire DelayedCloseResource\n"));
940 // Acquire DelayedCloseResource
941 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
942 ResAcq = TRUE;
943
944 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
945 AcquiredVcb = TRUE;
946
949 &PassedList, &PassedListSize, &FoundList, &FoundListSize);
950
951 if(!NT_SUCCESS(RC)) {
952 UDFPrint((" UDFBuildTreeItemsList(): error %x\n", RC));
953 try_return(RC);
954 }
955
956 if(!FoundList || !FoundListSize) {
958 }
959
960 // build array of referenced pointers
961 ListPtrArray = (PFE_LIST_ENTRY*)(MyAllocatePool__(NonPagedPool, FoundListSize*sizeof(PFE_LIST_ENTRY)));
962 if(!ListPtrArray) {
963 UDFPrint((" Can't alloc ListPtrArray for %x items\n", FoundListSize));
965 }
966
967 for(i=0;i<FoundListSize;i++) {
968
969 _SEH2_TRY {
970
971 CurFileInfo = FoundList[i];
972 if(!CurFileInfo->ListPtr) {
974 if(!CurFileInfo->ListPtr) {
975 UDFPrint((" Can't alloc ListPtrEntry for items %x\n", i));
977 }
978 CurFileInfo->ListPtr->FileInfo = CurFileInfo;
979 CurFileInfo->ListPtr->EntryRefCount = 0;
980 }
981 CurFileInfo->ListPtr->EntryRefCount++;
982 ListPtrArray[i] = CurFileInfo->ListPtr;
983
985 BrutePoint();
986 } _SEH2_END;
987 }
988
989 UDFReleaseResource(&(Vcb->VCBResource));
990 AcquiredVcb = FALSE;
991
992 if(System) {
993 // Remove from system queue
996 BOOLEAN NoDelayed = (Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) ?
997 TRUE : FALSE;
998
1000 for(i=FoundListSize;i>0;i--) {
1001 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1002 AcquiredVcb = TRUE;
1003 _SEH2_TRY {
1004
1005 CurListPtr = ListPtrArray[i-1];
1006 CurFileInfo = CurListPtr->FileInfo;
1007 if(CurFileInfo &&
1008 (Fcb = CurFileInfo->Fcb)) {
1009 NtReqFcb = Fcb->NTRequiredFCB;
1010 ASSERT((ULONG_PTR)NtReqFcb > 0x1000);
1011// ASSERT((ULONG)(NtReqFcb->SectionObject) > 0x1000);
1012 if(!(NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED) &&
1013 (NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_MODIFIED)) {
1014 MmPrint((" CcFlushCache()\n"));
1015 CcFlushCache(&(NtReqFcb->SectionObject), NULL, 0, &IoStatus);
1016 }
1017 if(NtReqFcb->SectionObject.ImageSectionObject) {
1018 MmPrint((" MmFlushImageSection()\n"));
1019 MmFlushImageSection(&(NtReqFcb->SectionObject), MmFlushForWrite);
1020 }
1021 if(NtReqFcb->SectionObject.DataSectionObject) {
1022 MmPrint((" CcPurgeCacheSection()\n"));
1023 CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
1024 }
1025 } else {
1026 MmPrint((" Skip item: deleted\n"));
1027 }
1028 CurListPtr->EntryRefCount--;
1029 if(!CurListPtr->EntryRefCount) {
1030 if(CurListPtr->FileInfo)
1031 CurListPtr->FileInfo->ListPtr = NULL;
1032 MyFreePool__(CurListPtr);
1033 }
1035 BrutePoint();
1036 } _SEH2_END;
1037 UDFReleaseResource(&(Vcb->VCBResource));
1038 AcquiredVcb = FALSE;
1039 }
1040 if(!NoDelayed)
1041 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_NO_DELAYED_CLOSE;
1042 } else {
1043 // Remove from internal queue
1044 PtrUDFIrpContextLite NextIrpContextLite;
1045
1046 for(i=FoundListSize;i>0;i--) {
1047
1048 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
1049 AcquiredVcb = TRUE;
1050
1051 CurListPtr = ListPtrArray[i-1];
1052 CurFileInfo = CurListPtr->FileInfo;
1053
1054 if(CurFileInfo &&
1055 CurFileInfo->Fcb &&
1056 (NextIrpContextLite = CurFileInfo->Fcb->IrpContextLite)) {
1057 RemoveEntryList( &(NextIrpContextLite->DelayedCloseLinks) );
1058 if (NextIrpContextLite->Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1059// BrutePoint();
1060 UDFGlobalData.DirDelayedCloseCount--;
1061 } else {
1062 UDFGlobalData.DelayedCloseCount--;
1063 }
1064 UDFDoDelayedClose(NextIrpContextLite);
1065 }
1066 CurListPtr->EntryRefCount--;
1067 if(!CurListPtr->EntryRefCount) {
1068 if(CurListPtr->FileInfo)
1069 CurListPtr->FileInfo->ListPtr = NULL;
1070 MyFreePool__(CurListPtr);
1071 }
1072 UDFReleaseResource(&(Vcb->VCBResource));
1073 AcquiredVcb = FALSE;
1074 }
1075 }
1076 RC = STATUS_SUCCESS;
1077
1078try_exit: NOTHING;
1079
1080 } _SEH2_FINALLY {
1081 // release Vcb
1082 if(AcquiredVcb)
1083 UDFReleaseResource(&(Vcb->VCBResource));
1084 // Release DelayedCloseResource
1085 if(ResAcq)
1086 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1087
1088 if(ListPtrArray)
1089 MyFreePool__(ListPtrArray);
1090 if(PassedList)
1091 MyFreePool__(PassedList);
1092 if(FoundList)
1093 MyFreePool__(FoundList);
1094 } _SEH2_END;
1095
1096 return RC;
1097} // end UDFCloseAllXXXDelayedInDir(
VOID NTAPI CcFlushCache(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, OUT OPTIONAL PIO_STATUS_BLOCK IoStatus)
Definition: cachesub.c:222
#define try_return(S)
Definition: cdprocs.h:2179
VOID UDFDoDelayedClose(IN PtrUDFIrpContextLite NextIrpContextLite)
Definition: close.cpp:670
NTSTATUS UDFBuildTreeItemsList(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN PCHECK_TREE_ITEM CheckItemProc, IN PUDF_DATALOC_INFO **PassedList, IN PULONG PassedListSize, IN PUDF_DATALOC_INFO **FoundList, IN PULONG FoundListSize)
BOOLEAN UDFIsLastClose(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:903
BOOLEAN UDFIsInDelayedCloseQueue(PUDF_FILE_INFO FileInfo)
Definition: close.cpp:895
#define _SEH2_FINALLY
Definition: filesup.c:21
BOOLEAN NTAPI CcPurgeCacheSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN OPTIONAL PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN UninitializeCacheMaps)
Definition: fssup.c:386
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define NOTHING
Definition: input_list.c:10
__in UCHAR __in POWER_STATE __in_opt PVOID __in PIO_STATUS_BLOCK IoStatus
Definition: mxum.h:159
#define _SEH2_VOLATILE
Definition: pseh2_64.h:163
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4356
#define UDF_NTREQ_FCB_DELETED
Definition: struct.h:235
#define UDF_NTREQ_FCB_MODIFIED
Definition: struct.h:236
Definition: udf_rel.h:414
ULONG EntryRefCount
Definition: udf_rel.h:416
PUDF_FILE_INFO FileInfo
Definition: udf_rel.h:415
LIST_ENTRY DelayedCloseLinks
Definition: struct.h:410
_UDFFileControlBlock * Fcb
Definition: struct.h:408
struct _FE_LIST_ENTRY * ListPtr
Definition: udf_rel.h:411
struct _UDFFileControlBlock * Fcb
Definition: udf_rel.h:362
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define UDF_VCB_FLAGS_NO_DELAYED_CLOSE
Definition: udf_common.h:480
struct _FE_LIST_ENTRY * PFE_LIST_ENTRY

◆ UDFCloseFileInfoChain()

NTSTATUS UDFCloseFileInfoChain ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  fi,
IN ULONG  TreeLength,
IN BOOLEAN  VcbAcquired 
)

Definition at line 696 of file cleanup.cpp.

702{
703 PUDF_FILE_INFO ParentFI;
707 NTSTATUS RC2;
708
709 // we can't process Tree until we can acquire Vcb
710 if(!VcbAcquired)
711 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
712
713 AdPrint(("UDFCloseFileInfoChain\n"));
714 for(; TreeLength && fi; TreeLength--) {
715
716 // close parent chain (if any)
717 // if we started path parsing not from RootDir on Create,
718 // we would never get RootDir here
720
721 // acquire parent
722 if((ParentFI = fi->ParentFile)) {
723 ParentFcb = fi->Fcb->ParentFcb;
725 ASSERT(ParentFcb->NTRequiredFCB);
728 ASSERT(ParentFcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
729 ASSERT(ParentFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
730 } else {
731 AdPrint(("Acquiring VCB...\n"));
732 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
733 AdPrint(("Done\n"));
734 }
735 // acquire current file/dir
736 // we must assure that no more threads try to reuse this object
737 if((Fcb = fi->Fcb)) {
738 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
740 ASSERT_REF(Fcb->ReferenceCount >= fi->RefCount);
741 if(!(Fcb->FCBFlags & UDF_FCB_DELETED) &&
742 (Fcb->FCBFlags & UDF_FCB_VALID))
743 UDFWriteSecurity(Vcb, Fcb, &(Fcb->NTRequiredFCB->SecurityDesc));
744 RC2 = UDFCloseFile__(Vcb,fi);
745 if(!NT_SUCCESS(RC2))
746 RC = RC2;
747 ASSERT_REF(Fcb->ReferenceCount > fi->RefCount);
748 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
749 UDFReleaseResource(&(Fcb->NTRequiredFCB->MainResource));
750 } else {
751 BrutePoint();
752 RC2 = UDFCloseFile__(Vcb,fi);
753 if(!NT_SUCCESS(RC2))
754 RC = RC2;
755 }
756
757 if(ParentFI) {
759 UDFReleaseResource(&(ParentFcb->NTRequiredFCB->MainResource));
760 } else {
761 UDFReleaseResource(&(Vcb->VCBResource));
762 }
763 fi = ParentFI;
764 }
765
766 if(!VcbAcquired)
767 UDFReleaseResource(&(Vcb->VCBResource));
768
769 return RC;
770
771} // end UDFCloseFileInfoChain()
NTSTATUS UDFWriteSecurity(IN PVCB Vcb, IN PtrUDFFCB Fcb, IN PSECURITY_DESCRIPTOR *SecurityDesc)
Definition: secursup.cpp:796
#define UDF_FCB_VALID
Definition: struct.h:300

Referenced by UDFCommonCleanup(), and UDFCommonCreate().

◆ UDFCloseResidual()

VOID UDFCloseResidual ( IN PVCB  Vcb)

Definition at line 1349 of file fscntrl.cpp.

1352{
1353 // Deinitialize Non-alloc file
1354 if(Vcb->VCBOpenCount)
1355 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1356 UDFPrint(("UDFCloseResidual: NonAllocFileInfo %x\n", Vcb->NonAllocFileInfo));
1357 if(Vcb->NonAllocFileInfo) {
1358 UDFCloseFile__(Vcb,Vcb->NonAllocFileInfo);
1359 UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1360 MyFreePool__(Vcb->NonAllocFileInfo);
1361 Vcb->NonAllocFileInfo = NULL;
1362 }
1363 // Deinitialize Unique ID Mapping
1364 UDFPrint(("UDFCloseResidual: NonAllocFileInfo %x\n", Vcb->NonAllocFileInfo));
1365 if(Vcb->UniqueIDMapFileInfo) {
1366 UDFCloseFile__(Vcb,Vcb->UniqueIDMapFileInfo);
1367 UDFCleanUpFile__(Vcb, Vcb->UniqueIDMapFileInfo);
1368 MyFreePool__(Vcb->UniqueIDMapFileInfo);
1369 Vcb->UniqueIDMapFileInfo = NULL;
1370 }
1371 // Deinitialize VAT file
1372 UDFPrint(("UDFCloseResidual: VatFileInfo %x\n", Vcb->VatFileInfo));
1373 if(Vcb->VatFileInfo) {
1374 UDFCloseFile__(Vcb,Vcb->VatFileInfo);
1375 UDFCleanUpFile__(Vcb, Vcb->VatFileInfo);
1376 MyFreePool__(Vcb->VatFileInfo);
1377 Vcb->VatFileInfo = NULL;
1378 }
1379 // System StreamDir
1380 UDFPrint(("UDFCloseResidual: SysSDirFileInfo %x\n", Vcb->SysSDirFileInfo));
1381 if(Vcb->SysSDirFileInfo) {
1382 UDFCloseFile__(Vcb, Vcb->SysSDirFileInfo);
1383 UDFCleanUpFile__(Vcb, Vcb->SysSDirFileInfo);
1384 MyFreePool__(Vcb->SysSDirFileInfo);
1385 Vcb->SysSDirFileInfo = NULL;
1386 }
1387/* // Deinitialize root dir fcb
1388 if(Vcb->RootDirFCB) {
1389 UDFCloseFile__(Vcb,Vcb->RootDirFCB->FileInfo);
1390 UDFCleanUpFile__(Vcb, Vcb->RootDirFCB->FileInfo);
1391 MyFreePool__(Vcb->RootDirFCB->FileInfo);
1392 UDFCleanUpFCB(Vcb->RootDirFCB);
1393 // Remove root FCB reference in vcb
1394 if(Vcb->VCBOpenCount) Vcb->VCBOpenCount--;
1395 }
1396
1397 // Deinitialize Non-alloc file
1398 if(Vcb->VCBOpenCount) Vcb->VCBOpenCount--;
1399 if(Vcb->NonAllocFileInfo) {
1400 UDFCloseFile__(Vcb,Vcb->NonAllocFileInfo);
1401 // We must release VCB here !!!!
1402// UDFCleanUpFcbChain(Vcb, Vcb->NonAllocFileInfo, 1);
1403 Vcb->NonAllocFileInfo = NULL;
1404 }
1405 // Deinitialize VAT file
1406 if(Vcb->VatFileInfo) {
1407 UDFCloseFile__(Vcb,Vcb->VatFileInfo);
1408 // We must release VCB here !!!!
1409// UDFCleanUpFcbChain(Vcb, Vcb->VatFileInfo, 1);
1410 Vcb->VatFileInfo = NULL;
1411 }*/
1412
1413 // Deinitialize root dir fcb
1414 UDFPrint(("UDFCloseResidual: RootDirFCB %x\n", Vcb->RootDirFCB));
1415 if(Vcb->RootDirFCB) {
1416 UDFCloseFile__(Vcb,Vcb->RootDirFCB->FileInfo);
1417 if(Vcb->RootDirFCB->OpenHandleCount)
1418 Vcb->RootDirFCB->OpenHandleCount--;
1419 UDFCleanUpFcbChain(Vcb, Vcb->RootDirFCB->FileInfo, 1, TRUE);
1420 // Remove root FCB reference in vcb
1421 if(Vcb->VCBOpenCount)
1422 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1423 Vcb->RootDirFCB = NULL;
1424 }
1425} // end UDFCloseResidual()
ULONG UDFCleanUpFcbChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: close.cpp:400

Referenced by UDFDismountVcb(), and UDFMountVolume().

◆ UDFCommonCleanup()

NTSTATUS UDFCommonCleanup ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 126 of file cleanup.cpp.

129{
132 NTSTATUS RC2;
137 PVCB Vcb = NULL;
139 ULONG lc = 0;
140 BOOLEAN AcquiredVcb = FALSE;
141 BOOLEAN AcquiredFCB = FALSE;
142 BOOLEAN AcquiredParentFCB = FALSE;
143
144// BOOLEAN CompleteIrp = TRUE;
145// BOOLEAN PostRequest = FALSE;
146 BOOLEAN ChangeTime = FALSE;
147#ifdef UDF_DBG
148 BOOLEAN CanWait = FALSE;
149#endif // UDF_DBG
150 BOOLEAN ForcedCleanUp = FALSE;
151
152 PUDF_FILE_INFO NextFileInfo = NULL;
153#ifdef UDF_DBG
154 UNICODE_STRING CurName;
155 PDIR_INDEX_HDR DirNdx;
156#endif // UDF_DBG
157// PUDF_DATALOC_INFO Dloc;
158
159 TmPrint(("UDFCommonCleanup\n"));
160
161// BrutePoint();
162
163 _SEH2_TRY {
164 // First, get a pointer to the current I/O stack location
167
169
170 // Get the FCB and CCB pointers
171 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
172 ASSERT(Ccb);
173 Fcb = Ccb->Fcb;
174 ASSERT(Fcb);
175
176 Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
177 ASSERT(Vcb);
178 ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
179// Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
180#ifdef UDF_DBG
181 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
182 AdPrint((" %s\n", CanWait ? "Wt" : "nw"));
183 ASSERT(CanWait);
184#endif // UDF_DBG
185 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
186 AcquiredVcb = TRUE;
187 // Steps we shall take at this point are:
188 // (a) Acquire the file (FCB) exclusively
189 // (b) Flush file data to disk
190 // (c) Talk to the FSRTL package (if we use it) about pending oplocks.
191 // (d) Notify the FSRTL package for use with pending notification IRPs
192 // (e) Unlock byte-range locks (if any were acquired by process)
193 // (f) Update time stamp values (e.g. fast-IO had been performed)
194 // (g) Inform the Cache Manager to uninitialize Cache Maps ...
195 // and other similar stuff.
196 // BrutePoint();
197 NtReqFcb = Fcb->NTRequiredFCB;
198
199 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
200 AdPrint(("Cleaning up Volume\n"));
201 AdPrint(("UDF: OpenHandleCount: %x\n",Fcb->OpenHandleCount));
202
204 UDFInterlockedDecrement((PLONG)&(Vcb->VCBHandleCount));
205 if(FileObject->Flags & FO_CACHE_SUPPORTED) {
206 // we've cached close
207 UDFInterlockedDecrement((PLONG)&(Fcb->CachedOpenHandleCount));
208 }
209 ASSERT(Fcb->OpenHandleCount <= (Fcb->ReferenceCount-1));
210
211 // If this handle had write access, and actually wrote something,
212 // flush the device buffers, and then set the verify bit now
213 // just to be safe (in case there is no dismount).
214 if( FileObject->WriteAccess &&
215 (FileObject->Flags & FO_FILE_MODIFIED)) {
216
217 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
218 }
219 // User may decide to close locked volume without call to unlock proc
220 // So, handle this situation properly & unlock it now...
221 if (FileObject == Vcb->VolumeLockFileObject) {
222 Vcb->VolumeLockFileObject = NULL;
223 Vcb->VolumeLockPID = -1;
224 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
225 Vcb->Vpb->Flags &= ~VPB_LOCKED;
227 }
228
229 MmPrint((" CcUninitializeCacheMap()\n"));
231 // reset device
232 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
233 (Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER)) {
234 // this call doesn't modify data buffer
235 // it just requires its presence
236 UDFResetDeviceDriver(Vcb, Vcb->TargetDeviceObject, TRUE);
237 }
238 // We must clean up the share access at this time, since we may not
239 // get a Close call for awhile if the file was mapped through this
240 // File Object.
241 IoRemoveShareAccess( FileObject, &(NtReqFcb->FCBShareAccess) );
242
244 }
245// BrutePoint();
246#ifdef UDF_DBG
247 DirNdx = UDFGetDirIndexByFileInfo(Fcb->FileInfo);
248 if(DirNdx) {
249 CurName.Buffer = UDFDirIndex(DirNdx, Fcb->FileInfo->Index)->FName.Buffer;
250 if(CurName.Buffer) {
251 AdPrint(("Cleaning up file: %ws %8.8x\n", CurName.Buffer, FileObject));
252 } else {
253 AdPrint(("Cleaning up file: ??? \n"));
254 }
255 }
256#endif //UDF_DBG
257 AdPrint(("UDF: OpenHandleCount: %x\n",Fcb->OpenHandleCount));
258 // Acquire parent object
259 if(Fcb->FileInfo->ParentFile) {
260 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB);
261 UDFAcquireResourceExclusive(&(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB->MainResource),TRUE);
262 } else {
263 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
264 }
265 AcquiredParentFCB = TRUE;
266 // Acquire current object
268 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource),TRUE);
269 AcquiredFCB = TRUE;
270 // dereference object
272 UDFInterlockedDecrement((PLONG)&(Vcb->VCBHandleCount));
273 if(FileObject->Flags & FO_CACHE_SUPPORTED) {
274 // we've cached close
275 UDFInterlockedDecrement((PLONG)&(Fcb->CachedOpenHandleCount));
276 }
277 ASSERT(Fcb->OpenHandleCount <= (Fcb->ReferenceCount-1));
278 // check if Ccb being cleaned up has DeleteOnClose flag set
279#ifndef UDF_READ_ONLY_BUILD
280 if(Ccb->CCBFlags & UDF_CCB_DELETE_ON_CLOSE) {
281 AdPrint((" DeleteOnClose\n"));
282 // Ok, now we'll become 'delete on close'...
283 ASSERT(!(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
284 Fcb->FCBFlags |= UDF_FCB_DELETE_ON_CLOSE;
285 FileObject->DeletePending = TRUE;
286 // Report this to the dir notify package for a directory.
287 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
288 FsRtlNotifyFullChangeDirectory( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
290 0, NULL, NULL, NULL );
291 }
292 }
293#endif //UDF_READ_ONLY_BUILD
294
295 if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
296 // Unlock all outstanding file locks.
297 FsRtlFastUnlockAll(&(NtReqFcb->FileLock),
300 NULL);
301 }
302 // get Link count
303 lc = UDFGetFileLinkCount(Fcb->FileInfo);
304
305#ifndef UDF_READ_ONLY_BUILD
306 if( (Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) &&
307 !(Fcb->OpenHandleCount)) {
308 // This can be useful for Streams, those were brutally deleted
309 // (together with parent object)
310 ASSERT(!(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
311 FileObject->DeletePending = TRUE;
312
313 // we should mark all streams of the file being deleted
314 // for deletion too, if there are no more Links to
315 // main data stream
316 if((lc <= 1) &&
317 !UDFIsSDirDeleted(Fcb->FileInfo->Dloc->SDirInfo)) {
318 RC = UDFMarkStreamsForDeletion(Vcb, Fcb, TRUE); // Delete
319 }
320 // we can release these resources 'cause UDF_FCB_DELETE_ON_CLOSE
321 // flag is already set & the file can't be opened
323 UDFReleaseResource(&(NtReqFcb->MainResource));
324 AcquiredFCB = FALSE;
325 if(Fcb->FileInfo->ParentFile) {
327 UDFReleaseResource(&(Fcb->ParentFcb->NTRequiredFCB->MainResource));
328 } else {
329 UDFReleaseResource(&(Vcb->VCBResource));
330 }
331 AcquiredParentFCB = FALSE;
332 UDFReleaseResource(&(Vcb->VCBResource));
333 AcquiredVcb = FALSE;
334
335 // Make system to issue last Close request
336 // for our Target ...
338
339#ifdef UDF_DELAYED_CLOSE
340 // remove file from our DelayedClose queue
342 ASSERT(!Fcb->IrpContextLite);
343#endif //UDF_DELAYED_CLOSE
344
345 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
346 AcquiredVcb = TRUE;
347 if(Fcb->FileInfo->ParentFile) {
349 UDFAcquireResourceExclusive(&(Fcb->ParentFcb->NTRequiredFCB->MainResource),TRUE);
350 } else {
351 UDFAcquireResourceShared(&(Vcb->VCBResource),TRUE);
352 }
353 AcquiredParentFCB = TRUE;
355 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource),TRUE);
356 AcquiredFCB = TRUE;
357
358 // we should set file sizes to zero if there are no more
359 // links to this file
360 if(lc <= 1) {
361 // Synchronize here with paging IO
362 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource),TRUE);
363 // set file size to zero (for system cache manager)
364// NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart =
365 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
366 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = 0;
367 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
368
369 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
370 }
371 }
372#endif //UDF_READ_ONLY_BUILD
373
374#ifdef UDF_DELAYED_CLOSE
375 if ((Fcb->ReferenceCount == 1) &&
376 /*(Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB) &&*/ // see above
377 (!(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE)) ) {
378 Fcb->FCBFlags |= UDF_FCB_DELAY_CLOSE;
379 }
380#endif //UDF_DELAYED_CLOSE
381
382 NextFileInfo = Fcb->FileInfo;
383
384#ifndef UDF_READ_ONLY_BUILD
385 // do we need to delete it now ?
386 if( (Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) &&
387 !(Fcb->OpenHandleCount)) {
388
389 // can we do it ?
390 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
391 ASSERT(!(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
392 if(!UDFIsDirEmpty__(NextFileInfo)) {
393 // forget about it
394 Fcb->FCBFlags &= ~UDF_FCB_DELETE_ON_CLOSE;
395 goto DiscardDelete;
396 }
397 } else
398 if (lc <= 1) {
399 // Synchronize here with paging IO
400 BOOLEAN AcquiredPagingIo;
401 AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&(NtReqFcb->PagingIoResource));
402 // set file size to zero (for UdfInfo package)
403 // we should not do this for directories and linked files
404 UDFResizeFile__(Vcb, NextFileInfo, 0);
405 if(AcquiredPagingIo) {
406 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
407 }
408 }
409 // mark parent object for deletion if requested
410 if((Fcb->FCBFlags & UDF_FCB_DELETE_PARENT) &&
411 Fcb->ParentFcb) {
414 }
415 // flush file. It is required by UDFUnlinkFile__()
416 RC = UDFFlushFile__(Vcb, NextFileInfo);
417 if(!NT_SUCCESS(RC)) {
418 AdPrint(("Error flushing file !!!\n"));
419 }
420 // try to unlink
421 if((RC = UDFUnlinkFile__(Vcb, NextFileInfo, TRUE)) == STATUS_CANNOT_DELETE) {
422 // If we can't delete file with Streams due to references,
423 // mark SDir & Streams
424 // for Deletion. We shall also set DELETE_PARENT flag to
425 // force Deletion of the current file later... when curently
426 // opened Streams would be cleaned up.
427
428 // WARNING! We should keep SDir & Streams if there is a
429 // link to this file
430 if(NextFileInfo->Dloc &&
431 NextFileInfo->Dloc->SDirInfo &&
432 NextFileInfo->Dloc->SDirInfo->Fcb) {
433
434 BrutePoint();
435 if(!UDFIsSDirDeleted(NextFileInfo->Dloc->SDirInfo)) {
436// RC = UDFMarkStreamsForDeletion(Vcb, Fcb, TRUE); // Delete
437//#ifdef UDF_ALLOW_PRETEND_DELETED
438 UDFPretendFileDeleted__(Vcb, Fcb->FileInfo);
439//#endif //UDF_ALLOW_PRETEND_DELETED
440 }
441 goto NotifyDelete;
442
443 } else {
444 // Getting here means that we can't delete file because of
445 // References/PemissionsDenied/Smth.Else,
446 // but not Linked+OpenedStream
447 BrutePoint();
448// RC = STATUS_SUCCESS;
449 goto DiscardDelete_1;
450 }
451 } else {
452DiscardDelete_1:
453 // We have got an ugly ERROR, or
454 // file is deleted, so forget about it
455 ASSERT(!(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
456 ForcedCleanUp = TRUE;
457 if(NT_SUCCESS(RC))
458 Fcb->FCBFlags &= ~UDF_FCB_DELETE_ON_CLOSE;
459 Fcb->FCBFlags |= UDF_FCB_DELETED;
460 RC = STATUS_SUCCESS;
461 }
462NotifyDelete:
463 // We should prevent SetEOF operations on completly
464 // deleted data streams
465 if(lc < 1) {
466 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_DELETED;
467 }
468 // Report that we have removed an entry.
469 if(UDFIsAStream(NextFileInfo)) {
470 UDFNotifyFullReportChange( Vcb, NextFileInfo,
473 } else {
474 UDFNotifyFullReportChange( Vcb, NextFileInfo,
477 }
478 } else
479 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
480DiscardDelete:
481 UDFNotifyFullReportChange( Vcb, NextFileInfo,
484 0,
486 }
487#endif //UDF_READ_ONLY_BUILD
488
489 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
490 // Report to the dir notify package for a directory.
491 FsRtlNotifyCleanup( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP), (PVOID)Ccb );
492 }
493
494 // we can't purge Cache when more than one link exists
495 if(lc > 1) {
496 ForcedCleanUp = FALSE;
497 }
498
499 if ( (FileObject->Flags & FO_CACHE_SUPPORTED) &&
500 (NtReqFcb->SectionObject.DataSectionObject) ) {
501 BOOLEAN LastNonCached = (!Fcb->CachedOpenHandleCount &&
503 // If this was the last cached open, and there are open
504 // non-cached handles, attempt a flush and purge operation
505 // to avoid cache coherency overhead from these non-cached
506 // handles later. We ignore any I/O errors from the flush.
507 // We shall not flush deleted files
508 RC = STATUS_SUCCESS;
509 if( LastNonCached
510 ||
511 (!Fcb->OpenHandleCount &&
512 !ForcedCleanUp) ) {
513
514#ifndef UDF_READ_ONLY_BUILD
515 LONGLONG OldFileSize, NewFileSize;
516
517 if( (OldFileSize = NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart) <
518 (NewFileSize = NtReqFcb->CommonFCBHeader.FileSize.QuadPart)) {
519/* UDFZeroDataEx(NtReqFcb,
520 OldFileSize,
521 NewFileSize - OldFileSize,
522 TRUE, Vcb, FileObject);*/
523
524 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = NewFileSize;
525 }
526#endif //UDF_READ_ONLY_BUILD
527 MmPrint((" CcFlushCache()\n"));
528 CcFlushCache( &(NtReqFcb->SectionObject), NULL, 0, &IoStatus );
529 if(!NT_SUCCESS(IoStatus.Status)) {
530 MmPrint((" CcFlushCache() error: %x\n", IoStatus.Status));
531 RC = IoStatus.Status;
532 }
533 }
534 // If file is deleted or it is last cached open, but there are
535 // some non-cached handles we should purge cache section
536 if(ForcedCleanUp || LastNonCached) {
537 if(NtReqFcb->SectionObject.DataSectionObject) {
538 MmPrint((" CcPurgeCacheSection()\n"));
539 CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );
540 }
541/* MmPrint((" CcPurgeCacheSection()\n"));
542 CcPurgeCacheSection( &(NtReqFcb->SectionObject), NULL, 0, FALSE );*/
543 }
544 // we needn't Flush here. It will be done in UDFCloseFileInfoChain()
545 }
546
547#ifndef UDF_READ_ONLY_BUILD
548 // Update FileTimes & Attrs
549 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) &&
550 !(Fcb->FCBFlags & (UDF_FCB_DELETE_ON_CLOSE |
552 UDF_FCB_DIRECTORY |
553 UDF_FCB_READ_ONLY*/)) &&
554 !UDFIsAStreamDir(NextFileInfo)) {
556 LONGLONG ASize;
558 // Check if we should set ARCHIVE bit & LastWriteTime
559 if(FileObject->Flags & FO_FILE_MODIFIED) {
560 ULONG Attr;
561 PDIR_INDEX_ITEM DirNdx;
562 DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(NextFileInfo), NextFileInfo->Index);
563 ASSERT(DirNdx);
564 // Archive bit
565 if(!(Ccb->CCBFlags & UDF_CCB_ATTRIBUTES_SET) &&
566 (Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT)) {
567 Attr = UDFAttributesToNT(DirNdx, NextFileInfo->Dloc->FileEntry);
568 if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))
569 UDFAttributesToUDF(DirNdx, NextFileInfo->Dloc->FileEntry, Attr | FILE_ATTRIBUTE_ARCHIVE);
570 }
571 // WriteTime
572 if(!(Ccb->CCBFlags & UDF_CCB_WRITE_TIME_SET) &&
573 (Vcb->CompatFlags & UDF_VCB_IC_UPDATE_MODIFY_TIME)) {
574 UDFSetFileXTime(NextFileInfo, NULL, &NtTime, NULL, &NtTime);
575 NtReqFcb->LastWriteTime.QuadPart =
576 NtReqFcb->LastAccessTime.QuadPart = NtTime;
577 ChangeTime = TRUE;
578 }
579 }
580 if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
581 // Update sizes in DirIndex
582 if(!Fcb->OpenHandleCount) {
583 ASize = UDFGetFileAllocationSize(Vcb, NextFileInfo);
584// NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart;
585 UDFSetFileSizeInDirNdx(Vcb, NextFileInfo, &ASize);
586 } else
587 if(FileObject->Flags & FO_FILE_SIZE_CHANGED) {
588 ASize = //UDFGetFileAllocationSize(Vcb, NextFileInfo);
589 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart;
590 UDFSetFileSizeInDirNdx(Vcb, NextFileInfo, &ASize);
591 }
592 }
593 // AccessTime
594 if((FileObject->Flags & FO_FILE_FAST_IO_READ) &&
595 !(Ccb->CCBFlags & UDF_CCB_ACCESS_TIME_SET) &&
596 (Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ACCESS_TIME)) {
597 UDFSetFileXTime(NextFileInfo, NULL, &NtTime, NULL, NULL);
598 NtReqFcb->LastAccessTime.QuadPart = NtTime;
599// ChangeTime = TRUE;
600 }
601 // ChangeTime (AttrTime)
602 if(!(Ccb->CCBFlags & UDF_CCB_MODIFY_TIME_SET) &&
603 (Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ATTR_TIME) &&
604 (ChangeTime || (Ccb->CCBFlags & (UDF_CCB_ATTRIBUTES_SET |
608 UDFSetFileXTime(NextFileInfo, NULL, NULL, &NtTime, NULL);
609 NtReqFcb->ChangeTime.QuadPart = NtTime;
610 }
611 }
612#endif //UDF_READ_ONLY_BUILD
613
614 if(!(Fcb->FCBFlags & UDF_FCB_DIRECTORY) &&
615 ForcedCleanUp) {
616 // flush system cache
617 MmPrint((" CcUninitializeCacheMap()\n"));
619 } else {
620 MmPrint((" CcUninitializeCacheMap()\n"));
622 }
623
624 // release resources now.
625 // they'll be acquired in UDFCloseFileInfoChain()
627 UDFReleaseResource(&(NtReqFcb->MainResource));
628 AcquiredFCB = FALSE;
629
630 if(Fcb->FileInfo->ParentFile) {
631 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB);
632 UDFReleaseResource(&(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB->MainResource));
633 } else {
634 UDFReleaseResource(&(Vcb->VCBResource));
635 }
636 AcquiredParentFCB = FALSE;
637 // close the chain
638 ASSERT(AcquiredVcb);
639 RC2 = UDFCloseFileInfoChain(Vcb, NextFileInfo, Ccb->TreeLength, TRUE);
640 if(NT_SUCCESS(RC))
641 RC = RC2;
642
643 Ccb->CCBFlags |= UDF_CCB_CLEANED;
644
645 // We must clean up the share access at this time, since we may not
646 // get a Close call for awhile if the file was mapped through this
647 // File Object.
648 IoRemoveShareAccess( FileObject, &(NtReqFcb->FCBShareAccess) );
649
650 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
651
653
654try_exit: NOTHING;
655
656 } _SEH2_FINALLY {
657
658 if(AcquiredFCB) {
660 UDFReleaseResource(&(NtReqFcb->MainResource));
661 }
662
663 if(AcquiredParentFCB) {
664 if(Fcb->FileInfo->ParentFile) {
665 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB);
666 UDFReleaseResource(&(Fcb->FileInfo->ParentFile->Fcb->NTRequiredFCB->MainResource));
667 } else {
668 UDFReleaseResource(&(Vcb->VCBResource));
669 }
670 }
671
672 if(AcquiredVcb) {
673 UDFReleaseResource(&(Vcb->VCBResource));
674 AcquiredVcb = FALSE;
675 }
676
678 // complete the IRP
679 Irp->IoStatus.Status = RC;
680 Irp->IoStatus.Information = 0;
682 // Free up the Irp Context
683 UDFReleaseIrpContext(PtrIrpContext);
684 }
685
686 } _SEH2_END; // end of "__finally" processing
687 return(RC);
688} // end UDFCommonCleanup()
VOID UDFSetFileXTime(IN PUDF_FILE_INFO FileInfo, IN LONGLONG *CrtTime, IN LONGLONG *AccTime, IN LONGLONG *AttrTime, IN LONGLONG *ChgTime)
VOID UDFAttributesToUDF(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry, IN ULONG NTAttr)
ULONG UDFAttributesToNT(IN PDIR_INDEX_ITEM FileDirNdx, IN tag *FileEntry)
struct _VCB * PVCB
Definition: fatstruc.h:557
NTSTATUS UDFCloseFileInfoChain(IN PVCB Vcb, IN PUDF_FILE_INFO fi, IN ULONG TreeLength, IN BOOLEAN VcbAcquired)
Definition: cleanup.cpp:696
PDIR_INDEX_HDR UDFGetDirIndexByFileInfo(IN PUDF_FILE_INFO FileInfo)
Definition: dirtree.cpp:1092
BOOLEAN UDFAcquireResourceExclusiveWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2529
VOID UDFReleaseIrpContext(PtrUDFIrpContext PtrIrpContext)
Definition: misc.cpp:1086
#define UDFNotifyVolumeEvent(FileObject, EventCode)
Definition: env_spec.h:114
__inline VOID UDFNotifyFullReportChange(PVCB V, PUDF_FILE_INFO FI, ULONG E, ULONG A)
Definition: env_spec.h:99
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible(IN PtrUDFFCB Fcb)
Definition: fastio.cpp:118
_In_ PLARGE_INTEGER NtTime
Definition: fatprocs.h:1914
NTSTATUS UDFMarkStreamsForDeletion(IN PVCB Vcb, IN PtrUDFFCB Fcb, IN BOOLEAN ForDel)
Definition: fileinfo.cpp:1137
NTSTATUS NTAPI FsRtlFastUnlockAll(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN PVOID Context OPTIONAL)
Definition: filelock.c:1025
VOID NTAPI CcSetFileSizes(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes)
Definition: fssup.c:356
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define FSRTL_VOLUME_UNLOCK
Definition: ntifs_ex.h:443
VOID NTAPI FsRtlNotifyCleanup(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext)
Definition: notify.c:659
VOID NTAPI FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
Definition: notify.c:1487
VOID NTAPI IoRemoveShareAccess(IN PFILE_OBJECT FileObject, IN PSHARE_ACCESS ShareAccess)
Definition: file.c:3478
PEPROCESS NTAPI IoGetRequestorProcess(IN PIRP Irp)
Definition: irp.c:1782
OSSTATUS UDFResetDeviceDriver(IN PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, IN BOOLEAN Unlock)
Definition: phys_lib.cpp:4199
#define UDFRemoveFromSystemDelayedQueue(Fcb)
Definition: protos.h:109
#define UDFRemoveFromDelayedQueue(Fcb)
Definition: protos.h:106
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:160
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define UDF_CCB_CREATE_TIME_SET
Definition: struct.h:155
#define UDF_CCB_ATTRIBUTES_SET
Definition: struct.h:157
#define UDF_CCB_ACCESS_TIME_SET
Definition: struct.h:153
#define UDF_FCB_ROOT_DIRECTORY
Definition: struct.h:304
#define UDF_CCB_CLEANED
Definition: struct.h:146
#define UDF_CCB_MODIFY_TIME_SET
Definition: struct.h:154
#define UDF_NODE_TYPE_VCB
Definition: struct.h:61
#define UDF_FCB_DELETE_ON_CLOSE
Definition: struct.h:309
#define UDF_FCB_DELAY_CLOSE
Definition: struct.h:313
#define UDF_CCB_WRITE_TIME_SET
Definition: struct.h:156
#define UDF_CCB_DELETE_ON_CLOSE
Definition: struct.h:162
PVOID DeviceExtension
Definition: env_spec_w32.h:418
UNICODE_STRING FName
Definition: udf_rel.h:173
struct _UDF_FILE_INFO * SDirInfo
Definition: udf_rel.h:319
PUDF_DATALOC_INFO Dloc
Definition: udf_rel.h:367
uint_di Index
Definition: udf_rel.h:392
Definition: cdstruc.h:498
int64_t LONGLONG
Definition: typedefs.h:68
#define UDF_VCB_IC_UPDATE_MODIFY_TIME
Definition: udf_common.h:494
#define UDF_VCB_FLAGS_VOLUME_MOUNTED
Definition: udf_common.h:459
#define UDF_VCB_IC_UPDATE_ATTR_TIME
Definition: udf_common.h:495
#define UDF_VCB_FLAGS_VOLUME_READ_ONLY
Definition: udf_common.h:463
#define UDF_VCB_IC_UPDATE_ARCH_BIT
Definition: udf_common.h:496
#define UDF_VCB_IC_UPDATE_ACCESS_TIME
Definition: udf_common.h:493
#define UDF_VCB_FLAGS_OUR_DEVICE_DRIVER
Definition: udf_common.h:466
uint16 UDFGetFileLinkCount(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1355
void UDFSetFileSizeInDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 *ASize)
Definition: udf_info.cpp:1190
OSSTATUS UDFResizeFile__(IN PVCB Vcb, IN OUT PUDF_FILE_INFO FileInfo, IN int64 NewLength)
Definition: udf_info.cpp:3468
OSSTATUS UDFPretendFileDeleted__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:5566
#define UDFIsSDirDeleted(FI)
Definition: udf_info.h:1004
#define UDFGetFileAllocationSize(Vcb, FileInfo)
Definition: udf_info.h:797
#define UDFIsDirEmpty__(fi)
Definition: udf_info.h:1070
__inline PDIR_INDEX_ITEM UDFDirIndex(IN PDIR_INDEX_HDR hDirNdx, IN uint_di i)
Definition: udf_info.h:1105
#define UDFIsADirectory(FileInfo)
Definition: udf_info.h:792
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define FILE_ACTION_MODIFIED_STREAM
#define FILE_ACTION_MODIFIED
#define FO_FILE_FAST_IO_READ
Definition: iotypes.h:1795
#define FILE_NOTIFY_CHANGE_STREAM_NAME
#define FILE_ACTION_REMOVED_STREAM
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
#define FILE_ACTION_REMOVED
#define FO_FILE_MODIFIED
Definition: iotypes.h:1788
#define FILE_NOTIFY_CHANGE_FILE_NAME
#define FO_CLEANUP_COMPLETE
Definition: iotypes.h:1790
* PFILE_OBJECT
Definition: iotypes.h:1998
#define FO_FILE_SIZE_CHANGED
Definition: iotypes.h:1789
#define FO_CACHE_SUPPORTED
Definition: iotypes.h:1781
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FILE_NOTIFY_CHANGE_DIR_NAME
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:608

Referenced by UDFCleanup(), and UDFCommonDispatch().

◆ UDFCommonClose()

NTSTATUS UDFCommonClose ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 137 of file close.cpp.

141{
147 PVCB Vcb = NULL;
148// PERESOURCE PtrResourceAcquired = NULL;
149 BOOLEAN AcquiredVcb = FALSE;
150 BOOLEAN AcquiredGD = FALSE;
152 ULONG i = 0;
153// ULONG clean_stat = 0;
154
155// BOOLEAN CompleteIrp = TRUE;
156 BOOLEAN PostRequest = FALSE;
157
158#ifdef UDF_DBG
159 UNICODE_STRING CurName;
160 PDIR_INDEX_HDR DirNdx;
161#endif
162
163 AdPrint(("UDFCommonClose: \n"));
164
165 _SEH2_TRY {
166 if (Irp) {
167
168 // If this is the first (IOManager) request
169 // First, get a pointer to the current I/O stack location
171 ASSERT(IrpSp);
172
175
176 // Get the FCB and CCB pointers
177 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
178 ASSERT(Ccb);
179 if(Ccb->CCBFlags & UDF_CCB_READ_ONLY) {
181 }
182 Fcb = Ccb->Fcb;
183 } else {
184 // If this is a queued call (for our dispatch)
185 // Get saved Fcb address
186 Fcb = PtrIrpContext->Fcb;
187 i = PtrIrpContext->TreeLength;
188 }
189
190 ASSERT(Fcb);
191 Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
192 ASSERT(Vcb);
193 ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
194// Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
195
196 // Steps we shall take at this point are:
197 // (a) Acquire the VCB shared
198 // (b) Acquire the FCB's CCB list exclusively
199 // (c) Delete the CCB structure (free memory)
200 // (d) If this is the last close, release the FCB structure
201 // (unless we keep these around for "delayed close" functionality.
202 // Note that it is often the case that the close dispatch entry point is invoked
203 // in the most inconvenient of situations (when it is not possible, for example,
204 // to safely acquire certain required resources without deadlocking or waiting).
205 // Therefore, be extremely careful in implementing this close dispatch entry point.
206 // Also note that we do not have the option of returning a failure code from the
207 // close dispatch entry point; the system expects that the close will always succeed.
208
209 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
210 AcquiredVcb = TRUE;
211
212 // Is this is the first (IOManager) request ?
213 if (Irp) {
214 PtrIrpContext->TreeLength =
215 i = Ccb->TreeLength;
216 // remember the number of incomplete Close requests
217 InterlockedIncrement((PLONG)&(Fcb->CcbCount));
218 // we can release CCB in any case
220 FileObject->FsContext2 = NULL;
221#ifdef DBG
222/* } else {
223 ASSERT(Fcb->NTRequiredFCB);
224 if(Fcb->NTRequiredFCB) {
225 ASSERT(Fcb->NTRequiredFCB->FileObject);
226 if(Fcb->NTRequiredFCB->FileObject) {
227 ASSERT(!Fcb->NTRequiredFCB->FileObject->FsContext2);
228 }
229 }*/
230#endif //DBG
231 }
232
233#ifdef UDF_DELAYED_CLOSE
234 // check if this is the last Close (no more Handles)
235 // and try to Delay it....
236 if((Fcb->FCBFlags & UDF_FCB_DELAY_CLOSE) &&
237 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
238 !(Vcb->VCBFlags & UDF_VCB_FLAGS_NO_DELAYED_CLOSE) &&
239 !(Fcb->OpenHandleCount)) {
240 UDFReleaseResource(&(Vcb->VCBResource));
241 AcquiredVcb = FALSE;
242 if((RC = UDFQueueDelayedClose(PtrIrpContext,Fcb)) == STATUS_SUCCESS)
244 // do standard Close if we can't Delay this opeartion
245 AdPrint((" Cant queue Close Irp, status=%x\n", RC));
246 }
247#endif //UDF_DELAYED_CLOSE
248
249 if(Irp) {
250 // We should post actual procesing if this is a recursive call
251 if((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_TOP_LEVEL) ||
252 (Fcb->NTRequiredFCB->AcqFlushCount)) {
253 AdPrint((" post NOT_TOP_LEVEL Irp\n"));
254 PostRequest = TRUE;
256 }
257 }
258
259 // Close request is near completion, Vcb is acquired.
260 // Now we can safely decrease CcbCount, because no Rename
261 // operation can run until Vcb release.
262 InterlockedDecrement((PLONG)&(Fcb->CcbCount));
263
264 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
265 if(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_READ_ONLY)
266 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCountRO));
267
268 if(!i || (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB)) {
269
270 AdPrint(("UDF: Closing volume\n"));
271 AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
272
273 if (Vcb->VCBOpenCount > UDF_RESIDUAL_REFERENCE) {
274 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
275 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
276 ASSERT(Fcb->NTRequiredFCB);
277 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
278
280 }
281
282 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
283
284 if(AcquiredVcb) {
285 UDFReleaseResource(&(Vcb->VCBResource));
286 AcquiredVcb = FALSE;
287 } else {
288 BrutePoint();
289 }
290 // Acquire GlobalDataResource
291 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
292 AcquiredGD = TRUE;
293// // Acquire Vcb
294 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
295 AcquiredVcb = TRUE;
296
297 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
298
299
300 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
301 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
302 ASSERT(Fcb->NTRequiredFCB);
303 UDFInterlockedDecrement((PLONG)&(Fcb->NTRequiredFCB->CommonRefCount));
304
305 //AdPrint(("UDF: Closing volume, reset driver (e.g. stop BGF)\n"));
306 //UDFResetDeviceDriver(Vcb, Vcb->TargetDeviceObject, FALSE);
307
308 AdPrint(("UDF: Closing volume, reset write status\n"));
309 RC = UDFPhSendIOCTL(IOCTL_CDRW_RESET_WRITE_STATUS, Vcb->TargetDeviceObject,
310 NULL, 0, NULL, 0, TRUE, NULL);
311
312 if((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) ||
313 ((!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) && (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE))) {
314 // Try to KILL dismounted volume....
315 // w2k requires this, NT4 - recomends
316 AcquiredVcb = UDFCheckForDismount(PtrIrpContext, Vcb, TRUE);
317 }
318
320 }
321
322 fi = Fcb->FileInfo;
323#ifdef UDF_DBG
324 if(!fi) {
325 BrutePoint();
326 }
327
328 DirNdx = UDFGetDirIndexByFileInfo(fi);
329 if(DirNdx) {
330 CurName.Buffer = UDFDirIndex(DirNdx,fi->Index)->FName.Buffer;
331 if(CurName.Buffer) {
332 AdPrint(("Closing file: %ws %8.8x\n", CurName.Buffer, FileObject));
333 } else {
334 AdPrint(("Closing file: ??? \n"));
335 }
336 }
337 AdPrint(("UDF: ReferenceCount: %x\n",Fcb->ReferenceCount));
338#endif // UDF_DBG
339 // try to clean up as long chain as it is possible
341
342try_exit: NOTHING;
343
344 } _SEH2_FINALLY {
345
346 if(AcquiredVcb) {
347 UDFReleaseResource(&(Vcb->VCBResource));
348 }
349 if(AcquiredGD) {
350 UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
351 }
352
353 // Post IRP if required
354 if (PostRequest) {
355
356 // Perform the post operation & complete the IRP
357 // if this is first call of UDFCommonClose
358 // and will return STATUS_SUCCESS back to us
359 PtrIrpContext->Irp = NULL;
360 PtrIrpContext->Fcb = Fcb;
361 UDFPostRequest(PtrIrpContext, NULL);
362 }
363
365 // If this is not async close complete the IRP
366 if (Irp) {
367/* if( FileObject ) {
368 if(clean_stat & UDF_CLOSE_NTREQFCB_DELETED) {
369// ASSERT(!FileObject->FsContext2);
370 FileObject->FsContext = NULL;
371#ifdef DBG
372 } else {
373 UDFNTRequiredFCB* NtReqFcb = ((UDFNTRequiredFCB*)(FileObject->FsContext));
374 if(NtReqFcb->FileObject == FileObject) {
375 NtReqFcb->FileObject = NULL;
376 }
377#endif //DBG
378 }
379 }*/
380 Irp->IoStatus.Status = STATUS_SUCCESS;
381 Irp->IoStatus.Information = 0;
383 }
384 // Free up the Irp Context
385 if(!PostRequest)
386 UDFReleaseIrpContext(PtrIrpContext);
387 }
388
389 } _SEH2_END; // end of "__finally" processing
390
391 return STATUS_SUCCESS ;
392} // end UDFCommonClose()
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define IOCTL_CDRW_RESET_WRITE_STATUS
Definition: cdrw_usr.h:102
NTSTATUS UDFQueueDelayedClose(PtrUDFIrpContext IrpContext, PtrUDFFCB Fcb)
Definition: close.cpp:1106
NTSTATUS UDFPostRequest(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: misc.cpp:1128
VOID __fastcall UDFCleanUpCCB(PtrUDFCCB Ccb)
Definition: misc.cpp:805
NTSTATUS NTAPI UDFPhSendIOCTL(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:511
#define UDFInterlockedIncrement(addr)
Definition: env_spec_w32.h:675
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN VcbAcquired)
Definition: verfysup.cpp:629
#define UDF_CCB_READ_ONLY
Definition: struct.h:170
#define UDF_IRP_CONTEXT_READ_ONLY
Definition: struct.h:394
_UDFFileControlBlock * Fcb
Definition: struct.h:378
ULONG TreeLength
Definition: struct.h:379

Referenced by UDFClose(), UDFCommonDispatch(), and UDFDoDelayedClose().

◆ UDFCommonCreate()

NTSTATUS UDFCommonCreate ( IN PtrUDFIrpContext  PtrIrpContext,
IN PIRP  Irp 
)

◆ UDFCommonDeviceControl()

NTSTATUS NTAPI UDFCommonDeviceControl ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 149 of file devcntrl.cpp.

153{
156// PIO_STACK_LOCATION PtrNextIoStackLocation = NULL;
160 PVCB Vcb = NULL;
163// PVOID BufferPointer = NULL;
164 BOOLEAN AcquiredVcb = FALSE;
165 BOOLEAN FSDevObj;
166 ULONG TrackNumber;
167 BOOLEAN UnsafeIoctl = TRUE;
168 UCHAR ScsiCommand;
169 PPREVENT_MEDIA_REMOVAL_USER_IN Buf = NULL; // FSD buffer
170 PCDB Cdb;
171 PCHAR CdbData;
172 PCHAR ModeSelectData;
173
174 UDFPrint(("UDFCommonDeviceControl\n"));
175
176 _SEH2_TRY {
177 // First, get a pointer to the current I/O stack location
179 ASSERT(IrpSp);
180
181 // Get the IoControlCode value
182 IoControlCode = IrpSp->Parameters.DeviceIoControl.IoControlCode;
183
186
187 FSDevObj = UDFIsFSDevObj(PtrIrpContext->TargetDeviceObject);
188
189 if(FSDevObj) {
190 switch (IoControlCode) {
194#ifndef UDF_READ_ONLY_BUILD
196#endif //UDF_READ_ONLY_BUILD
198 break;
199 default:
200 UDFPrint(("UDFCommonDeviceControl: STATUS_INVALID_PARAMETER %x for FsDevObj\n", IoControlCode));
203 }
204 } else {
205 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
206 if(!Ccb) {
207 UDFPrint((" !Ccb\n"));
208 goto ioctl_do_default;
209 }
210 ASSERT(Ccb);
211 Fcb = Ccb->Fcb;
212 ASSERT(Fcb);
213
214 // Check if the IOCTL is suitable for this type of File
215 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
216 // Everything is acceptable for Volume
217 Vcb = (PVCB)(Fcb);
218 } else {
219 Vcb = Fcb->Vcb;
221 // For files/disrs only the following are acceptable
222 switch (IoControlCode) {
226 break;
227 default:
228 UDFPrint(("UDFCommonDeviceControl: STATUS_INVALID_PARAMETER %x for File/Dir Obj\n", IoControlCode));
230 }
231 }
232 // check 'safe' IOCTLs
233 switch (IoControlCode) {
235
240
245
250
255
269
274
278
280
298
300
303
310// case :
311
313
314 UnsafeIoctl = FALSE;
315 break;
316 }
317
319 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
320 } else {
321 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
322 }
323 AcquiredVcb = TRUE;
324 }
325
326 UDFPrint(("UDF Irp %x, ctx %x, DevIoCtl %x\n", Irp, PtrIrpContext, IoControlCode));
327
328 // We may wish to allow only volume open operations.
329 switch (IoControlCode) {
330
333
334 if(!Irp->AssociatedIrp.SystemBuffer)
335 goto ioctl_do_default;
336
338 Cdb = (PCDB)&(((PSCSI_PASS_THROUGH_DIRECT)(Irp->AssociatedIrp.SystemBuffer))->Cdb);
339 CdbData = (PCHAR)(((PSCSI_PASS_THROUGH_DIRECT)(Irp->AssociatedIrp.SystemBuffer))->DataBuffer);
340 } else {
341 Cdb = (PCDB)&(((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->Cdb);
342 if(((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->DataBufferOffset) {
343 CdbData = ((PCHAR)Cdb) +
344 ((PSCSI_PASS_THROUGH)(Irp->AssociatedIrp.SystemBuffer))->DataBufferOffset;
345 } else {
346 CdbData = NULL;
347 }
348 }
349 ScsiCommand = Cdb->CDB6.OperationCode;
350
351 if(ScsiCommand == SCSIOP_WRITE_CD) {
352 UDFPrint(("Write10, LBA %2.2x%2.2x%2.2x%2.2x\n",
353 Cdb->WRITE_CD.LBA[0],
354 Cdb->WRITE_CD.LBA[1],
355 Cdb->WRITE_CD.LBA[2],
356 Cdb->WRITE_CD.LBA[3]
357 ));
358 } else
359 if(ScsiCommand == SCSIOP_WRITE12) {
360 UDFPrint(("Write12, LBA %2.2x%2.2x%2.2x%2.2x\n",
361 Cdb->CDB12READWRITE.LBA[0],
362 Cdb->CDB12READWRITE.LBA[1],
363 Cdb->CDB12READWRITE.LBA[2],
364 Cdb->CDB12READWRITE.LBA[3]
365 ));
366 } else {
367 }
368
369 switch(ScsiCommand) {
370 case SCSIOP_MODE_SELECT: {
371// PMODE_PARAMETER_HEADER ParamHdr = (PMODE_PARAMETER_HEADER)CdbData;
372 ModeSelectData = CdbData+4;
373 switch(ModeSelectData[0]) {
374 case MODE_PAGE_MRW2:
376 case MODE_PAGE_MRW:
377 UDFPrint(("Unsafe MODE_SELECT_6 via pass-through (%2.2x)\n", ModeSelectData[0]));
378 goto unsafe_direct_scsi_cmd;
379 }
380 break; }
381
383// PMODE_PARAMETER_HEADER10 ParamHdr = (PMODE_PARAMETER_HEADER10)CdbData;
384 ModeSelectData = CdbData+8;
385 switch(ModeSelectData[0]) {
386 case MODE_PAGE_MRW2:
388 case MODE_PAGE_MRW:
389 UDFPrint(("Unsafe MODE_SELECT_10 via pass-through (%2.2x)\n", ModeSelectData[0]));
390 goto unsafe_direct_scsi_cmd;
391 }
392 break; }
393
399 case SCSIOP_WRITE6:
400 case SCSIOP_WRITE_CD:
401 case SCSIOP_BLANK:
402 case SCSIOP_WRITE12:
404 UDFPrint(("UDF Direct media modification via pass-through (%2.2x)\n", ScsiCommand));
405unsafe_direct_scsi_cmd:
406 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED))
407 goto ioctl_do_default;
408
409 UDFPrint(("Forget this volume\n"));
410 // Acquire Vcb resource (Shared -> Exclusive)
411 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
412 UDFReleaseResource(&(Vcb->VCBResource));
413
414 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
415 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
416 }
417#ifdef UDF_DELAYED_CLOSE
418 // Acquire exclusive access to the Vcb.
420#endif //UDF_DELAYED_CLOSE
421
422 // allocate tmp buffer for FSD calls
424 if(!Buf)
426
427 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
428 AcquiredVcb = TRUE;
429 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
430
432 MyFreePool__(Buf);
433 Buf = NULL;
434 Vcb->MediaLockCount = 0;
435
436 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
437 Vcb->WriteSecurity = FALSE;
438
439 // Release the Vcb resource.
440 UDFReleaseResource(&(Vcb->VCBResource));
441 AcquiredVcb = FALSE;
442 // disable Eject Request Waiter if any
444
445 // Make sure, that volume will never be quick-remounted
446 // It is very important for ChkUdf utility and
447 // some CD-recording libraries
448 Vcb->SerialNumber--;
449
450 UDFPrint(("Forgotten\n"));
451
452 goto notify_media_change;
453
455 case SCSIOP_DOORLOCK:
458 UDFPrint(("UDF Medium/Tray control IOCTL via pass-through\n"));
459 }
460 goto ioctl_do_default;
461
462 case IOCTL_CDRW_BLANK:
465
466notify_media_change:
467/* Vcb->VCBFlags |= UDF_VCB_FLAGS_UNSAFE_IOCTL;
468 // Make sure, that volume will never be quick-remounted
469 // It is very important for ChkUdf utility and
470 // some CD-recording libraries
471 Vcb->SerialNumber--;
472*/ goto ioctl_do_default;
473
475
476 UDFPrint(("UDF Register Autoformat\n"));
479 } else {
481 RC = STATUS_SUCCESS;
482 }
484 Irp->IoStatus.Information = 0;
485 break;
486 }
487
489
490 UDFPrint(("UDF Disable driver\n"));
491 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject);
492 // Now, delete any device objects, etc. we may have created
493 if (UDFGlobalData.UDFDeviceObject) {
494 IoDeleteDevice(UDFGlobalData.UDFDeviceObject);
495 UDFGlobalData.UDFDeviceObject = NULL;
496 }
497
498 // free up any memory we might have reserved for zones/lookaside
499 // lists
502 }
503
504 // delete the resource we may have initialized
506 // un-initialize this resource
507 UDFDeleteResource(&(UDFGlobalData.GlobalDataResource));
509 }
510 RC = STATUS_SUCCESS;
512 Irp->IoStatus.Information = 0;
513 break;
514 }
516 UDFPrint(("UDF Invaidate volume\n"));
517 if(AcquiredVcb) {
518 UDFReleaseResource(&(Vcb->VCBResource));
519 AcquiredVcb = FALSE;
520 }
521 RC = UDFInvalidateVolumes( PtrIrpContext, Irp );
523 Irp->IoStatus.Information = 0;
524 break;
525 }
526
528 {
529 if (IrpSp->Parameters.DeviceIoControl.InputBufferLength != sizeof(HANDLE))
530 {
532 }
533 else
534 {
535 HANDLE MountEventHandle = *(PHANDLE)Irp->AssociatedIrp.SystemBuffer;
536 if (MountEventHandle)
537 {
538 if (!UDFGlobalData.MountEvent)
539 {
541 MountEventHandle,
542 0,
543 NULL,
544 UserMode,
545 (PVOID *) &UDFGlobalData.MountEvent,
546 NULL);
547
548 if (!NT_SUCCESS(RC))
549 {
550 UDFGlobalData.MountEvent = NULL;
551 }
552 }
553 else
554 {
556 }
557 }
558 else
559 {
560 if (!UDFGlobalData.MountEvent)
561 {
563 }
564 else
565 {
567 UDFGlobalData.MountEvent = NULL;
568 }
569 }
570 }
571
573 Irp->IoStatus.Information = 0;
574 break;
575 }
576
578 {
579 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(BOOLEAN))
580 {
582 }
583 else
584 {
585 *(PBOOLEAN)Irp->AssociatedIrp.SystemBuffer = Vcb->IsVolumeJustMounted;
586 Vcb->IsVolumeJustMounted = FALSE;
587 }
588
590 Irp->IoStatus.Information = 0;
591 break;
592 }
593
594
595 //case FSCTL_GET_RETRIEVAL_POINTERS
597 UDFPrint(("UDF: Get Retrieval Pointers\n"));
598 RC = UDFGetRetrievalPointers( PtrIrpContext, Irp, 0 );
600 break;
601 }
603 UDFPrint(("UDF: Get Spec Retrieval Pointers\n"));
604 PUDF_GET_SPEC_RETRIEVAL_POINTERS_IN SpecRetrPointer;
605 SpecRetrPointer = (PUDF_GET_SPEC_RETRIEVAL_POINTERS_IN)(Irp->AssociatedIrp.SystemBuffer);
606 RC = UDFGetRetrievalPointers( PtrIrpContext, Irp, SpecRetrPointer->Special );
608 break;
609 }
611 UDFPrint(("UDF: Get File Alloc mode (from ICB)\n"));
612 RC = UDFGetFileAllocModeFromICB( PtrIrpContext, Irp );
614 break;
615 }
616#ifndef UDF_READ_ONLY_BUILD
618 UDFPrint(("UDF: Set File Alloc mode\n"));
619 RC = UDFSetFileAllocModeFromICB( PtrIrpContext, Irp );
621 break;
622 }
623#endif //UDF_READ_ONLY_BUILD
625 if(AcquiredVcb) {
626 UDFReleaseResource(&(Vcb->VCBResource));
627 AcquiredVcb = FALSE;
628 }
629 RC = UDFLockVolume( PtrIrpContext, Irp, GetCurrentPID() );
631 break;
633 if(AcquiredVcb) {
634 UDFReleaseResource(&(Vcb->VCBResource));
635 AcquiredVcb = FALSE;
636 }
637 RC = UDFUnlockVolume( PtrIrpContext, Irp, GetCurrentPID() );
639 break;
640#ifndef UDF_READ_ONLY_BUILD
642 RC = STATUS_SUCCESS;
643
644 Irp->IoStatus.Information = 0;
645 Irp->IoStatus.Status = STATUS_SUCCESS;
647 break;
648#endif //UDF_READ_ONLY_BUILD
650
651 PUDF_GET_VERSION_OUT udf_ver;
652
653 UDFPrint(("UDFUserFsCtrlRequest: IOCTL_UDF_GET_VERSION\n"));
654
655 Irp->IoStatus.Information = 0;
657
658 if(!IrpSp->Parameters.DeviceIoControl.OutputBufferLength) {
659 UDFPrint(("!OutputBufferLength\n"));
661 }
662 // Check the size of the output buffer.
663 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UDF_GET_VERSION_OUT)) {
664 UDFPrint(("OutputBufferLength < %x\n", sizeof(UDF_GET_VERSION_OUT)));
666 }
667
668 udf_ver = (PUDF_GET_VERSION_OUT)(Irp->AssociatedIrp.SystemBuffer);
669 if(!udf_ver) {
670 UDFPrint(("!udf_ver\n"));
672 }
673
674 RtlZeroMemory(udf_ver, IrpSp->Parameters.DeviceIoControl.OutputBufferLength);
675
676 udf_ver->header.Length = sizeof(UDF_GET_VERSION_OUT);
677 udf_ver->header.DriverVersionMj = 0x00010005;
678 udf_ver->header.DriverVersionMn = 0x12;
679 udf_ver->header.DriverVersionBuild = UDF_CURRENT_BUILD;
680
681 udf_ver->FSVersionMj = Vcb->CurrentUDFRev >> 8;
682 udf_ver->FSVersionMn = Vcb->CurrentUDFRev & 0xff;
683 udf_ver->FSFlags = Vcb->UserFSFlags;
684 if( ((Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) &&
685 (Vcb->CompatFlags & UDF_VCB_IC_DIRTY_RO))
686 ||
687 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) ) {
688 UDFPrint((" UDF_USER_FS_FLAGS_RO\n"));
689 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_RO;
690 }
691 if(Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER) {
692 UDFPrint((" UDF_USER_FS_FLAGS_OUR_DRIVER\n"));
694 }
695 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
696 UDFPrint((" UDF_USER_FS_FLAGS_RAW\n"));
697 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_RAW;
698 }
699 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
700 UDFPrint((" UDF_USER_FS_FLAGS_MEDIA_RO\n"));
702 }
703 if(Vcb->FP_disc) {
704 UDFPrint((" UDF_USER_FS_FLAGS_FP\n"));
705 udf_ver->FSFlags |= UDF_USER_FS_FLAGS_FP;
706 }
707 udf_ver->FSCompatFlags = Vcb->CompatFlags;
708
709 udf_ver->FSCfgVersion = Vcb->CfgVersion;
710
711 Irp->IoStatus.Information = sizeof(UDF_GET_VERSION_OUT);
712 RC = STATUS_SUCCESS;
714
715 break; }
717
718 PUDF_SET_OPTIONS_IN udf_opt;
719 BOOLEAN PrevVerifyOnWrite;
720
721 UDFPrint(("UDF: IOCTL_UDF_SET_OPTIONS\n"));
722
723 Irp->IoStatus.Information = 0;
725
726 if(IrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(UDF_SET_OPTIONS_IN)) {
727 UDFPrint(("InputBufferLength < %x\n", sizeof(UDF_SET_OPTIONS_IN)));
729 }
730
731 udf_opt = (PUDF_SET_OPTIONS_IN)(Irp->AssociatedIrp.SystemBuffer);
732 if(!udf_opt) {
733 UDFPrint(("!udf_opt\n"));
735 }
736
738 UDFPrint(("invalid opt target\n"));
740 }
741
742 if(AcquiredVcb) {
743 UDFReleaseResource(&(Vcb->VCBResource));
744 AcquiredVcb = FALSE;
745 }
746 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
747 AcquiredVcb = TRUE;
748
749 PrevVerifyOnWrite = Vcb->VerifyOnWrite;
750
751 Vcb->Cfg = ((PUCHAR)(udf_opt)) + udf_opt->header.HdrLength;
752 Vcb->CfgLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength - offsetof(UDF_SET_OPTIONS_IN, Data);
753 UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE /*cfg*/);
754 Vcb->Cfg = NULL;
755 Vcb->CfgLength = 0;
756 Vcb->CfgVersion++;
757 //UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE);
758 if(PrevVerifyOnWrite != Vcb->VerifyOnWrite) {
759 if(Vcb->VerifyOnWrite) {
760 UDFVInit(Vcb);
761 } else {
762 WCacheFlushBlocks__(&(Vcb->FastCache), Vcb, 0, Vcb->LastLBA);
763 UDFVFlush(Vcb);
765 }
766 }
767
768 RC = STATUS_SUCCESS;
769 break; }
770#if 0
771 case IOCTL_UDF_GET_OPTIONS_VERSION: {
772
773 PUDF_GET_OPTIONS_VERSION_OUT udf_opt_ver;
774
775 UDFPrint(("UDF: IOCTL_UDF_GET_OPTIONS_VERSION\n"));
776
777 Irp->IoStatus.Information = 0;
779
780 if(IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(UDF_GET_OPTIONS_VERSION_OUT)) {
781 UDFPrint(("OutputBufferLength < %x\n", sizeof(UDF_GET_OPTIONS_VERSION_OUT)));
783 }
784
785 udf_opt_ver = (PUDF_GET_OPTIONS_VERSION_OUT)(Irp->AssociatedIrp.SystemBuffer);
786 if(!udf_opt_ver) {
787 UDFPrint(("!udf_opt-ver\n"));
789 }
790/*
791 if(AcquiredVcb) {
792 UDFReleaseResource(&(Vcb->VCBResource));
793 AcquiredVcb = FALSE;
794 }
795 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
796 AcquiredVcb = TRUE;
797*/
798 udf_opt_ver->CfgVersion = Vcb->CfgVersion;
799 Irp->IoStatus.Information = sizeof(UDF_GET_OPTIONS_VERSION_OUT);
800
801 RC = STATUS_SUCCESS;
802 break; }
803#endif //0
805
806 UDFPrint(("UDF: IOCTL_CDRW_RESET_DRIVER\n"));
807 Vcb->MediaLockCount = 0;
808 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_MEDIA_LOCKED;
809 goto ioctl_do_default;
810
812
813 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_ALLOW_EXTENDED_DASD_IO\n"));
814 // DASD i/o is always permitted
815 // So, no-op this call
816 RC = STATUS_SUCCESS;
817
818 Irp->IoStatus.Information = 0;
819 Irp->IoStatus.Status = STATUS_SUCCESS;
821 break;
822
824
825 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_IS_VOLUME_DIRTY\n"));
826 // DASD i/o is always permitted
827 // So, no-op this call
828 RC = UDFIsVolumeDirty(PtrIrpContext, Irp);
830 break;
831
835
836 UDFPrint(("UDF Reset/Eject request\n"));
837// PPREVENT_MEDIA_REMOVAL_USER_IN Buf;
838
839 if(Vcb->EjectWaiter) {
840 UDFPrint((" Vcb->EjectWaiter present\n"));
841 Irp->IoStatus.Information = 0;
842 Vcb->EjectWaiter->SoftEjectReq = TRUE;
843 Vcb->SoftEjectReq = TRUE;
846 }
847 UDFPrint((" !Vcb->EjectWaiter\n"));
848 goto ioctl_do_default;
849/*
850 Buf = (PPREVENT_MEDIA_REMOVAL_USER_IN)MyAllocatePool__(NonPagedPool, sizeof(PREVENT_MEDIA_REMOVAL_USER_IN));
851 if(!Buf) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
852 // Acquire Vcb resource (Shared -> Exclusive)
853 UDFReleaseResource(&(Vcb->VCBResource));
854 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
855
856 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
857 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
858
859 UDFDoDismountSequence(Vcb, Buf, IoControlCode == IOCTL_CDROM_EJECT_MEDIA);
860 // disable Eject Request Waiter if any
861 MyFreePool__(Buf);
862 // Release the Vcb resource.
863 UDFReleaseResource(&(Vcb->VCBResource));
864 AcquiredVcb = FALSE;
865 UDFStopEjectWaiter(Vcb);
866 CompleteIrp = TRUE;
867 RC = STATUS_SUCCESS;
868 break;*/
869 }
871
872 UDFPrint(("UDF Cdrom Disk Type\n"));
874 // Verify the Vcb in this case to detect if the volume has changed.
875 Irp->IoStatus.Information = 0;
876 RC = UDFVerifyVcb(PtrIrpContext,Vcb);
877 if(!NT_SUCCESS(RC))
878 try_return(RC);
879
880 // Check the size of the output buffer.
881 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof(CDROM_DISK_DATA_USER_OUT))
883
884 // Copy the data from the Vcb.
885 ((PCDROM_DISK_DATA_USER_OUT)(Irp->AssociatedIrp.SystemBuffer))->DiskData = CDROM_DISK_DATA_TRACK;
886 for(TrackNumber=Vcb->FirstTrackNum; TrackNumber<Vcb->LastTrackNum; TrackNumber++) {
887 if((Vcb->TrackMap[TrackNumber].TrackParam & Trk_QSubChan_Type_Mask) ==
889 ((PCDROM_DISK_DATA_USER_OUT)(Irp->AssociatedIrp.SystemBuffer))->DiskData |= CDROM_DISK_AUDIO_TRACK;
890 break;
891 }
892 }
893
894 Irp->IoStatus.Information = sizeof(CDROM_DISK_DATA_USER_OUT);
895 RC = STATUS_SUCCESS;
896 break;
897 }
898
903 UDFPrint(("UDF Lock/Unlock\n"));
904 PPREVENT_MEDIA_REMOVAL_USER_IN buffer; // user supplied buffer
905 buffer = (PPREVENT_MEDIA_REMOVAL_USER_IN)(Irp->AssociatedIrp.SystemBuffer);
906 if(!buffer) {
907 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
908 UDFPrint(("!mounted\n"));
909 goto ioctl_do_default;
910 }
911 UDFPrint(("abort\n"));
913 Irp->IoStatus.Information = 0;
914 UnsafeIoctl = FALSE;
916 break;
917 }
918 if(!buffer->PreventMediaRemoval &&
919 !Vcb->MediaLockCount) {
920
921 UDFPrint(("!locked + unlock req\n"));
922 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
923 UDFPrint(("!mounted\n"));
924 goto ioctl_do_default;
925 }
926#if 0
927 // allocate tmp buffer for FSD calls
929 if(!Buf)
931
932 // Acquire Vcb resource (Shared -> Exclusive)
933 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
934 UDFReleaseResource(&(Vcb->VCBResource));
935
936#ifdef UDF_DELAYED_CLOSE
937 // Acquire exclusive access to the Vcb.
939#endif //UDF_DELAYED_CLOSE
940
941 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
942 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
943
945 MyFreePool__(Buf);
946 Buf = NULL;
947 Vcb->MediaLockCount = 0;
948 // Release the Vcb resource.
949 UDFReleaseResource(&(Vcb->VCBResource));
950 AcquiredVcb = FALSE;
951 // disable Eject Request Waiter if any
953#else
954 // just ignore
955#endif
956ignore_lock:
957 UDFPrint(("ignore lock/unlock\n"));
959 Irp->IoStatus.Information = 0;
960 RC = STATUS_SUCCESS;
961 break;
962 }
963 if(buffer->PreventMediaRemoval) {
964 UDFPrint(("lock req\n"));
965 Vcb->MediaLockCount++;
966 Vcb->VCBFlags |= UDF_VCB_FLAGS_MEDIA_LOCKED;
967 UnsafeIoctl = FALSE;
968 } else {
969 UDFPrint(("unlock req\n"));
970 if(Vcb->MediaLockCount) {
971 UDFPrint(("lock count %d\n", Vcb->MediaLockCount));
972 UnsafeIoctl = FALSE;
973 Vcb->MediaLockCount--;
974 }
975 }
976 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
977 UDFPrint(("!mounted\n"));
978 goto ioctl_do_default;
979 }
980 goto ignore_lock;
981 }
982 default:
983
984 UDFPrint(("default processing Irp %x, ctx %x, DevIoCtl %x\n", Irp, PtrIrpContext, IoControlCode));
985ioctl_do_default:
986
987 // make sure volume is Sync'ed BEFORE sending unsafe IOCTL
988 if(Vcb && UnsafeIoctl) {
990 UDFPrint((" sync'ed\n"));
991 }
992 // Invoke the lower level driver in the chain.
993 //PtrNextIoStackLocation = IoGetNextIrpStackLocation(Irp);
994 //*PtrNextIoStackLocation = *IrpSp;
996/*
997 // Set a completion routine.
998 IoSetCompletionRoutine(Irp, UDFDevIoctlCompletion, PtrIrpContext, TRUE, TRUE, TRUE);
999 // Send the request.
1000*/
1001 RC = IoCallDriver(Vcb->TargetDeviceObject, Irp);
1002 if(!CompleteIrp) {
1003 // since now we do not use IoSetCompletionRoutine()
1004 UDFReleaseIrpContext(PtrIrpContext);
1005 }
1006 break;
1007 }
1008
1009 if(Vcb && UnsafeIoctl) {
1010 UDFPrint((" set UnsafeIoctl\n"));
1011 Vcb->VCBFlags |= UDF_VCB_FLAGS_UNSAFE_IOCTL;
1012 }
1013
1014try_exit: NOTHING;
1015
1016 } _SEH2_FINALLY {
1017
1018 if(AcquiredVcb) {
1019 UDFReleaseResource(&(Vcb->VCBResource));
1020 AcquiredVcb = FALSE;
1021 }
1022
1023 if(Buf) {
1024 MyFreePool__(Buf);
1025 }
1026
1028 CompleteIrp) {
1029 UDFPrint((" complete Irp %x, ctx %x, status %x, iolen %x\n",
1030 Irp, PtrIrpContext, RC, Irp->IoStatus.Information));
1031 Irp->IoStatus.Status = RC;
1032 // complete the IRP
1034 // Release the IRP context
1035 UDFReleaseIrpContext(PtrIrpContext);
1036 }
1037 } _SEH2_END;
1038
1039 return(RC);
1040} // end UDFCommonDeviceControl()
#define SCSIOP_WRITE_CD
Definition: cdrw_hw.h:907
#define Trk_QSubChan_Type_Mask
Definition: cdrw_hw.h:2370
#define SCSIOP_DOORUNLOCK
Definition: cdrw_hw.h:972
#define Trk_QSubChan_Type_Audio
Definition: cdrw_hw.h:2372
#define SCSIOP_SEND_CUE_SHEET
Definition: cdrw_hw.h:949
#define SCSIOP_WRITE6
Definition: cdrw_hw.h:876
#define MODE_PAGE_MRW2
Definition: cdrw_hw.h:843
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define SCSIOP_SEND_DVD_STRUCTURE
Definition: cdrw_hw.h:969
#define SCSIOP_FORMAT_UNIT
Definition: cdrw_hw.h:871
#define SCSIOP_RESERVE_TRACK
Definition: cdrw_hw.h:941
#define MODE_PAGE_WRITE_PARAMS
Definition: cdrw_hw.h:844
#define MODE_PAGE_MRW
Definition: cdrw_hw.h:855
#define SCSIOP_CLOSE_TRACK_SESSION
Definition: cdrw_hw.h:947
#define SCSIOP_BLANK
Definition: cdrw_hw.h:950
#define SCSIOP_DOORLOCK
Definition: cdrw_hw.h:971
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
union _CDB * PCDB
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define SCSIOP_SET_STREAMING
Definition: cdrw_hw.h:963
#define SCSIOP_MODE_SELECT10
Definition: cdrw_hw.h:943
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
#define IOCTL_CDRW_READ_ATIP
Definition: cdrw_usr.h:116
#define IOCTL_CDRW_GET_WRITE_MODE
Definition: cdrw_usr.h:85
#define IOCTL_CDROM_EJECT_MEDIA
Definition: cdrw_usr.h:60
#define IOCTL_CDRW_READ_SESSION_INFO
Definition: cdrw_usr.h:115
#define IOCTL_CDRW_BUFFER_CAPACITY
Definition: cdrw_usr.h:94
#define IOCTL_CDRW_GET_MEDIA_TYPE
Definition: cdrw_usr.h:84
#define IOCTL_CDRW_MODE_SENSE
Definition: cdrw_usr.h:104
struct _CDROM_DISK_DATA_USER_OUT CDROM_DISK_DATA_USER_OUT
struct _PREVENT_MEDIA_REMOVAL_USER_IN * PPREVENT_MEDIA_REMOVAL_USER_IN
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define IOCTL_DISK_GET_DRIVE_GEOMETRY
Definition: cdrw_usr.h:169
struct _CDROM_DISK_DATA_USER_OUT * PCDROM_DISK_DATA_USER_OUT
#define IOCTL_CDRW_READ_TOC_EX
Definition: cdrw_usr.h:118
#define IOCTL_CDRW_BLANK
Definition: cdrw_usr.h:88
#define IOCTL_CDRW_LL_READ
Definition: cdrw_usr.h:110
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
#define IOCTL_CDRW_READ_TRACK_INFO
Definition: cdrw_usr.h:92
#define IOCTL_DISK_EJECT_MEDIA
Definition: cdrw_usr.h:177
#define IOCTL_CDRW_LOCK_DOOR
Definition: cdrw_usr.h:79
#define IOCTL_DISK_LOAD_MEDIA
Definition: cdrw_usr.h:178
#define IOCTL_CDRW_READ_PMA
Definition: cdrw_usr.h:114
#define IOCTL_CDRW_GET_DEVICE_NAME
Definition: cdrw_usr.h:121
#define IOCTL_DISK_GET_MEDIA_TYPES
Definition: cdrw_usr.h:182
#define IOCTL_CDRW_RESET_DRIVER
Definition: cdrw_usr.h:96
#define IOCTL_CDRW_GET_SIGNATURE
Definition: cdrw_usr.h:95
#define IOCTL_DISK_IS_WRITABLE
Definition: cdrw_usr.h:172
#define IOCTL_CDROM_LOAD_MEDIA
Definition: cdrw_usr.h:61
#define IOCTL_CDRW_TEST_UNIT_READY
Definition: cdrw_usr.h:101
#define IOCTL_DVD_READ_STRUCTURE
Definition: cdrw_usr.h:157
#define IOCTL_CDRW_GET_DEVICE_INFO
Definition: cdrw_usr.h:119
#define IOCTL_CDROM_MEDIA_REMOVAL
Definition: cdrw_usr.h:59
#define IOCTL_CDRW_READ_CD_TEXT
Definition: cdrw_usr.h:117
#define IOCTL_CDRW_LL_WRITE
Definition: cdrw_usr.h:91
#define IOCTL_CDRW_GET_EVENT
Definition: cdrw_usr.h:120
#define IOCTL_CDRW_READ_FULL_TOC
Definition: cdrw_usr.h:113
#define IOCTL_CDRW_READ_DISC_INFO
Definition: cdrw_usr.h:93
#define IOCTL_CDRW_GET_LAST_ERROR
Definition: cdrw_usr.h:103
#define IOCTL_CDRW_GET_MEDIA_TYPE_EX
Definition: cdrw_usr.h:123
#define IOCTL_CDRW_SET_SPEED
Definition: cdrw_usr.h:80
#define IOCTL_CDRW_FORMAT_UNIT
Definition: cdrw_usr.h:98
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX
Definition: cdrw_usr.h:190
#define IOCTL_CDRW_GET_CAPABILITIES
Definition: cdrw_usr.h:82
VOID UDFCloseAllDelayed(IN PVCB Vcb)
Definition: close.cpp:754
NTSTATUS UDFGetFileAllocModeFromICB(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: devcntrl.cpp:1132
#define UDF_CURRENT_BUILD
Definition: devcntrl.cpp:21
NTSTATUS UDFSetFileAllocModeFromICB(PtrUDFIrpContext IrpContext, PIRP Irp)
Definition: devcntrl.cpp:1169
VOID UDFReadRegKeys(PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg)
Definition: misc.cpp:1780
VOID UDFDestroyZones(VOID)
Definition: misc.cpp:177
VOID CompleteIrp(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: pnp.c:12
#define GetCurrentPID()
Definition: env_spec.h:152
#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX
Definition: ntddk_ex.h:208
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
#define IOCTL_DISK_GET_DRIVE_LAYOUT_EX
Definition: ntddk_ex.h:207
#define IOCTL_STORAGE_CHECK_VERIFY2
Definition: ntddk_ex.h:212
#define IOCTL_STORAGE_LOAD_MEDIA2
Definition: ntddk_ex.h:210
ULONG UDFFlushLogicalVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PVCB Vcb, IN ULONG FlushFlags)
Definition: flush.cpp:506
NTSTATUS UDFUnlockVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID)
Definition: fscntrl.cpp:1859
NTSTATUS UDFLockVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG PID)
Definition: fscntrl.cpp:1724
NTSTATUS UDFGetRetrievalPointers(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN ULONG Special)
Definition: fscntrl.cpp:2205
NTSTATUS UDFIsVolumeDirty(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2367
NTSTATUS UDFInvalidateVolumes(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2441
GLuint buffer
Definition: glext.h:5915
if(dx< 0)
Definition: linetemp.h:194
#define PCHAR
Definition: match.c:90
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
#define IOCTL_CDROM_GET_LAST_SESSION
Definition: ntddcdrm.h:64
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX
Definition: ntddcdrm.h:76
#define IOCTL_CDROM_SEEK_AUDIO_MSF
Definition: ntddcdrm.h:37
#define IOCTL_CDROM_READ_TOC_EX
Definition: ntddcdrm.h:79
#define CDROM_DISK_DATA_TRACK
Definition: ntddcdrm.h:146
#define IOCTL_CDROM_GET_VOLUME
Definition: ntddcdrm.h:49
#define IOCTL_CDROM_CHECK_VERIFY
Definition: ntddcdrm.h:103
#define IOCTL_CDROM_DISK_TYPE
Definition: ntddcdrm.h:70
#define IOCTL_CDROM_PAUSE_AUDIO
Definition: ntddcdrm.h:43
#define CDROM_DISK_AUDIO_TRACK
Definition: ntddcdrm.h:145
#define IOCTL_CDROM_SET_VOLUME
Definition: ntddcdrm.h:55
#define IOCTL_CDROM_STOP_AUDIO
Definition: ntddcdrm.h:40
#define IOCTL_CDROM_GET_CONTROL
Definition: ntddcdrm.h:61
#define IOCTL_CDROM_READ_Q_CHANNEL
Definition: ntddcdrm.h:58
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY
Definition: ntddcdrm.h:73
#define IOCTL_CDROM_GET_CONFIGURATION
Definition: ntddcdrm.h:82
#define IOCTL_CDROM_PLAY_AUDIO_MSF
Definition: ntddcdrm.h:52
#define IOCTL_CDROM_RESUME_AUDIO
Definition: ntddcdrm.h:46
#define IOCTL_CDROM_READ_TOC
Definition: ntddcdrm.h:34
#define IOCTL_CDROM_RAW_READ
Definition: ntddcdrm.h:67
#define IOCTL_DISK_GET_DRIVE_LAYOUT
Definition: ntdddisk.h:91
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
#define IOCTL_STORAGE_CHECK_VERIFY
Definition: ntddstor.h:98
#define IOCTL_STORAGE_LOAD_MEDIA
Definition: ntddstor.h:110
#define IOCTL_STORAGE_GET_MEDIA_TYPES
Definition: ntddstor.h:131
#define IOCTL_STORAGE_EJECT_MEDIA
Definition: ntddstor.h:107
#define IOCTL_STORAGE_MEDIA_REMOVAL
Definition: ntddstor.h:104
#define IoSkipCurrentIrpStackLocation(Irp)
Definition: ntifs_ex.h:421
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
#define IoCallDriver
Definition: irp.c:1225
VOID NTAPI IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:1056
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
OSSTATUS UDFDoDismountSequence(IN PVCB Vcb, IN PPREVENT_MEDIA_REMOVAL_USER_IN Buf, IN BOOLEAN Eject)
Definition: phys_eject.cpp:704
NTSTATUS UDFVerifyVcb(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb)
Definition: verfysup.cpp:37
#define UDFCloseAllSystemDelayedInDir(Vcb, FI)
Definition: protos.h:99
#define FSCTL_IS_VOLUME_DIRTY
Definition: winioctl.h:714
#define FSCTL_ALLOW_EXTENDED_DASD_IO
Definition: winioctl.h:124
VOID UDFVFlush(IN PVCB Vcb)
Definition: remap.cpp:742
VOID UDFVRelease(IN PVCB Vcb)
Definition: remap.cpp:132
OSSTATUS UDFVInit(IN PVCB Vcb)
Definition: remap.cpp:54
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
struct _SCSI_PASS_THROUGH * PSCSI_PASS_THROUGH
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define offsetof(TYPE, MEMBER)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
uint32 UDFFlags
Definition: udf_common.h:627
struct _UDF_GET_VERSION_OUT::@960 header
struct _UDF_SET_OPTIONS_IN::@961 header
unsigned char * PBOOLEAN
Definition: typedefs.h:53
unsigned char * PUCHAR
Definition: typedefs.h:53
char * PCHAR
Definition: typedefs.h:51
#define UDF_DATA_FLAGS_RESOURCE_INITIALIZED
Definition: udf_common.h:634
#define UDF_DATA_FLAGS_ZONES_INITIALIZED
Definition: udf_common.h:635
#define UDF_VCB_FLAGS_UNSAFE_IOCTL
Definition: udf_common.h:488
#define UDF_VCB_FLAGS_MEDIA_READ_ONLY
Definition: udf_common.h:481
#define UDF_VCB_FLAGS_MEDIA_LOCKED
Definition: udf_common.h:469
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define UDFClearFlag(Flag, Value)
Definition: udffs.h:192
#define UDF_USER_FS_FLAGS_MEDIA_RO
Definition: udfpubl.h:111
#define IOCTL_UDF_SET_FILE_ALLOCATION_MODE
Definition: udfpubl.h:41
struct _UDF_GET_VERSION_OUT UDF_GET_VERSION_OUT
#define IOCTL_UDF_SET_OPTIONS
Definition: udfpubl.h:50
#define IOCTL_UDF_REGISTER_AUTOFORMAT
Definition: udfpubl.h:49
#define UDF_USER_FS_FLAGS_RAW
Definition: udfpubl.h:108
#define IOCTL_UDF_SET_NOTIFICATION_EVENT
Definition: udfpubl.h:47
#define IOCTL_UDF_GET_VERSION
Definition: udfpubl.h:46
#define IOCTL_UDF_GET_RETRIEVAL_POINTERS
Definition: udfpubl.h:39
#define IOCTL_UDF_INVALIDATE_VOLUMES
Definition: udfpubl.h:38
struct _UDF_SET_OPTIONS_IN * PUDF_SET_OPTIONS_IN
#define UDF_USER_FS_FLAGS_OUR_DRIVER
Definition: udfpubl.h:109
#define UDF_SET_OPTIONS_FLAG_TEMPORARY
Definition: udfpubl.h:132
struct _UDF_GET_VERSION_OUT * PUDF_GET_VERSION_OUT
#define IOCTL_UDF_GET_SPEC_RETRIEVAL_POINTERS
Definition: udfpubl.h:45
#define IOCTL_UDF_IS_VOLUME_JUST_MOUNTED
Definition: udfpubl.h:48
#define UDF_USER_FS_FLAGS_FP
Definition: udfpubl.h:110
#define UDF_USER_FS_FLAGS_RO
Definition: udfpubl.h:107
#define IOCTL_UDF_GET_FILE_ALLOCATION_MODE
Definition: udfpubl.h:40
#define IOCTL_UDF_LOCK_VOLUME_BY_PID
Definition: udfpubl.h:42
#define IOCTL_UDF_DISABLE_DRIVER
Definition: udfpubl.h:36
#define IOCTL_UDF_UNLOCK_VOLUME_BY_PID
Definition: udfpubl.h:43
#define UDF_SET_OPTIONS_FLAG_MASK
Definition: udfpubl.h:136
#define IOCTL_UDF_SEND_LICENSE_KEY
Definition: udfpubl.h:44
Definition: cdrw_hw.h:28
struct _CDB::_CDB6 CDB6
struct _CDB::_WRITE_CD WRITE_CD
struct _CDB::_CDB12READWRITE CDB12READWRITE
OSSTATUS WCacheFlushBlocks__(IN PW_CACHE Cache, IN PVOID Context, IN lba_t Lba, IN ULONG BCount)
_In_ WDFREQUEST _In_ size_t _In_ size_t _In_ ULONG IoControlCode
Definition: wdfio.h:325
#define ObDereferenceObject
Definition: obfuncs.h:203
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by UDFDeviceControl().

◆ UDFCommonDirControl()

NTSTATUS NTAPI UDFCommonDirControl ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 127 of file dircntrl.cpp.

131{
138 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
139
140 TmPrint(("UDFCommonDirControl: \n"));
141// BrutePoint();
142
143 _SEH2_TRY {
144 // First, get a pointer to the current I/O stack location
146 ASSERT(IrpSp);
147
150
151 // Get the FCB and CCB pointers
152 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
153 ASSERT(Ccb);
154 Fcb = Ccb->Fcb;
155 ASSERT(Fcb);
156
157 Vcb = (PVCB)(PtrIrpContext->TargetDeviceObject->DeviceExtension);
158 ASSERT(Vcb);
159 ASSERT(Vcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB);
160// Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
161
163 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
164 AcquiredVcb = TRUE;
165 // Get some of the parameters supplied to us
166 switch (IrpSp->MinorFunction) {
168 RC = UDFQueryDirectory(PtrIrpContext, Irp, IrpSp, FileObject, Fcb, Ccb);
169 break;
171 RC = UDFNotifyChangeDirectory(PtrIrpContext, Irp, IrpSp, FileObject, Fcb, Ccb);
172 break;
173 default:
174 // This should not happen.
176 Irp->IoStatus.Status = RC;
177 Irp->IoStatus.Information = 0;
178
179 // Free up the Irp Context
180 UDFReleaseIrpContext(PtrIrpContext);
181
182 // complete the IRP
184 break;
185 }
186
187//try_exit: NOTHING;
188
189 } _SEH2_FINALLY {
190
191 if(AcquiredVcb) {
192 UDFReleaseResource(&(Vcb->VCBResource));
193 AcquiredVcb = FALSE;
194 }
195 } _SEH2_END;
196 return(RC);
197} // end UDFCommonDirControl()
NTSTATUS NTAPI UDFQueryDirectory(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, PFILE_OBJECT FileObject, PtrUDFFCB Fcb, PtrUDFCCB Ccb)
Definition: dircntrl.cpp:216
NTSTATUS NTAPI UDFNotifyChangeDirectory(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, PFILE_OBJECT FileObject, PtrUDFFCB Fcb, PtrUDFCCB Ccb)
Definition: dircntrl.cpp:683
VOID UDFFlushTryBreak(IN PVCB Vcb)
Definition: flush.cpp:625
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138

Referenced by UDFCommonDispatch(), and UDFDirControl().

◆ UDFCommonDispatch()

VOID NTAPI UDFCommonDispatch ( VOID Context)

◆ UDFCommonFileInfo()

NTSTATUS UDFCommonFileInfo ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 114 of file fileinfo.cpp.

118{
124 PVCB Vcb = NULL;
126 BOOLEAN MainResourceAcquired = FALSE;
127 BOOLEAN ParentResourceAcquired = FALSE;
128 BOOLEAN PagingIoResourceAcquired = FALSE;
129 PVOID PtrSystemBuffer = NULL;
130 LONG BufferLength = 0;
131 FILE_INFORMATION_CLASS FunctionalityRequested;
132 BOOLEAN CanWait = FALSE;
133 BOOLEAN PostRequest = FALSE;
134 BOOLEAN AcquiredVcb = FALSE;
135 PIRP TopIrp;
136
137 TmPrint(("UDFCommonFileInfo: irp %x\n", Irp));
138
139 TopIrp = IoGetTopLevelIrp();
140 switch((ULONG_PTR)TopIrp) {
142 UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
143 break;
145 UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
146 break;
148 UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
149 break;
151 UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
152 BrutePoint()
153 break;
154 case NULL:
155 UDFPrint((" NULL TOP_LEVEL_IRP\n"));
156 break;
157 default:
158 if(TopIrp == Irp) {
159 UDFPrint((" TOP_LEVEL_IRP\n"));
160 } else {
161 UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
162 }
163 }
164
165 _SEH2_TRY {
166 // First, get a pointer to the current I/O stack location.
168 ASSERT(IrpSp);
169
172
173 // Get the FCB and CCB pointers.
174 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
175 ASSERT(Ccb);
176 if(!Ccb) {
177 // some applications sends us FO without Ccb
178 // This is not allowed...
180 try_return(RC);
181 }
182 Fcb = Ccb->Fcb;
183 ASSERT(Fcb);
184
185 NtReqFcb = Fcb->NTRequiredFCB;
186
187 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
188
189 // If the caller has opened a logical volume and is attempting to
190 // query information for it as a file stream, return an error.
191 if(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
192 // This is not allowed. Caller must use get/set volume information instead.
194 try_return(RC);
195 }
196
197
199 ASSERT(Vcb);
200 ASSERT(Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_FCB);
201 //Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
202
203 // The NT I/O Manager always allocates and supplies a system
204 // buffer for query and set file information calls.
205 // Copying information to/from the user buffer and the system
206 // buffer is performed by the I/O Manager and the FSD need not worry about it.
207 PtrSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
208
210 if(!UDFAcquireResourceShared(&(Vcb->VCBResource), CanWait)) {
211 PostRequest = TRUE;
213 }
214 AcquiredVcb = TRUE;
215
217 // Now, obtain some parameters.
218 BufferLength = IrpSp->Parameters.QueryFile.Length;
219 FunctionalityRequested = IrpSp->Parameters.QueryFile.FileInformationClass;
220#ifdef UDF_ENABLE_SECURITY
222 Ccb->PreviouslyGrantedAccess,
223 PtrIrpContext->MajorFunction,
224 PtrIrpContext->MinorFunction,
225 0,
226 &FunctionalityRequested,
227 NULL);
228 if(!NT_SUCCESS(RC)) {
229 try_return(RC);
230 }
231#endif //UDF_ENABLE_SECURITY
232 // Acquire the MainResource shared (NOTE: for paging-IO on a
233 // page file, we should avoid acquiring any resources and simply
234 // trust the VMM to do the right thing, else we could possibly
235 // run into deadlocks).
236 if(!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
237 // Acquire the MainResource shared.
239 UDFAcquireResourceShared(&(NtReqFcb->MainResource), TRUE);
240 MainResourceAcquired = TRUE;
241 }
242
243 // Do whatever the caller asked us to do
244 switch (FunctionalityRequested) {
247 break;
250 break;
251#if(_WIN32_WINNT >= 0x0400)
254 break;
255#endif // _WIN32_WINNT >= 0x0400
257 RC = UDFGetInternalInformation(PtrIrpContext, Fcb, Ccb, (PFILE_INTERNAL_INFORMATION) PtrSystemBuffer, &BufferLength);
258 break;
260 RC = UDFGetEaInformation(PtrIrpContext, Fcb, (PFILE_EA_INFORMATION) PtrSystemBuffer, &BufferLength);
261 break;
264 break;
267 break;
268// case FileCompressionInformation:
269// // RC = UDFGetCompressionInformation(...);
270// break;
273 break;
276 break;
278 // The I/O Manager supplies the Mode, Access, and Alignment
279 // information. The rest is up to us to provide.
280 // Therefore, decrement the BufferLength appropriately (assuming
281 // that the above 3 types on information are already in the
282 // buffer)
283 {
284 PFILE_ALL_INFORMATION PtrAllInfo = (PFILE_ALL_INFORMATION)PtrSystemBuffer;
285
289
290 // Get the remaining stuff.
293 !NT_SUCCESS(RC = UDFGetInternalInformation(PtrIrpContext, Fcb, Ccb, &(PtrAllInfo->InternalInformation), &BufferLength)) ||
294 !NT_SUCCESS(RC = UDFGetEaInformation(PtrIrpContext, Fcb, &(PtrAllInfo->EaInformation), &BufferLength)) ||
297 )
298 try_return(RC);
299 }
300 break;
301 default:
303 try_return(RC);
304 }
305
306#ifndef UDF_READ_ONLY_BUILD
307 } else {
308// if(IrpSp->MajorFunction == IRP_MJ_SET_INFORMATION) {
309 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
311 // Now, obtain some parameters.
312 FunctionalityRequested = IrpSp->Parameters.SetFile.FileInformationClass;
313 if((Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) &&
314 (FunctionalityRequested != FilePositionInformation)) {
316 }
317#ifdef UDF_ENABLE_SECURITY
319 Ccb->PreviouslyGrantedAccess,
320 PtrIrpContext->MajorFunction,
321 PtrIrpContext->MinorFunction,
322 0,
323 &FunctionalityRequested,
324 NULL);
325 if(!NT_SUCCESS(RC)) {
326 try_return(RC);
327 }
328#endif //UDF_ENABLE_SECURITY
329 // If the FSD supports opportunistic locking,
330 // then we should check whether the oplock state
331 // allows the caller to proceed.
332
333 // Rename, and link operations require creation of a directory
334 // entry and possibly deletion of another directory entry.
335
336 // Unless this is an operation on a page file, we should go ahead and
337 // acquire the FCB exclusively at this time. Note that we will pretty
338 // much block out anything being done to the FCB from this point on.
339 if(!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE) &&
340 (FunctionalityRequested != FilePositionInformation) &&
341 (FunctionalityRequested != FileRenameInformation) &&
342 (FunctionalityRequested != FileLinkInformation)) {
343 // Acquire the Parent & Main Resources exclusive.
344 if(Fcb->FileInfo->ParentFile) {
346 if(!UDFAcquireResourceExclusive(&(Fcb->ParentFcb->NTRequiredFCB->MainResource), CanWait)) {
347 PostRequest = TRUE;
349 }
350 ParentResourceAcquired = TRUE;
351 }
353 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
354 PostRequest = TRUE;
356 }
357 MainResourceAcquired = TRUE;
358 } else
359 // The only operations that could conceivably proceed from this point
360 // on are paging-IO read/write operations. For delete, link (rename),
361 // set allocation size, and set EOF, should also acquire the paging-IO
362 // resource, thereby synchronizing with paging-IO requests.
363 if((Fcb->FCBFlags & UDF_FCB_PAGE_FILE) &&
364 ((FunctionalityRequested == FileDispositionInformation) ||
365 (FunctionalityRequested == FileAllocationInformation) ||
366 (FunctionalityRequested == FileEndOfFileInformation)) ) {
367
368 // Acquire the MainResource shared.
370 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
371 PostRequest = TRUE;
373 }
374 MainResourceAcquired = TRUE;
375 // Acquire the PagingResource exclusive.
376 if(!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
377 PostRequest = TRUE;
379 }
380 PagingIoResourceAcquired = TRUE;
381 } else if((FunctionalityRequested != FileRenameInformation) &&
382 (FunctionalityRequested != FileLinkInformation)) {
383 // Acquire the MainResource shared.
385 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
386 PostRequest = TRUE;
388 }
389 MainResourceAcquired = TRUE;
390 }
391
392 if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
393 (FunctionalityRequested != FilePositionInformation)) {
394 AdPrint((" Can't change File Information on blank volume ;)\n"));
396 }
397
398 // Do whatever the caller asked us to do
399 switch (FunctionalityRequested) {
402 break;
404 // Check if no intermediate buffering has been specified.
405 // If it was specified, do not allow non-aligned set file
406 // position requests to succeed.
407 PFILE_POSITION_INFORMATION PtrFileInfoBuffer;
408
409 PtrFileInfoBuffer = (PFILE_POSITION_INFORMATION)PtrSystemBuffer;
410
413 // Invalid alignment.
415 }
416 }
417
418 FileObject->CurrentByteOffset = PtrFileInfoBuffer->CurrentByteOffset;
419 break;
420 }
423 ((PFILE_DISPOSITION_INFORMATION)PtrSystemBuffer)->DeleteFile ? TRUE : FALSE);
424 break;
426 if(!CanWait) {
427 PostRequest = TRUE;
429 }
430 RC = UDFRename(IrpSp, Fcb, Ccb, FileObject, (PFILE_RENAME_INFORMATION)PtrSystemBuffer);
431 if(RC == STATUS_PENDING) {
432 PostRequest = TRUE;
433 try_return(RC);
434 }
435 break;
436#ifdef UDF_ALLOW_HARD_LINKS
438 if(!CanWait) {
439 PostRequest = TRUE;
441 }
442 RC = UDFHardLink(IrpSp, Fcb, Ccb, FileObject, (PFILE_LINK_INFORMATION)PtrSystemBuffer);
443 break;
444#endif //UDF_ALLOW_HARD_LINKS
447 PtrIrpContext, Irp,
448 (PFILE_ALLOCATION_INFORMATION)PtrSystemBuffer);
449 break;
452 break;
453 default:
455 try_return(RC);
456 }
457#endif //UDF_READ_ONLY_BUILD
458 }
459
460try_exit: NOTHING;
461
462 } _SEH2_FINALLY {
463
464 if(PagingIoResourceAcquired) {
465 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
466 PagingIoResourceAcquired = FALSE;
467 }
468
469 if(MainResourceAcquired) {
471 UDFReleaseResource(&(NtReqFcb->MainResource));
472 MainResourceAcquired = FALSE;
473 }
474
475 if(ParentResourceAcquired) {
477 UDFReleaseResource(&(Fcb->ParentFcb->NTRequiredFCB->MainResource));
478 ParentResourceAcquired = FALSE;
479 }
480
481 // Post IRP if required
482 if(PostRequest) {
483
484 // Since, the I/O Manager gave us a system buffer, we do not
485 // need to "lock" anything.
486
487 // Perform the post operation which will mark the IRP pending
488 // and will return STATUS_PENDING back to us
489 RC = UDFPostRequest(PtrIrpContext, Irp);
490
491 } else {
492
494 Irp->IoStatus.Status = RC;
495 // Set status for "query" requests
497 // Return the amount of information transferred.
498 Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - BufferLength;
499#ifndef UDF_READ_ONLY_BUILD
500#ifdef UDF_DELAYED_CLOSE
501 } else
502 if(NT_SUCCESS(RC)) {
503 if(FunctionalityRequested == FileDispositionInformation) {
504 if(AcquiredVcb) {
505 AcquiredVcb = FALSE;
506 UDFReleaseResource(&(Vcb->VCBResource));
507 }
509 }
510#endif //UDF_DELAYED_CLOSE
511#endif //UDF_READ_ONLY_BUILD
512 }
513 // complete the IRP
515 // Free up the Irp Context
516 UDFReleaseIrpContext(PtrIrpContext);
517 } // can we complete the IRP ?
518
519 }
520 if(AcquiredVcb) {
521 UDFReleaseResource(&(Vcb->VCBResource));
522 }
523 } _SEH2_END;// end of "__finally" processing
524
525 return(RC);
526} // end UDFCommonFileInfo()
NTSTATUS UDFGetFileStreamInformation(IN PtrUDFFCB Fcb, IN PFILE_STREAM_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:930
NTSTATUS UDFGetEaInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PFILE_EA_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:801
NTSTATUS UDFSetBasicInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_OBJECT FileObject, IN PFILE_BASIC_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1013
NTSTATUS UDFGetInternalInformation(PtrUDFIrpContext PtrIrpContext, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PFILE_INTERNAL_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:747
NTSTATUS UDFSetAllocationInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PFILE_ALLOCATION_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1454
NTSTATUS UDFSetEOF(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PIRP Irp, IN PFILE_END_OF_FILE_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1627
NTSTATUS UDFGetBasicInformation(IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PFILE_BASIC_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:532
NTSTATUS UDFGetFullNameInformation(IN PFILE_OBJECT FileObject, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:836
NTSTATUS UDFGetNetworkInformation(IN PtrUDFFCB Fcb, IN PFILE_NETWORK_OPEN_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:676
NTSTATUS UDFGetStandardInformation(IN PtrUDFFCB Fcb, IN PFILE_STANDARD_INFORMATION PtrBuffer, IN OUT LONG *PtrReturnedLength)
Definition: fileinfo.cpp:614
NTSTATUS UDFRename(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb1, IN PtrUDFCCB Ccb1, IN PFILE_OBJECT FileObject1, IN PFILE_RENAME_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:1961
NTSTATUS UDFGetPositionInformation(IN PFILE_OBJECT FileObject, IN PFILE_POSITION_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:910
NTSTATUS UDFSetDispositionInformation(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN BOOLEAN Delete)
Definition: fileinfo.cpp:1340
NTSTATUS UDFHardLink(IN PIO_STACK_LOCATION PtrSp, IN PtrUDFFCB Fcb1, IN PtrUDFCCB Ccb1, IN PFILE_OBJECT FileObject1, IN PFILE_LINK_INFORMATION PtrBuffer)
Definition: fileinfo.cpp:2494
NTSTATUS UDFGetAltNameInformation(IN PtrUDFFCB Fcb, IN PFILE_NAME_INFORMATION PtrBuffer, IN OUT PLONG PtrReturnedLength)
Definition: fileinfo.cpp:869
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllInformation
Definition: from_kernel.h:79
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileEaInformation
Definition: from_kernel.h:68
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileStreamInformation
Definition: from_kernel.h:83
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
#define FSRTL_FSP_TOP_LEVEL_IRP
Definition: fsrtltypes.h:59
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP
Definition: fsrtltypes.h:61
#define FSRTL_FAST_IO_TOP_LEVEL_IRP
Definition: fsrtltypes.h:62
GLdouble n
Definition: glext.h:7729
struct _FILE_MODE_INFORMATION FILE_MODE_INFORMATION
struct _FILE_ALL_INFORMATION * PFILE_ALL_INFORMATION
struct _FILE_ALIGNMENT_INFORMATION FILE_ALIGNMENT_INFORMATION
struct _FILE_POSITION_INFORMATION * PFILE_POSITION_INFORMATION
NTSTATUS NTAPI IoCheckFunctionAccess(IN ACCESS_MASK GrantedAccess, IN UCHAR MajorFunction, IN UCHAR MinorFunction, IN ULONG IoControlCode, IN PVOID ExtraData OPTIONAL, IN PVOID ExtraData2 OPTIONAL)
Definition: util.c:276
#define STATUS_PENDING
Definition: ntstatus.h:82
#define FileStandardInformation
Definition: propsheet.cpp:61
#define IRP_MJ_SET_INFORMATION
Definition: rdpdr.c:49
#define IRP_MJ_QUERY_INFORMATION
Definition: rdpdr.c:48
#define UDF_FCB_PAGE_FILE
Definition: struct.h:302
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
FILE_STANDARD_INFORMATION StandardInformation
Definition: winternl.h:797
FILE_EA_INFORMATION EaInformation
Definition: winternl.h:799
FILE_INTERNAL_INFORMATION InternalInformation
Definition: winternl.h:798
FILE_NAME_INFORMATION NameInformation
Definition: winternl.h:804
FILE_POSITION_INFORMATION PositionInformation
Definition: winternl.h:801
FILE_BASIC_INFORMATION BasicInformation
Definition: winternl.h:796
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:955
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
#define UDF_VCB_SKIP_EJECT_CHECK
Definition: udf_common.h:470
ULONG LowPart
Definition: typedefs.h:106
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771
#define DeleteFile
Definition: winbase.h:3699
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1778

Referenced by UDFCommonDispatch(), and UDFFileInfo().

◆ UDFCommonFlush()

NTSTATUS UDFCommonFlush ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 110 of file flush.cpp.

114{
120 PVCB Vcb = NULL;
122 BOOLEAN AcquiredVCB = FALSE;
123 BOOLEAN AcquiredFCB = FALSE;
124 BOOLEAN PostRequest = FALSE;
125 BOOLEAN CanWait = TRUE;
126
127 UDFPrint(("UDFCommonFlush: \n"));
128
129 _SEH2_TRY {
130
131 // Get some of the parameters supplied to us
132 CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
133 // If we cannot wait, post the request immediately since a flush is inherently blocking/synchronous.
134 if (!CanWait) {
135 PostRequest = TRUE;
136 try_return(RC);
137 }
138
139 // First, get a pointer to the current I/O stack location
141 ASSERT(IrpSp);
142
145
146 // Get the FCB and CCB pointers
147 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
148 ASSERT(Ccb);
149 Fcb = Ccb->Fcb;
150 ASSERT(Fcb);
151 NtReqFcb = Fcb->NTRequiredFCB;
152
153 // Check the type of object passed-in. That will determine the course of
154 // action we take.
155 if ((Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) || (Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)) {
156
157 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
158 Vcb = (PVCB)(Fcb);
159 } else {
160 Vcb = Fcb->Vcb;
161 }
162 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
163
164#ifdef UDF_DELAYED_CLOSE
166#endif //UDF_DELAYED_CLOSE
167
168 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
169 AcquiredVCB = TRUE;
170 // The caller wishes to flush all files for the mounted
171 // logical volume. The flush volume routine below should simply
172 // walk through all of the open file streams, acquire the
173 // VCB resource, and request the flush operation from the Cache
174 // Manager. Basically, the sequence of operations listed below
175 // for a single file should be executed on all open files.
176
177 UDFFlushLogicalVolume(PtrIrpContext, Irp, Vcb, 0);
178
179 UDFReleaseResource(&(Vcb->VCBResource));
180 AcquiredVCB = FALSE;
181
182 try_return(RC);
183 } else
184 if (!(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
185 // This is a regular file.
186 Vcb = Fcb->Vcb;
187 ASSERT(Vcb);
188 if(!ExIsResourceAcquiredExclusiveLite(&(Vcb->VCBResource)) &&
189 !ExIsResourceAcquiredSharedLite(&(Vcb->VCBResource))) {
190 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
191 AcquiredVCB = TRUE;
192 }
194 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), TRUE);
195 AcquiredFCB = TRUE;
196
197 // Request the Cache Manager to perform a flush operation.
198 // Further, instruct the Cache Manager that we wish to flush the
199 // entire file stream.
200 UDFFlushAFile(Fcb, Ccb, &(Irp->IoStatus), 0);
201 RC = Irp->IoStatus.Status;
202
203 // Some log-based FSD implementations may wish to flush their
204 // log files at this time. Finally, we should update the time-stamp
205 // values for the file stream appropriately. This would involve
206 // obtaining the current time and modifying the appropriate directory
207 // entry fields.
208 } else {
209 Vcb = Fcb->Vcb;
210 }
211
212try_exit: NOTHING;
213
214 } _SEH2_FINALLY {
215
216 if (AcquiredFCB) {
218 UDFReleaseResource(&(NtReqFcb->MainResource));
219 AcquiredFCB = FALSE;
220 }
221 if (AcquiredVCB) {
222 UDFReleaseResource(&(Vcb->VCBResource));
223 AcquiredVCB = FALSE;
224 }
225
227 if (PostRequest) {
228 // Nothing to lock now.
229 BrutePoint();
230 RC = UDFPostRequest(PtrIrpContext, Irp);
231 } else {
232 // Some applications like this request very much
233 // (ex. WinWord). But it's not a good idea for CD-R/RW media
234 if(Vcb->FlushMedia) {
235 PIO_STACK_LOCATION PtrNextIoStackLocation = NULL;
237
238 // Send the request down at this point.
239 // To do this, we must set the next IRP stack location, and
240 // maybe set a completion routine.
241 // Be careful about marking the IRP pending if the lower level
242 // driver returned pending and we do have a completion routine!
243 PtrNextIoStackLocation = IoGetNextIrpStackLocation(Irp);
244 *PtrNextIoStackLocation = *IrpSp;
245
246 // Set the completion routine to "eat-up" any
247 // STATUS_INVALID_DEVICE_REQUEST error code returned by the lower
248 // level driver.
250
251 RC1 = IoCallDriver(Vcb->TargetDeviceObject, Irp);
252
253 RC = ((RC1 == STATUS_INVALID_DEVICE_REQUEST) ? RC : RC1);
254
255 // Release the IRP context at this time.
256 UDFReleaseIrpContext(PtrIrpContext);
257 } else {
258 Irp->IoStatus.Status = RC;
259 Irp->IoStatus.Information = 0;
260 // Free up the Irp Context
261 UDFReleaseIrpContext(PtrIrpContext);
262 // complete the IRP
264 }
265 }
266 }
267 } _SEH2_END;
268
269 return(RC);
270} // end UDFCommonFlush()
NTSTATUS NTAPI UDFFlushCompletion(PDEVICE_OBJECT PtrDeviceObject, PIRP Irp, PVOID Context)
Definition: flush.cpp:578
ULONG UDFFlushAFile(IN PtrUDFFCB Fcb, IN PtrUDFCCB Ccb, OUT PIO_STATUS_BLOCK PtrIoStatus, IN ULONG FlushFlags)
Definition: flush.cpp:288
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695

Referenced by UDFFlush().

◆ UDFCommonFSControl()

NTSTATUS NTAPI UDFCommonFSControl ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 103 of file fscntrl.cpp.

107{
110// PDEVICE_OBJECT PtrTargetDeviceObject = NULL;
111
112 UDFPrint(("\nUDFCommonFSControl\n\n"));
113// BrutePoint();
114
115 _SEH2_TRY {
116
118 ASSERT(IrpSp);
119
120 switch ((IrpSp)->MinorFunction)
121 {
123 UDFPrint((" UDFFSControl: UserFsReq request ....\n"));
124
125 RC = UDFUserFsCtrlRequest(PtrIrpContext,Irp);
126 break;
128
129 UDFPrint((" UDFFSControl: MOUNT_VOLUME request ....\n"));
130
131 RC = UDFMountVolume(PtrIrpContext,Irp);
132 break;
134
135 UDFPrint((" UDFFSControl: VERIFY_VOLUME request ....\n"));
136
137 RC = UDFVerifyVolume(Irp);
138 break;
139 default:
140 UDFPrintErr((" UDFFSControl: STATUS_INVALID_DEVICE_REQUEST MinorFunction %x\n", (IrpSp)->MinorFunction));
142
143 Irp->IoStatus.Status = RC;
144 Irp->IoStatus.Information = 0;
145 // complete the IRP
147 break;
148 }
149
150//try_exit: NOTHING;
151 } _SEH2_FINALLY {
153 // Free up the Irp Context
154 UDFPrint((" UDFCommonFSControl: finally\n"));
155 UDFReleaseIrpContext(PtrIrpContext);
156 } else {
157 UDFPrint((" UDFCommonFSControl: finally after exception ***\n"));
158 }
159 } _SEH2_END;
160
161 return(RC);
162} // end UDFCommonFSControl()
NTSTATUS NTAPI UDFUserFsCtrlRequest(PtrUDFIrpContext IrpContext, PIRP Irp)
Definition: fscntrl.cpp:178
NTSTATUS NTAPI UDFMountVolume(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:315
NTSTATUS UDFVerifyVolume(IN PIRP Irp)
Definition: verfysup.cpp:158
#define STATUS_UNRECOGNIZED_VOLUME
Definition: udferr_usr.h:173
#define UDFPrintErr(Args)
Definition: udffs.h:229
_In_ UCHAR _In_ UCHAR MinorFunction
Definition: wdfdevice.h:1699
#define IRP_MN_VERIFY_VOLUME
Definition: iotypes.h:4405
#define IRP_MN_USER_FS_REQUEST
Definition: iotypes.h:4403
#define IRP_MN_MOUNT_VOLUME
Definition: iotypes.h:4404

Referenced by UDFFSControl().

◆ UDFCommonGetSecurity()

NTSTATUS UDFCommonGetSecurity ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Referenced by UDFCommonDispatch().

◆ UDFCommonLockControl()

NTSTATUS NTAPI UDFCommonLockControl ( IN PtrUDFIrpContext  PtrIrpContext,
IN PIRP  Irp 
)

Definition at line 105 of file lockctrl.cpp.

108{
111 //IO_STATUS_BLOCK LocalIoStatus;
112// BOOLEAN CompleteRequest = FALSE;
113 BOOLEAN PostRequest = FALSE;
114 BOOLEAN CanWait = FALSE;
116 BOOLEAN AcquiredFCB = FALSE;
120
121 UDFPrint(("UDFCommonLockControl\n"));
122
123 _SEH2_TRY {
124 // First, get a pointer to the current I/O stack location.
126 ASSERT(IrpSp);
127
130
131 // Get the FCB and CCB pointers.
132 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
133 ASSERT(Ccb);
134 Fcb = Ccb->Fcb;
135 ASSERT(Fcb);
136 // Validate the sent-in FCB
137 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
138 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
139
140// CompleteRequest = TRUE;
142 }
143
144 NtReqFcb = Fcb->NTRequiredFCB;
145 CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
146
147 // Acquire the FCB resource shared
149 if (!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
150 PostRequest = TRUE;
152 }
153 AcquiredFCB = TRUE;
154
155 RC = FsRtlProcessFileLock(&(NtReqFcb->FileLock), Irp, NULL);
156// CompleteRequest = TRUE;
157
158try_exit: NOTHING;
159
160 } _SEH2_FINALLY {
161
162 // Release the FCB resources if acquired.
163 if (AcquiredFCB) {
165 UDFReleaseResource(&(NtReqFcb->MainResource));
166 AcquiredFCB = FALSE;
167 }
168 if (PostRequest) {
169 // Perform appropriate post related processing here
170 RC = UDFPostRequest(PtrIrpContext, Irp);
171 } else
173 // Simply free up the IrpContext since the IRP has been queued or
174 // Completed by FsRtlProcessFileLock
175 UDFReleaseIrpContext(PtrIrpContext);
176 }
177 } _SEH2_END; // end of "__finally" processing
178
179 return(RC);
180} // end UDFCommonLockControl()
NTSTATUS NTAPI FsRtlProcessFileLock(IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
Definition: filelock.c:1152

Referenced by UDFLockControl().

◆ UDFCommonQueryVolInfo()

NTSTATUS UDFCommonQueryVolInfo ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 149 of file volinfo.cpp.

153{
157 BOOLEAN CanWait = FALSE;
158 PVCB Vcb;
159 BOOLEAN PostRequest = FALSE;
160 BOOLEAN AcquiredVCB = FALSE;
162// PtrUDFFCB Fcb = NULL;
164
165 _SEH2_TRY {
166
167 UDFPrint(("UDFCommonQueryVolInfo: \n"));
168
169 ASSERT(PtrIrpContext);
170 ASSERT(Irp);
171
172 PAGED_CODE();
173
176
177 // Get the FCB and CCB pointers.
178 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
179 ASSERT(Ccb);
180
182 ASSERT(Vcb);
183 //Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
184 // Reference our input parameters to make things easier
185 Length = IrpSp->Parameters.QueryVolume.Length;
186 // Acquire the Vcb for this volume.
187 CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
188#ifdef UDF_ENABLE_SECURITY
190 Ccb->PreviouslyGrantedAccess,
191 PtrIrpContext->MajorFunction,
192 PtrIrpContext->MinorFunction,
193 0,
194 NULL,
195 &(IrpSp->Parameters.QueryVolume.FsInformationClass));
196 if(!NT_SUCCESS(RC)) {
197 try_return(RC);
198 }
199#endif //UDF_ENABLE_SECURITY
200
201 RtlZeroMemory(Irp->AssociatedIrp.SystemBuffer, Length);
202
203 switch (IrpSp->Parameters.QueryVolume.FsInformationClass) {
204
206
207 // This is the only routine we need the Vcb shared because of
208 // copying the volume label. All other routines copy fields that
209 // cannot change or are just manifest constants.
211 if (!UDFAcquireResourceShared(&(Vcb->VCBResource), CanWait)) {
212 PostRequest = TRUE;
214 }
215 AcquiredVCB = TRUE;
216
217 RC = UDFQueryFsVolumeInfo( PtrIrpContext, Vcb, (PFILE_FS_VOLUME_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
218 break;
219
221
222 RC = UDFQueryFsSizeInfo( PtrIrpContext, Vcb, (PFILE_FS_SIZE_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
223 break;
224
226
227 RC = UDFQueryFsDeviceInfo( PtrIrpContext, Vcb, (PFILE_FS_DEVICE_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
228 break;
229
231
232 RC = UDFQueryFsAttributeInfo( PtrIrpContext, Vcb, (PFILE_FS_ATTRIBUTE_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
233 break;
234
236
237 RC = UDFQueryFsFullSizeInfo( PtrIrpContext, Vcb, (PFILE_FS_FULL_SIZE_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
238 break;
239
240 default:
241
243 Irp->IoStatus.Information = 0;
244 break;
245
246 }
247
248 // Set the information field to the number of bytes actually filled in
249 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
250
251try_exit: NOTHING;
252
253 } _SEH2_FINALLY {
254
255 if (AcquiredVCB) {
256 UDFReleaseResource(&(Vcb->VCBResource));
257 AcquiredVCB = FALSE;
258 }
259
260 // Post IRP if required
261 if (PostRequest) {
262
263 // Since, the I/O Manager gave us a system buffer, we do not
264 // need to "lock" anything.
265
266 // Perform the post operation which will mark the IRP pending
267 // and will return STATUS_PENDING back to us
268 RC = UDFPostRequest(PtrIrpContext, Irp);
269
270 } else
272
273 Irp->IoStatus.Status = RC;
274 // Free up the Irp Context
275 UDFReleaseIrpContext(PtrIrpContext);
276 // complete the IRP
278 } // can we complete the IRP ?
279
280 } _SEH2_END;
281
282 return RC;
283} // end UDFCommonQueryVolInfo()
#define PAGED_CODE()
@ FileFsDeviceInformation
Definition: from_kernel.h:222
@ FileFsAttributeInformation
Definition: from_kernel.h:223
@ FileFsVolumeInformation
Definition: from_kernel.h:219
@ FileFsSizeInformation
Definition: from_kernel.h:221
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define FileFsFullSizeInformation
Definition: ntifs_ex.h:389
NTSTATUS UDFQueryFsFullSizeInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_FULL_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:404
NTSTATUS UDFQueryFsDeviceInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_DEVICE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:457
NTSTATUS UDFQueryFsVolumeInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_VOLUME_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:300
NTSTATUS UDFQueryFsSizeInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_SIZE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:352
NTSTATUS UDFQueryFsAttributeInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:496

Referenced by UDFCommonDispatch(), and UDFQueryVolInfo().

◆ UDFCommonRead()

NTSTATUS UDFCommonRead ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 229 of file read.cpp.

233{
237 ULONG ReadLength = 0, TruncatedLength = 0;
238 SIZE_T NumberBytesRead = 0;
242 PVCB Vcb = NULL;
244 PERESOURCE PtrResourceAcquired = NULL;
245 PERESOURCE PtrResourceAcquired2 = NULL;
246 PVOID SystemBuffer = NULL;
247 PIRP TopIrp;
248// uint32 KeyValue = 0;
249
250 ULONG Res1Acq = 0;
251 ULONG Res2Acq = 0;
252
253 BOOLEAN CacheLocked = FALSE;
254
255 BOOLEAN CanWait = FALSE;
256 BOOLEAN PagingIo = FALSE;
257 BOOLEAN NonBufferedIo = FALSE;
258 BOOLEAN SynchronousIo = FALSE;
259
260 TmPrint(("UDFCommonRead: irp %x\n", Irp));
261
262 _SEH2_TRY {
263
264 TopIrp = IoGetTopLevelIrp();
265 switch((ULONG_PTR)TopIrp) {
267 UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
268 break;
270 UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
271 break;
273 UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
274// BrutePoint()
275 break;
277 UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
278// BrutePoint()
279 break;
280 case NULL:
281 UDFPrint((" NULL TOP_LEVEL_IRP\n"));
282 break;
283 default:
284 if(TopIrp == Irp) {
285 UDFPrint((" TOP_LEVEL_IRP\n"));
286 } else {
287 UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
288 }
289 break;
290 }
291 // First, get a pointer to the current I/O stack location
293 ASSERT(IrpSp);
294 MmPrint((" Enter Irp, MDL=%x\n", Irp->MdlAddress));
295 if(Irp->MdlAddress) {
296 UDFTouch(Irp->MdlAddress);
297 }
298
299 // If this happens to be a MDL read complete request, then
300 // there is not much processing that the FSD has to do.
302 // Caller wants to tell the Cache Manager that a previously
303 // allocated MDL can be freed.
304 UDFMdlComplete(PtrIrpContext, Irp, IrpSp, TRUE);
305 // The IRP has been completed.
307 }
308
309 // If this is a request at IRQL DISPATCH_LEVEL, then post
310 // the request (your FSD may choose to process it synchronously
311 // if you implement the support correctly; obviously you will be
312 // quite constrained in what you can do at such IRQL).
315 }
316
319
320 // Get the FCB and CCB pointers
321 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
322 ASSERT(Ccb);
323 Fcb = Ccb->Fcb;
324 ASSERT(Fcb);
325 Vcb = Fcb->Vcb;
326
327 if(Fcb->FCBFlags & UDF_FCB_DELETED) {
328 ASSERT(FALSE);
330 }
331
332 // check for stack overflow
333 if (IoGetRemainingStackSize() < OVERFLOW_READ_THRESHHOLD) {
334 RC = UDFPostStackOverflowRead( PtrIrpContext, Irp, Fcb );
335 try_return(RC);
336 }
337
338 // Disk based file systems might decide to verify the logical volume
339 // (if required and only if removable media are supported) at this time
340 // As soon as Tray is locked, we needn't call UDFVerifyVcb()
341
342 ByteOffset = IrpSp->Parameters.Read.ByteOffset;
343
344 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
345 PagingIo = (Irp->Flags & IRP_PAGING_IO) ? TRUE : FALSE;
346 NonBufferedIo = (Irp->Flags & IRP_NOCACHE) ? TRUE : FALSE;
347 SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO) ? TRUE : FALSE;
348 UDFPrint((" Flags: %s %s %s %s\n",
349 CanWait ? "W" : "w", PagingIo ? "Pg" : "pg",
350 NonBufferedIo ? "NBuf" : "buff", SynchronousIo ? "Snc" : "Asc"));
351
352 if(!NonBufferedIo &&
353 (Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB)) {
354 if(UDFIsAStream(Fcb->FileInfo)) {
358 } else {
362 }
363 }
364
365 // Get some of the parameters supplied to us
366 ReadLength = IrpSp->Parameters.Read.Length;
367 if (ReadLength == 0) {
368 // a 0 byte read can be immediately succeeded
369 try_return(RC);
370 }
371 UDFPrint((" ByteOffset = %I64x, ReadLength = %x\n", ByteOffset.QuadPart, ReadLength));
372
373 // Is this a read of the volume itself ?
374 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
375 // Yup, we need to send this on to the disk driver after
376 // validation of the offset and length.
377 Vcb = (PVCB)Fcb;
378 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
379 if(!CanWait)
381
382
384
385 UDFPrint((" UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
386 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH2_REQUIRED;
387
388 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
389 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
390 }
391#ifdef UDF_DELAYED_CLOSE
393#endif //UDF_DELAYED_CLOSE
394
395 }
396
398
399 UDFPrint((" UDF_IRP_CONTEXT_FLUSH_REQUIRED\n"));
400 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH_REQUIRED;
401
402 // Acquire the volume resource exclusive
403 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
404 PtrResourceAcquired = &(Vcb->VCBResource);
405
407
408 UDFReleaseResource(PtrResourceAcquired);
409 PtrResourceAcquired = NULL;
410 }
411
412 // Acquire the volume resource shared ...
413 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
414 PtrResourceAcquired = &(Vcb->VCBResource);
415
416#if 0
417 if(PagingIo) {
418 CollectStatistics(Vcb, MetaDataReads);
419 CollectStatisticsEx(Vcb, MetaDataReadBytes, NumberBytesRead);
420 }
421#endif
422
423 // Forward the request to the lower level driver
424 // Lock the callers buffer
425 if (!NT_SUCCESS(RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength))) {
426 try_return(RC);
427 }
428 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
429 if(!SystemBuffer) {
431 }
432 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) {
433 RC = UDFReadData(Vcb, TRUE, ByteOffset.QuadPart,
434 ReadLength, FALSE, (PCHAR)SystemBuffer,
435 &NumberBytesRead);
436 } else {
437 RC = UDFTRead(Vcb, SystemBuffer, ReadLength,
438 (ULONG)(ByteOffset.QuadPart >> Vcb->BlockSizeBits),
439 &NumberBytesRead);
440 }
441 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
442 try_return(RC);
443 }
444 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
445
446 // If the read request is directed to a page file (if your FSD
447 // supports paging files), send the request directly to the disk
448 // driver. For requests directed to a page file, you have to trust
449 // that the offsets will be set correctly by the VMM. You should not
450 // attempt to acquire any FSD resources either.
451 if(Fcb->FCBFlags & UDF_FCB_PAGE_FILE) {
452 NonBufferedIo = TRUE;
453 }
454
455 if(ByteOffset.HighPart == -1) {
457 ByteOffset = FileObject->CurrentByteOffset;
458 }
459 }
460
461 // If this read is directed to a directory, it is not allowed
462 // by the UDF FSD.
463 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
465 try_return(RC);
466 }
467
468 NtReqFcb = Fcb->NTRequiredFCB;
469
470 Res1Acq = UDFIsResourceAcquired(&(NtReqFcb->MainResource));
471 if(!Res1Acq) {
472 Res1Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES1_ACQ;
473 }
474 Res2Acq = UDFIsResourceAcquired(&(NtReqFcb->PagingIoResource));
475 if(!Res2Acq) {
476 Res2Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES2_ACQ;
477 }
478
479#if 0
480 if(PagingIo) {
481 CollectStatistics(Vcb, UserFileReads);
482 CollectStatisticsEx(Vcb, UserFileReadBytes, NumberBytesRead);
483 }
484#endif
485
486 // This is a good place for oplock related processing.
487
488 // If this is the normal file we have to check for
489 // write access according to the current state of the file locks.
490 if (!PagingIo &&
491 !FsRtlCheckLockForReadAccess( &(NtReqFcb->FileLock), Irp )) {
493 }
494
495 // Validate start offset and length supplied.
496 // If start offset is > end-of-file, return an appropriate error. Note
497 // that since a FCB resource has already been acquired, and since all
498 // file size changes require acquisition of both FCB resources,
499 // the contents of the FCB and associated data structures
500 // can safely be examined.
501
502 // Also note that we are using the file size in the "Common FCB Header"
503 // to perform the check. However, your FSD might decide to keep a
504 // separate copy in the FCB (or some other representation of the
505 // file associated with the FCB).
506
507 TruncatedLength = ReadLength;
508 if (ByteOffset.QuadPart >= NtReqFcb->CommonFCBHeader.FileSize.QuadPart) {
509 // Starting offset is >= file size
511 }
512 // We can also go ahead and truncate the read length here
513 // such that it is contained within the file size
514 if( NtReqFcb->CommonFCBHeader.FileSize.QuadPart < (ByteOffset.QuadPart + ReadLength) ) {
515 TruncatedLength = (ULONG)(NtReqFcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
516 // we can't get ZERO here
517 }
518 UDFPrint((" TruncatedLength = %x\n", TruncatedLength));
519
520 // There are certain complications that arise when the same file stream
521 // has been opened for cached and non-cached access. The FSD is then
522 // responsible for maintaining a consistent view of the data seen by
523 // the caller.
524 // Also, it is possible for file streams to be mapped in both as data files
525 // and as an executable. This could also lead to consistency problems since
526 // there now exist two separate sections (and pages) containing file
527 // information.
528
529 // The test below flushes the data cached in system memory if the current
530 // request madates non-cached access (file stream must be cached) and
531 // (a) the current request is not paging-io which indicates it is not
532 // a recursive I/O operation OR originating in the Cache Manager
533 // (b) OR the current request is paging-io BUT it did not originate via
534 // the Cache Manager (or is a recursive I/O operation) and we do
535 // have an image section that has been initialized.
536#define UDF_REQ_NOT_VIA_CACHE_MGR(ptr) (!MmIsRecursiveIoFault() && ((ptr)->ImageSectionObject != NULL))
537
538 if(NonBufferedIo &&
539 (NtReqFcb->SectionObject.DataSectionObject != NULL)) {
540 if(!PagingIo) {
541
542/* // We hold the main resource exclusive here because the flush
543 // may generate a recursive write in this thread. The PagingIo
544 // resource is held shared so the drop-and-release serialization
545 // below will work.
546 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
547 try_return(RC = STATUS_PENDING);
548 }
549 PtrResourceAcquired = &(NtReqFcb->MainResource);
550
551 // We hold PagingIo shared around the flush to fix a
552 // cache coherency problem.
553 UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), TRUE );*/
554
555 MmPrint((" CcFlushCache()\n"));
556 CcFlushCache(&(NtReqFcb->SectionObject), &ByteOffset, TruncatedLength, &(Irp->IoStatus));
557
558/* UDFReleaseResource(&(NtReqFcb->PagingIoResource));
559 UDFReleaseResource(PtrResourceAcquired);
560 PtrResourceAcquired = NULL;
561 // If the flush failed, return error to the caller
562 if(!NT_SUCCESS(RC = Irp->IoStatus.Status)) {
563 try_return(RC);
564 }
565
566 // Acquiring and immediately dropping the resource serializes
567 // us behind any other writes taking place (either from the
568 // lazy writer or modified page writer).*/
569 if(!Res2Acq) {
570 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE );
571 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
572 }
573 }
574 }
575
576 // Acquire the appropriate FCB resource shared
577 if (PagingIo) {
578 // Try to acquire the FCB PagingIoResource shared
579 if(!Res2Acq) {
580 if (!UDFAcquireResourceShared(&(NtReqFcb->PagingIoResource), CanWait)) {
582 }
583 // Remember the resource that was acquired
584 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
585 }
586 } else {
587 // Try to acquire the FCB MainResource shared
588 if(NonBufferedIo) {
589 if(!Res2Acq) {
590 if(!UDFAcquireSharedWaitForExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
592 }
593 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
594 }
595 } else {
596 if(!Res1Acq) {
598 if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
600 }
601 // Remember the resource that was acquired
602 PtrResourceAcquired = &(NtReqFcb->MainResource);
603 }
604 }
605 }
606
607 // This is also a good place to set whether fast-io can be performed
608 // on this particular file or not. Your FSD must make it's own
609 // determination on whether or not to allow fast-io operations.
610 // Commonly, fast-io is not allowed if any byte range locks exist
611 // on the file or if oplocks prevent fast-io. Practically any reason
612 // choosen by your FSD could result in your setting FastIoIsNotPossible
613 // OR FastIoIsQuestionable instead of FastIoIsPossible.
614
615 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
616/* if(NtReqFcb->CommonFCBHeader.IsFastIoPossible == FastIoIsPossible)
617 NtReqFcb->CommonFCBHeader.IsFastIoPossible = FastIoIsQuestionable;*/
618
619#ifdef UDF_DISABLE_SYSTEM_CACHE_MANAGER
620 NonBufferedIo = TRUE;
621#endif
622
623 if(Fcb && Fcb->FileInfo && Fcb->FileInfo->Dloc) {
624 AdPrint(("UDFCommonRead: DataLoc %x, Mapping %x\n", &Fcb->FileInfo->Dloc->DataLoc, Fcb->FileInfo->Dloc->DataLoc.Mapping));
625 }
626
627 // Branch here for cached vs non-cached I/O
628 if (!NonBufferedIo) {
629
630 if(FileObject->Flags & FO_WRITE_THROUGH) {
631 CanWait = TRUE;
632 }
633 // The caller wishes to perform cached I/O. Initiate caching if
634 // this is the first cached I/O operation using this file object
635 if (!(FileObject->PrivateCacheMap)) {
636 // This is the first cached I/O operation. You must ensure
637 // that the FCB Common FCB Header contains valid sizes at this time
638 MmPrint((" CcInitializeCacheMap()\n"));
639 CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&(NtReqFcb->CommonFCBHeader.AllocationSize)),
640 FALSE, // We will not utilize pin access for this file
641 &(UDFGlobalData.CacheMgrCallBacks), // callbacks
642 NtReqFcb); // The context used in callbacks
643 MmPrint((" CcSetReadAheadGranularity()\n"));
644 CcSetReadAheadGranularity(FileObject, Vcb->SystemCacheGran);
645 }
646
647 // Check and see if this request requires a MDL returned to the caller
649 // Caller does want a MDL returned. Note that this mode
650 // implies that the caller is prepared to block
651 MmPrint((" CcMdlRead()\n"));
652// CcMdlRead(FileObject, &ByteOffset, TruncatedLength, &(Irp->MdlAddress), &(Irp->IoStatus));
653// NumberBytesRead = Irp->IoStatus.Information;
654// RC = Irp->IoStatus.Status;
655 NumberBytesRead = 0;
657
658 try_return(RC);
659 }
660
661 // This is a regular run-of-the-mill cached I/O request. Let the
662 // Cache Manager worry about it!
663 // First though, we need a buffer pointer (address) that is valid
664 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
665 if(!SystemBuffer)
667 ASSERT(SystemBuffer);
668 MmPrint((" CcCopyRead()\n"));
669 if (!CcCopyRead(FileObject, &(ByteOffset), TruncatedLength, CanWait, SystemBuffer, &(Irp->IoStatus))) {
670 // The caller was not prepared to block and data is not immediately
671 // available in the system cache
673 }
674
675 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
676 // We have the data
677 RC = Irp->IoStatus.Status;
678 NumberBytesRead = Irp->IoStatus.Information;
679
680 try_return(RC);
681
682 } else {
683
684 MmPrint((" Read NonBufferedIo\n"));
685
686#if 1
688 UDFPrint(("FSRTL_MOD_WRITE_TOP_LEVEL_IRP => CanWait\n"));
689 CanWait = TRUE;
690 } else
691 if((ULONG_PTR)TopIrp == FSRTL_CACHE_TOP_LEVEL_IRP) {
692 UDFPrint(("FSRTL_CACHE_TOP_LEVEL_IRP => CanWait\n"));
693 CanWait = TRUE;
694 }
695
696 if(NtReqFcb->AcqSectionCount || NtReqFcb->AcqFlushCount) {
697 MmPrint((" AcqCount (%d/%d)=> CanWait ?\n", NtReqFcb->AcqSectionCount, NtReqFcb->AcqFlushCount));
698 CanWait = TRUE;
699 } else
700 {}
701/* if((TopIrp != Irp)) {
702 UDFPrint(("(TopIrp != Irp) => CanWait\n"));
703 CanWait = TRUE;
704 } else*/
705#endif
707 MmPrint((" !PASSIVE_LEVEL\n"));
708 CanWait = FALSE;
710 }
711 if(!CanWait && UDFIsFileCached__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength, FALSE)) {
712 MmPrint((" Locked => CanWait\n"));
713 CacheLocked = TRUE;
714 CanWait = TRUE;
715 }
716
717 // Send the request to lower level drivers
718 if(!CanWait) {
720 }
721
722// ASSERT(NT_SUCCESS(RC));
723 if(!Res2Acq) {
724 if(UDFAcquireResourceSharedWithCheck(&(NtReqFcb->PagingIoResource)))
725 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
726 }
727
728 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, TruncatedLength);
729 if(!NT_SUCCESS(RC)) {
730 try_return(RC);
731 }
732
733 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
734 if(!SystemBuffer) {
736 }
737
738 RC = UDFReadFile__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength,
739 CacheLocked, (PCHAR)SystemBuffer, &NumberBytesRead);
740/* // AFAIU, CacheManager wants this:
741 if(!NT_SUCCESS(RC)) {
742 NumberBytesRead = 0;
743 }*/
744
745 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
746
747#if 0
748 if(PagingIo) {
749 CollectStatistics(Vcb, UserDiskReads);
750 } else {
751 CollectStatistics2(Vcb, NonCachedDiskReads);
752 }
753#endif
754
755 try_return(RC);
756
757 // For paging-io, the FSD has to trust the VMM to do the right thing
758
759 // Here is a common method used by Windows NT native file systems
760 // that are in the process of sending a request to the disk driver.
761 // First, mark the IRP as pending, then invoke the lower level driver
762 // after setting a completion routine.
763 // Meanwhile, this particular thread can immediately return a
764 // STATUS_PENDING return code.
765 // The completion routine is then responsible for completing the IRP
766 // and unlocking appropriate resources
767
768 // Also, at this point, the FSD might choose to utilize the
769 // information contained in the ValidDataLength field to simply
770 // return zeroes to the caller for reads extending beyond current
771 // valid data length.
772
773 }
774
775try_exit: NOTHING;
776
777 } _SEH2_FINALLY {
778
779 if(CacheLocked) {
780 WCacheEODirect__(&(Vcb->FastCache), Vcb);
781 }
782
783 // Release any resources acquired here ...
784 if(PtrResourceAcquired2) {
785 UDFReleaseResource(PtrResourceAcquired2);
786 }
787 if(PtrResourceAcquired) {
788 if(NtReqFcb &&
789 (PtrResourceAcquired ==
790 &(NtReqFcb->MainResource))) {
792 }
793 UDFReleaseResource(PtrResourceAcquired);
794 }
795
796 // Post IRP if required
797 if(RC == STATUS_PENDING) {
798
799 // Lock the callers buffer here. Then invoke a common routine to
800 // perform the post operation.
801 if (!(IrpSp->MinorFunction & IRP_MN_MDL)) {
802 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, ReadLength);
803 ASSERT(NT_SUCCESS(RC));
804 }
805 if(PagingIo) {
806 if(Res1Acq) {
808 }
809 if(Res2Acq) {
811 }
812 }
813 // Perform the post operation which will mark the IRP pending
814 // and will return STATUS_PENDING back to us
815 RC = UDFPostRequest(PtrIrpContext, Irp);
816
817 } else {
818 // For synchronous I/O, the FSD must maintain the current byte offset
819 // Do not do this however, if I/O is marked as paging-io
820 if (SynchronousIo && !PagingIo && NT_SUCCESS(RC)) {
821 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + NumberBytesRead;
822 }
823 // If the read completed successfully and this was not a paging-io
824 // operation, set a flag in the CCB that indicates that a read was
825 // performed and that the file time should be updated at cleanup
826 if (NT_SUCCESS(RC) && !PagingIo) {
828 Ccb->CCBFlags |= UDF_CCB_ACCESSED;
829 }
830
832 Irp->IoStatus.Status = RC;
833 Irp->IoStatus.Information = NumberBytesRead;
834 UDFPrint((" NumberBytesRead = %x\n", NumberBytesRead));
835 // Free up the Irp Context
836 UDFReleaseIrpContext(PtrIrpContext);
837 // complete the IRP
838 MmPrint((" Complete Irp, MDL=%x\n", Irp->MdlAddress));
839 if(Irp->MdlAddress) {
840 UDFTouch(Irp->MdlAddress);
841 }
843 }
844 } // can we complete the IRP ?
845 } _SEH2_END; // end of "__finally" processing
846
847 return(RC);
848} // end UDFCommonRead()
ULONG ReadLength
VOID NTAPI CcSetReadAheadGranularity(IN PFILE_OBJECT FileObject, IN ULONG Granularity)
Definition: cachesub.c:36
ULONG UDFIsResourceAcquired(IN PERESOURCE Resource)
Definition: misc.cpp:2518
BOOLEAN UDFAcquireResourceSharedWithCheck(IN PERESOURCE Resource)
Definition: misc.cpp:2556
#define CollectStatistics(VCB, Field)
Definition: env_spec.h:120
#define CollectStatisticsEx(VCB, Field, a)
Definition: env_spec.h:124
#define CollectStatistics2(VCB, Field)
Definition: env_spec.h:128
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define UDFAcquireSharedWaitForExclusive(Resource, CanWait)
Definition: env_spec_w32.h:671
ERESOURCE * PERESOURCE
Definition: env_spec_w32.h:595
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
BOOLEAN NTAPI FsRtlCheckLockForReadAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:672
VOID NTAPI CcInitializeCacheMap(IN PFILE_OBJECT FileObject, IN PCC_FILE_SIZES FileSizes, IN BOOLEAN PinAccess, IN PCACHE_MANAGER_CALLBACKS Callbacks, IN PVOID LazyWriteContext)
Definition: fssup.c:195
#define FILE_USE_FILE_POINTER_POSITION
Definition: nt_native.h:780
BOOLEAN NTAPI CcCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus)
Definition: copysup.c:43
#define STATUS_FILE_LOCK_CONFLICT
Definition: ntstatus.h:320
OSSTATUS UDFTRead(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
Definition: phys_lib.cpp:596
OSSTATUS UDFReadData(IN PVCB Vcb, IN BOOLEAN Translate, IN LONGLONG Offset, IN ULONG Length, IN BOOLEAN Direct, OUT PCHAR Buffer, OUT PSIZE_T ReadBytes)
NTSTATUS UDFLockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
Definition: read.cpp:936
VOID UDFMdlComplete(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
Definition: read.cpp:1117
NTSTATUS UDFPostStackOverflowRead(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp, IN PtrUDFFCB Fcb)
Definition: read.cpp:118
#define OVERFLOW_READ_THRESHHOLD
Definition: read.cpp:29
PVOID UDFGetCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:871
NTSTATUS UDFUnlockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
Definition: read.cpp:1034
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define UDF_IRP_CONTEXT_RES1_ACQ
Definition: struct.h:395
#define UDF_IRP_CONTEXT_FLUSH2_REQUIRED
Definition: struct.h:393
#define UDF_IRP_CONTEXT_FLUSH_REQUIRED
Definition: struct.h:392
#define UDF_IRP_CONTEXT_FORCED_POST
Definition: struct.h:397
#define UDF_CCB_ACCESSED
Definition: struct.h:149
#define UDF_IRP_CONTEXT_RES2_ACQ
Definition: struct.h:396
ULONG Flags
Definition: ntfs.h:536
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define UDFIsFileCached__(Vcb, FileInfo, Offset, Length, ForWrite)
Definition: udf_info.h:839
__inline OSSTATUS UDFReadFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, OUT int8 *Buffer, OUT PSIZE_T ReadBytes)
Definition: udf_info.h:666
OSSTATUS WCacheEODirect__(IN PW_CACHE Cache, IN PVOID Context)
#define IRP_MN_COMPLETE
Definition: iotypes.h:4420
#define IRP_PAGING_IO
#define FO_WRITE_THROUGH
Definition: iotypes.h:1779
#define IRP_MN_MDL
Definition: iotypes.h:4419
#define IRP_MN_DPC
Definition: iotypes.h:4418
#define FO_SYNCHRONOUS_IO
Definition: iotypes.h:1776
#define IRP_NOCACHE

Referenced by UDFCommonDispatch(), UDFRead(), and UDFStackOverflowRead().

◆ UDFCommonSetSecurity()

NTSTATUS UDFCommonSetSecurity ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Referenced by UDFCommonDispatch().

◆ UDFCommonSetVolInfo()

NTSTATUS UDFCommonSetVolInfo ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 666 of file volinfo.cpp.

670{
674 BOOLEAN CanWait = FALSE;
675 PVCB Vcb;
676 BOOLEAN PostRequest = FALSE;
677 BOOLEAN AcquiredVCB = FALSE;
679// PtrUDFFCB Fcb = NULL;
681
682 _SEH2_TRY {
683
684 UDFPrint(("UDFCommonSetVolInfo: \n"));
685 ASSERT(PtrIrpContext);
686 ASSERT(Irp);
687
688 PAGED_CODE();
689
692
693 // Get the FCB and CCB pointers.
694 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
695 ASSERT(Ccb);
696
697 if(Ccb && Ccb->Fcb && (Ccb->Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB)) {
698 UDFPrint((" Can't change Label on Non-volume object\n"));
700 }
701
703 ASSERT(Vcb);
704 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
705 // Reference our input parameters to make things easier
706
707 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
708 UDFPrint((" Can't change Label on blank volume ;)\n"));
710 }
711
712 Length = IrpSp->Parameters.SetVolume.Length;
713 // Acquire the Vcb for this volume.
714 CanWait = ((PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE);
715 if (!UDFAcquireResourceShared(&(Vcb->VCBResource), CanWait)) {
716 PostRequest = TRUE;
718 }
719 AcquiredVCB = TRUE;
720#ifdef UDF_ENABLE_SECURITY
722 Ccb->PreviouslyGrantedAccess,
723 PtrIrpContext->MajorFunction,
724 PtrIrpContext->MinorFunction,
725 0,
726 NULL,
727 &(IrpSp->Parameters.SetVolume.FsInformationClass));
728 if(!NT_SUCCESS(RC)) {
729 try_return(RC);
730 }
731#endif //UDF_ENABLE_SECURITY
732 switch (IrpSp->Parameters.SetVolume.FsInformationClass) {
733
735
736 RC = UDFSetLabelInfo( PtrIrpContext, Vcb, (PFILE_FS_LABEL_INFORMATION)(Irp->AssociatedIrp.SystemBuffer), &Length );
737 Irp->IoStatus.Information = 0;
738 break;
739
740 default:
741
743 Irp->IoStatus.Information = 0;
744 break;
745
746 }
747
748 // Set the information field to the number of bytes actually filled in
749 Irp->IoStatus.Information = IrpSp->Parameters.SetVolume.Length - Length;
750
751try_exit: NOTHING;
752
753 } _SEH2_FINALLY {
754
755 if (AcquiredVCB) {
756 UDFReleaseResource(&(Vcb->VCBResource));
757 AcquiredVCB = FALSE;
758 }
759
760 // Post IRP if required
761 if (PostRequest) {
762
763 // Since, the I/O Manager gave us a system buffer, we do not
764 // need to "lock" anything.
765
766 // Perform the post operation which will mark the IRP pending
767 // and will return STATUS_PENDING back to us
768 RC = UDFPostRequest(PtrIrpContext, Irp);
769
770 } else {
771
772 // Can complete the IRP here if no exception was encountered
774 Irp->IoStatus.Status = RC;
775
776 // Free up the Irp Context
777 UDFReleaseIrpContext(PtrIrpContext);
778 // complete the IRP
780 }
781 } // can we complete the IRP ?
782
783 } _SEH2_END;
784
785 return RC;
786} // end UDFCommonSetVolInfo()
@ FileFsLabelInformation
Definition: from_kernel.h:220
NTSTATUS UDFSetLabelInfo(IN PtrUDFIrpContext PtrIrpContext, IN PVCB Vcb, IN PFILE_FS_LABEL_INFORMATION Buffer, IN OUT PULONG Length)
Definition: volinfo.cpp:792

Referenced by UDFCommonDispatch(), and UDFSetVolInfo().

◆ UDFCommonShutdown()

NTSTATUS UDFCommonShutdown ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 115 of file shutdown.cpp.

119{
122 PVCB Vcb;
125 LARGE_INTEGER delay;
126
127 UDFPrint(("UDFCommonShutdown\n"));
128
129 _SEH2_TRY {
130 // First, get a pointer to the current I/O stack location
132 ASSERT(IrpSp);
133
135 if(!Buf)
137
138 // (a) Block all new "mount volume" requests by acquiring an appropriate
139 // global resource/lock.
140 // (b) Go through your linked list of mounted logical volumes and for
141 // each such volume, do the following:
142 // (i) acquire the volume resource exclusively
143 // (ii) invoke UDFFlushLogicalVolume() (internally) to flush the
144 // open data streams belonging to the volume from the system
145 // cache
146 // (iii) Invoke the physical/virtual/logical target device object
147 // on which the volume is mounted and inform this device
148 // about the shutdown request (Use IoBuildSynchronouFsdRequest()
149 // to create an IRP with MajorFunction = IRP_MJ_SHUTDOWN that you
150 // will then issue to the target device object).
151 // (iv) Wait for the completion of the shutdown processing by the target
152 // device object
153 // (v) Release the VCB resource we will have acquired in (i) above.
154
155 // Acquire GlobalDataResource
156 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
157 // Walk through all of the Vcb's attached to the global data.
158 Link = UDFGlobalData.VCBQueue.Flink;
159
160 while (Link != &(UDFGlobalData.VCBQueue)) {
161 // Get 'next' Vcb
162 Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
163 // Move to the next link now since the current Vcb may be deleted.
164 Link = Link->Flink;
165 ASSERT(Link != Link->Flink);
166
167 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_SHUTDOWN)) {
168
169#ifdef UDF_DELAYED_CLOSE
170 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
171 UDFPrint((" UDFCommonShutdown: set UDF_VCB_FLAGS_NO_DELAYED_CLOSE\n"));
173 UDFReleaseResource(&(Vcb->VCBResource));
174#endif //UDF_DELAYED_CLOSE
175
176 // Note: UDFCloseAllDelayed() doesn't acquire DelayedCloseResource if
177 // GlobalDataResource is already acquired. Thus for now we should
178 // release GlobalDataResource and re-acquire it later.
179 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
180 if(Vcb->RootDirFCB && Vcb->RootDirFCB->FileInfo) {
181 UDFPrint((" UDFCommonShutdown: UDFCloseAllSystemDelayedInDir\n"));
182 RC = UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
183 ASSERT(OS_SUCCESS(RC));
184 }
185
186#ifdef UDF_DELAYED_CLOSE
188// UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
189#endif //UDF_DELAYED_CLOSE
190
191 // re-acquire GlobalDataResource
192 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
193
194 // disable Eject Waiter
196 // Acquire Vcb resource
197 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
198
199 ASSERT(!Vcb->OverflowQueueCount);
200
201 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_SHUTDOWN)) {
202
204 if(Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) {
205 // let drive flush all data before reset
206 delay.QuadPart = -10000000; // 1 sec
208 }
209 Vcb->VCBFlags |= (UDF_VCB_FLAGS_SHUTDOWN |
211 }
212
213 UDFReleaseResource(&(Vcb->VCBResource));
214 }
215 }
216 // Once we have processed all the mounted logical volumes, we can release
217 // all acquired global resources and leave (in peace :-)
218 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
219 RC = STATUS_SUCCESS;
220
221try_exit: NOTHING;
222
223 } _SEH2_FINALLY {
224
225 if(Buf) MyFreePool__(Buf);
227 Irp->IoStatus.Status = RC;
228 Irp->IoStatus.Information = 0;
229 // Free up the Irp Context
230 UDFReleaseIrpContext(PtrIrpContext);
231 // complete the IRP
233 }
234
235 } _SEH2_END; // end of "__finally" processing
236
237 return(RC);
238} // end UDFCommonShutdown()
#define OS_SUCCESS(a)
Definition: env_spec_w32.h:56
#define KeDelayExecutionThread(mode, foo, t)
Definition: env_spec_w32.h:484
#define KernelMode
Definition: asm.h:34
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define UDF_VCB_FLAGS_REMOVABLE_MEDIA
Definition: udf_common.h:468
#define UDF_VCB_FLAGS_SHUTDOWN
Definition: udf_common.h:462
LONGLONG QuadPart
Definition: typedefs.h:114
static int Link(const char **args)
Definition: vfdcmd.c:2414

Referenced by UDFShutdown().

◆ UDFCommonWrite()

NTSTATUS UDFCommonWrite ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 112 of file write.cpp.

115{
119 ULONG WriteLength = 0, TruncatedLength = 0;
120 SIZE_T NumberBytesWritten = 0;
124 PVCB Vcb = NULL;
126 PERESOURCE PtrResourceAcquired = NULL;
127 PERESOURCE PtrResourceAcquired2 = NULL;
128 PVOID SystemBuffer = NULL;
129// PVOID TmpBuffer = NULL;
130// uint32 KeyValue = 0;
131 PIRP TopIrp;
132
133 LONGLONG ASize;
134 LONGLONG OldVDL;
135
136 ULONG Res1Acq = 0;
137 ULONG Res2Acq = 0;
138
139 BOOLEAN CacheLocked = FALSE;
140
141 BOOLEAN CanWait = FALSE;
142 BOOLEAN PagingIo = FALSE;
143 BOOLEAN NonBufferedIo = FALSE;
144 BOOLEAN SynchronousIo = FALSE;
145 BOOLEAN IsThisADeferredWrite = FALSE;
146 BOOLEAN WriteToEOF = FALSE;
147 BOOLEAN Resized = FALSE;
148 BOOLEAN RecursiveWriteThrough = FALSE;
149 BOOLEAN WriteFileSizeToDirNdx = FALSE;
150 BOOLEAN ZeroBlock = FALSE;
151 BOOLEAN VcbAcquired = FALSE;
152 BOOLEAN ZeroBlockDone = FALSE;
153
154 TmPrint(("UDFCommonWrite: irp %x\n", Irp));
155
156 _SEH2_TRY {
157
158
159 TopIrp = IoGetTopLevelIrp();
160
161 switch((ULONG_PTR)TopIrp) {
163 UDFPrint((" FSRTL_FSP_TOP_LEVEL_IRP\n"));
164 break;
166 UDFPrint((" FSRTL_CACHE_TOP_LEVEL_IRP\n"));
167 break;
169 UDFPrint((" FSRTL_MOD_WRITE_TOP_LEVEL_IRP\n"));
170 break;
172 UDFPrint((" FSRTL_FAST_IO_TOP_LEVEL_IRP\n"));
173 BrutePoint();
174 break;
175 case NULL:
176 UDFPrint((" NULL TOP_LEVEL_IRP\n"));
177 break;
178 default:
179 if(TopIrp == Irp) {
180 UDFPrint((" TOP_LEVEL_IRP\n"));
181 } else {
182 UDFPrint((" RECURSIVE_IRP, TOP = %x\n", TopIrp));
183 }
184 break;
185 }
186
187 // First, get a pointer to the current I/O stack location
189 ASSERT(IrpSp);
190 MmPrint((" Enter Irp, MDL=%x\n", Irp->MdlAddress));
191 if(Irp->MdlAddress) {
192 UDFTouch(Irp->MdlAddress);
193 }
194
197
198 // If this happens to be a MDL write complete request, then
199 // allocated MDL can be freed. This may cause a recursive write
200 // back into the FSD.
202 // Caller wants to tell the Cache Manager that a previously
203 // allocated MDL can be freed.
204 UDFMdlComplete(PtrIrpContext, Irp, IrpSp, FALSE);
205 // The IRP has been completed.
207 }
208
209 // If this is a request at IRQL DISPATCH_LEVEL, then post the request
212 }
213
214 // Get the FCB and CCB pointers
215 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
216 ASSERT(Ccb);
217 Fcb = Ccb->Fcb;
218 ASSERT(Fcb);
219 Vcb = Fcb->Vcb;
220
221 if(Fcb->FCBFlags & UDF_FCB_DELETED) {
222 ASSERT(FALSE);
224 }
225
226 // is this operation allowed ?
227 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
229 }
230 Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
231
232 // Disk based file systems might decide to verify the logical volume
233 // (if required and only if removable media are supported) at this time
234 // As soon as Tray is locked, we needn't call UDFVerifyVcb()
235
236 ByteOffset = IrpSp->Parameters.Write.ByteOffset;
237
238 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
239 PagingIo = (Irp->Flags & IRP_PAGING_IO) ? TRUE : FALSE;
240 NonBufferedIo = (Irp->Flags & IRP_NOCACHE) ? TRUE : FALSE;
241 SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO) ? TRUE : FALSE;
242 UDFPrint((" Flags: %s; %s; %s; %s; Irp(W): %8.8x\n",
243 CanWait ? "Wt" : "nw", PagingIo ? "Pg" : "np",
244 NonBufferedIo ? "NBuf" : "buff", SynchronousIo ? "Snc" : "Asc",
245 Irp->Flags));
246
247 NtReqFcb = Fcb->NTRequiredFCB;
248
249 Res1Acq = UDFIsResourceAcquired(&(NtReqFcb->MainResource));
250 if(!Res1Acq) {
251 Res1Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES1_ACQ;
252 }
253 Res2Acq = UDFIsResourceAcquired(&(NtReqFcb->PagingIoResource));
254 if(!Res2Acq) {
255 Res2Acq = PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_RES2_ACQ;
256 }
257
258 if(!NonBufferedIo &&
259 (Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB)) {
260 if((Fcb->NodeIdentifier.NodeType != UDF_NODE_TYPE_VCB) &&
261 UDFIsAStream(Fcb->FileInfo)) {
265 } else {
269 }
270 }
271
272 // Get some of the parameters supplied to us
273 WriteLength = IrpSp->Parameters.Write.Length;
274 if (WriteLength == 0) {
275 // a 0 byte write can be immediately succeeded
276 if (SynchronousIo && !PagingIo && NT_SUCCESS(RC)) {
277 // NT expects changing CurrentByteOffset to zero in this case
278 FileObject->CurrentByteOffset.QuadPart = 0;
279 }
280 try_return(RC);
281 }
282
283 // If this is the normal file we have to check for
284 // write access according to the current state of the file locks.
285 if (!PagingIo &&
286 !FsRtlCheckLockForWriteAccess( &(NtReqFcb->FileLock), Irp) ) {
288 }
289
290 // **********
291 // Is this a write of the volume itself ?
292 // **********
293 if (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) {
294 // Yup, we need to send this on to the disk driver after
295 // validation of the offset and length.
296 Vcb = (PVCB)(Fcb);
297 if(!CanWait)
299 // I dislike the idea of writing to not locked media
300 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED)) {
302 }
303
305
306 UDFPrint((" UDF_IRP_CONTEXT_FLUSH2_REQUIRED\n"));
307 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_FLUSH2_REQUIRED;
308
309 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK)) {
310 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
311 }
312#ifdef UDF_DELAYED_CLOSE
314#endif //UDF_DELAYED_CLOSE
315
316 }
317
318 // Acquire the volume resource exclusive
319 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
320 PtrResourceAcquired = &(Vcb->VCBResource);
321
322 // I dislike the idea of writing to mounted media too, but M$ has another point of view...
323 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) {
324 // flush system cache
326 }
327#if defined(_MSC_VER) && !defined(__clang__)
328/* FIXME */
329 if(PagingIo) {
330 CollectStatistics(Vcb, MetaDataWrites);
331 CollectStatisticsEx(Vcb, MetaDataWriteBytes, NumberBytesWritten);
332 }
333#endif
334 // Forward the request to the lower level driver
335 // Lock the callers buffer
336 if (!NT_SUCCESS(RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, WriteLength))) {
337 try_return(RC);
338 }
339 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
340 if(!SystemBuffer)
342 // Indicate, that volume contents can change after this operation
343 // This flag will force VerifyVolume in future
344 UDFPrint((" set UnsafeIoctl\n"));
345 Vcb->VCBFlags |= UDF_VCB_FLAGS_UNSAFE_IOCTL;
346 // Make sure, that volume will never be quick-remounted
347 // It is very important for ChkUdf utility.
348 Vcb->SerialNumber--;
349 // Perform actual Write
350 RC = UDFTWrite(Vcb, SystemBuffer, WriteLength,
351 (ULONG)(ByteOffset.QuadPart >> Vcb->BlockSizeBits),
352 &NumberBytesWritten);
353 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
354 try_return(RC);
355 }
356
357 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) {
359 }
360
361 // back pressure for very smart and fast system cache ;)
362 if(!NonBufferedIo) {
363 // cached IO
364 if(Vcb->VerifyCtx.QueuedCount ||
365 Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
367 }
368 } else {
369 if(Vcb->VerifyCtx.ItemCount > UDF_SYS_CACHE_STOP_THR) {
371 }
372 }
373
374 // The FSD (if it is a "nice" FSD) should check whether it is
375 // convenient to allow the write to proceed by utilizing the
376 // CcCanIWrite() function call. If it is not convenient to perform
377 // the write at this time, we should defer the request for a while.
378 // The check should not however be performed for non-cached write
379 // operations. To determine whether we are retrying the operation
380 // or now, use Flags in the IrpContext structure we have created
381
382 IsThisADeferredWrite = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_DEFERRED_WRITE) ? TRUE : FALSE;
383
384 if (!NonBufferedIo) {
385 MmPrint((" CcCanIWrite()\n"));
386 if (!CcCanIWrite(FileObject, WriteLength, CanWait, IsThisADeferredWrite)) {
387 // Cache Manager and/or the VMM does not want us to perform
388 // the write at this time. Post the request.
390 UDFPrint(("UDFCommonWrite: Defer write\n"));
391 MmPrint((" CcDeferWrite()\n"));
392 CcDeferWrite(FileObject, UDFDeferredWriteCallBack, PtrIrpContext, Irp, WriteLength, IsThisADeferredWrite);
394 }
395 }
396
397 // If the write request is directed to a page file,
398 // send the request directly to the disk
399 if (Fcb->FCBFlags & UDF_FCB_PAGE_FILE) {
400 NonBufferedIo = TRUE;
401 }
402
403 // We can continue. Check whether this write operation is targeted
404 // to a directory object in which case the UDF FSD will disallow
405 // the write request.
406 if (Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
408 try_return(RC);
409 }
410
411 // Validate start offset and length supplied.
412 // Here is a special check that determines whether the caller wishes to
413 // begin the write at current end-of-file (whatever the value of that
414 // offset might be)
415 if(ByteOffset.HighPart == (LONG)0xFFFFFFFF) {
417 WriteToEOF = TRUE;
418 ByteOffset = NtReqFcb->CommonFCBHeader.FileSize;
419 } else
421 ByteOffset = FileObject->CurrentByteOffset;
422 }
423 }
424
425 // Check if this volume has already been shut down. If it has, fail
426 // this write request.
427 if (Vcb->VCBFlags & UDF_VCB_FLAGS_SHUTDOWN) {
429 }
430
431 // Paging I/O write operations are special. If paging i/o write
432 // requests begin beyond end-of-file, the request should be no-oped
433 // If paging i/o
434 // requests extend beyond current end of file, they should be truncated
435 // to current end-of-file.
436 if(PagingIo && (WriteToEOF || ((ByteOffset.QuadPart + WriteLength) > NtReqFcb->CommonFCBHeader.FileSize.QuadPart))) {
437 if (ByteOffset.QuadPart > NtReqFcb->CommonFCBHeader.FileSize.QuadPart) {
438 TruncatedLength = 0;
439 } else {
440 TruncatedLength = (ULONG)(NtReqFcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
441 }
442 if(!TruncatedLength) try_return(RC = STATUS_SUCCESS);
443 } else {
444 TruncatedLength = WriteLength;
445 }
446
447#if defined(_MSC_VER) && !defined(__clang__)
448/* FIXME */
449 if(PagingIo) {
450 CollectStatistics(Vcb, UserFileWrites);
451 CollectStatisticsEx(Vcb, UserFileWriteBytes, NumberBytesWritten);
452 }
453#endif
454
455 // There are certain complications that arise when the same file stream
456 // has been opened for cached and non-cached access. The FSD is then
457 // responsible for maintaining a consistent view of the data seen by
458 // the caller.
459 // If this happens to be a non-buffered I/O, we should __try to flush the
460 // cached data (if some other file object has already initiated caching
461 // on the file stream). We should also __try to purge the cached
462 // information though the purge will probably fail if the file has been
463 // mapped into some process' virtual address space
464 // WARNING !!! we should not flush data beyond valid data length
465 if ( NonBufferedIo &&
466 !PagingIo &&
467 NtReqFcb->SectionObject.DataSectionObject &&
468 TruncatedLength &&
469 (ByteOffset.QuadPart < NtReqFcb->CommonFCBHeader.FileSize.QuadPart)) {
470
471 if(!Res1Acq) {
472 // Try to acquire the FCB MainResource exclusively
473 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
475 }
476 PtrResourceAcquired = &(NtReqFcb->MainResource);
477 }
478
479 if(!Res2Acq) {
480 // We hold PagingIo shared around the flush to fix a
481 // cache coherency problem.
482 UDFAcquireSharedStarveExclusive(&(NtReqFcb->PagingIoResource), TRUE );
483 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
484 }
485
486 // Flush and then attempt to purge the cache
487 if((ByteOffset.QuadPart + TruncatedLength) > NtReqFcb->CommonFCBHeader.FileSize.QuadPart) {
488 NumberBytesWritten = TruncatedLength;
489 } else {
490 NumberBytesWritten = (ULONG)(NtReqFcb->CommonFCBHeader.FileSize.QuadPart - ByteOffset.QuadPart);
491 }
492
493 MmPrint((" CcFlushCache()\n"));
494 CcFlushCache(&(NtReqFcb->SectionObject), &ByteOffset, NumberBytesWritten, &(Irp->IoStatus));
495
496 if(PtrResourceAcquired2) {
497 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
498 PtrResourceAcquired2 = NULL;
499 }
500 // If the flush failed, return error to the caller
501 if (!NT_SUCCESS(RC = Irp->IoStatus.Status)) {
502 NumberBytesWritten = 0;
503 try_return(RC);
504 }
505
506 if(!Res2Acq) {
507 // Acquiring and immediately dropping the resource serializes
508 // us behind any other writes taking place (either from the
509 // lazy writer or modified page writer).
510 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE );
511 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
512 }
513
514 // Attempt the purge and ignore the return code
515 MmPrint((" CcPurgeCacheSection()\n"));
516 CcPurgeCacheSection(&(NtReqFcb->SectionObject), &ByteOffset,
517 NumberBytesWritten, FALSE);
518 NumberBytesWritten = 0;
519 // We are finished with our flushing and purging
520 if(PtrResourceAcquired) {
521 UDFReleaseResource(PtrResourceAcquired);
522 PtrResourceAcquired = NULL;
523 }
524 }
525
526 // Determine if we were called by the lazywriter.
527 // We reuse 'IsThisADeferredWrite' here to decrease stack usage
528 IsThisADeferredWrite = (NtReqFcb->LazyWriterThreadID == HandleToUlong(PsGetCurrentThreadId()));
529
530 // Acquire the appropriate FCB resource
531 if(PagingIo) {
532 // PagingIoResource is already acquired exclusive
533 // on LazyWrite condition (see UDFAcqLazyWrite())
534 ASSERT(NonBufferedIo);
535 if(!IsThisADeferredWrite) {
536 if(!Res2Acq) {
537 // Try to acquire the FCB PagingIoResource exclusive
538 if(!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
540 }
541 // Remember the resource that was acquired
542 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
543 }
544 }
545 } else {
546 // Try to acquire the FCB MainResource shared
547 if(NonBufferedIo) {
548 if(!Res2Acq) {
549 if(!UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
550 //if(!UDFAcquireSharedWaitForExclusive(&(NtReqFcb->PagingIoResource), CanWait)) {
552 }
553 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
554 }
555 } else {
556 if(!Res1Acq) {
558 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
559 //if(!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
561 }
562 PtrResourceAcquired = &(NtReqFcb->MainResource);
563 }
564 }
565 // Remember the resource that was acquired
566 }
567
568 // Set the flag indicating if Fast I/O is possible
569 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
570/* if(NtReqFcb->CommonFCBHeader.IsFastIoPossible == FastIoIsPossible) {
571 NtReqFcb->CommonFCBHeader.IsFastIoPossible = FastIoIsQuestionable;
572 }*/
573
574 if ( (Irp->Flags & IRP_SYNCHRONOUS_PAGING_IO) &&
576
577 // This clause determines if the top level request was
578 // in the FastIo path.
580
581 PIO_STACK_LOCATION IrpStack;
582 ASSERT( TopIrp->Type == IO_TYPE_IRP );
583 IrpStack = IoGetCurrentIrpStackLocation(TopIrp);
584
585 // Finally this routine detects if the Top irp was a
586 // write to this file and thus we are the writethrough.
587 if ((IrpStack->MajorFunction == IRP_MJ_WRITE) &&
588 (IrpStack->FileObject->FsContext == FileObject->FsContext)) {
589
590 RecursiveWriteThrough = TRUE;
592 }
593 }
594 }
595
596 // Here is the deal with ValidDataLength and FileSize:
597 //
598 // Rule 1: PagingIo is never allowed to extend file size.
599 //
600 // Rule 2: Only the top level requestor may extend Valid
601 // Data Length. This may be paging IO, as when a
602 // a user maps a file, but will never be as a result
603 // of cache lazy writer writes since they are not the
604 // top level request.
605 //
606 // Rule 3: If, using Rules 1 and 2, we decide we must extend
607 // file size or valid data, we take the Fcb exclusive.
608
609 // Check whether the current request will extend the file size,
610 // or the valid data length (if the FSD supports the concept of a
611 // valid data length associated with the file stream). In either case,
612 // inform the Cache Manager at this time using CcSetFileSizes() about
613 // the new file length. Note that real FSD implementations will have to
614 // first allocate enough on-disk space at this point (before they
615 // inform the Cache Manager about the new size) to ensure that the write
616 // will subsequently not fail due to lack of disk space.
617
618 OldVDL = NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart;
619 ZeroBlock = (ByteOffset.QuadPart > OldVDL);
620
621 if (!PagingIo &&
622 !RecursiveWriteThrough &&
623 !IsThisADeferredWrite) {
624
625 BOOLEAN ExtendFS;
626
627 ExtendFS = (ByteOffset.QuadPart + TruncatedLength > NtReqFcb->CommonFCBHeader.FileSize.QuadPart);
628
629 if( WriteToEOF || ZeroBlock || ExtendFS) {
630 // we are extending the file;
631
632 if(!CanWait)
634// CanWait = TRUE;
635 // Release any resources acquired above ...
636 if (PtrResourceAcquired2) {
637 UDFReleaseResource(PtrResourceAcquired2);
638 PtrResourceAcquired2 = NULL;
639 }
640 if (PtrResourceAcquired) {
641 UDFReleaseResource(PtrResourceAcquired);
642 PtrResourceAcquired = NULL;
643 }
644 if(!UDFAcquireResourceShared(&(Vcb->VCBResource), CanWait)) {
646 }
647 VcbAcquired = TRUE;
648 if(!Res1Acq) {
649 // Try to acquire the FCB MainResource exclusively
651 if(!UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), CanWait)) {
653 }
654 // Remember the resource that was acquired
655 PtrResourceAcquired = &(NtReqFcb->MainResource);
656 }
657
658 if(!Res2Acq) {
659 // allocate space...
660 AdPrint((" Try to acquire PagingIoRes\n"));
661 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE );
662 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
663 }
664 AdPrint((" PagingIoRes Ok, Resizing...\n"));
665
666 if(ExtendFS) {
667 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart + TruncatedLength);
668
669 if(!NT_SUCCESS(RC)) {
670 if(PtrResourceAcquired2) {
671 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
672 PtrResourceAcquired2 = NULL;
673 }
674 try_return(RC);
675 }
676 Resized = TRUE;
677 // ... and inform the Cache Manager about it
678 NtReqFcb->CommonFCBHeader.FileSize.QuadPart = ByteOffset.QuadPart + TruncatedLength;
679 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFGetFileAllocationSize(Vcb, Fcb->FileInfo);
680 if(!Vcb->LowFreeSpace) {
681 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart += (PAGE_SIZE*9-1);
682 } else {
683 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart += (PAGE_SIZE-1);
684 }
685 NtReqFcb->CommonFCBHeader.AllocationSize.LowPart &= ~(PAGE_SIZE-1);
686 }
687
688 UDFPrint(("UDFCommonWrite: Set size %x (alloc size %x)\n", ByteOffset.LowPart + TruncatedLength, NtReqFcb->CommonFCBHeader.AllocationSize.LowPart));
690 if(ExtendFS) {
691 MmPrint((" CcSetFileSizes()\n"));
692 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
693 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
694 }
695 // Attempt to Zero newly added fragment
696 // and ignore the return code
697 // This should be done to inform cache manager
698 // that given extent has no cached data
699 // (Otherwise, CM sometimes thinks that it has)
700 if(ZeroBlock) {
701 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
702 ThPrint((" UDFZeroDataEx(1)\n"));
704 OldVDL,
705 /*ByteOffset.QuadPart*/ NtReqFcb->CommonFCBHeader.FileSize.QuadPart - OldVDL,
706 CanWait, Vcb, FileObject);
707#ifdef UDF_DBG
708 ZeroBlockDone = TRUE;
709#endif //UDF_DBG
710 }
711 }
712 if (PtrResourceAcquired2) {
713 UDFReleaseResource(PtrResourceAcquired2);
714 PtrResourceAcquired2 = NULL;
715 }
716
717 // Inform any pending IRPs (notify change directory).
718 if(UDFIsAStream(Fcb->FileInfo)) {
722 } else {
726 }
727 }
728
729 }
730
731#ifdef UDF_DISABLE_SYSTEM_CACHE_MANAGER
732 NonBufferedIo = TRUE;
733#endif
734 if(Fcb && Fcb->FileInfo && Fcb->FileInfo->Dloc) {
735 AdPrint(("UDFCommonWrite: DataLoc %x, Mapping %x\n", Fcb->FileInfo->Dloc->DataLoc, Fcb->FileInfo->Dloc->DataLoc.Mapping));
736 }
737
738 // Branch here for cached vs non-cached I/O
739 if (!NonBufferedIo) {
740
741 // The caller wishes to perform cached I/O. Initiate caching if
742 // this is the first cached I/O operation using this file object
743 if (!FileObject->PrivateCacheMap) {
744 // This is the first cached I/O operation. You must ensure
745 // that the FCB Common FCB Header contains valid sizes at this time
746 UDFPrint(("UDFCommonWrite: Init system cache\n"));
747 MmPrint((" CcInitializeCacheMap()\n"));
748 CcInitializeCacheMap(FileObject, (PCC_FILE_SIZES)(&(NtReqFcb->CommonFCBHeader.AllocationSize)),
749 FALSE, // We will not utilize pin access for this file
750 &(UDFGlobalData.CacheMgrCallBacks), // callbacks
751 NtReqFcb); // The context used in callbacks
752 MmPrint((" CcSetReadAheadGranularity()\n"));
753 CcSetReadAheadGranularity(FileObject, Vcb->SystemCacheGran);
754
755 }
756
757 if(ZeroBlock && !ZeroBlockDone) {
758 ThPrint((" UDFZeroDataEx(2)\n"));
760 OldVDL,
761 /*ByteOffset.QuadPart*/ ByteOffset.QuadPart + TruncatedLength - OldVDL,
762 CanWait, Vcb, FileObject);
763 if(ByteOffset.LowPart & (PAGE_SIZE-1)) {
764 }
765 }
766
767 WriteFileSizeToDirNdx = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_WRITE_THROUGH) ?
768 TRUE : FALSE;
769 // Check and see if this request requires a MDL returned to the caller
771 // Caller does want a MDL returned. Note that this mode
772 // implies that the caller is prepared to block
773 MmPrint((" CcPrepareMdlWrite()\n"));
774// CcPrepareMdlWrite(FileObject, &ByteOffset, TruncatedLength, &(Irp->MdlAddress), &(Irp->IoStatus));
775// NumberBytesWritten = Irp->IoStatus.Information;
776// RC = Irp->IoStatus.Status;
777
778 NumberBytesWritten = 0;
780
781 try_return(RC);
782 }
783
784 if(NtReqFcb->SectionObject.DataSectionObject &&
785 TruncatedLength >= 0x10000 &&
786 ByteOffset.LowPart &&
787 !(ByteOffset.LowPart & 0x00ffffff)) {
788
789 //if(WinVer_Id() < WinVer_2k) {
790 //LARGE_INTEGER flush_offs;
791 //flush_offs.QuadPart = ByteOffset.QuadPart - 0x100*0x10000;
792 MmPrint((" CcFlushCache() 16Mb\n"));
793 //CcFlushCache(&(NtReqFcb->SectionObject), &ByteOffset, 0x100*0x10000, &(Irp->IoStatus));
794
795 // there was a nice idea: flush just previous part. But it doesn't work
796 CcFlushCache(&(NtReqFcb->SectionObject), NULL, 0, &(Irp->IoStatus));
797 //}
798 }
799
800 // This is a regular run-of-the-mill cached I/O request. Let the
801 // Cache Manager worry about it!
802 // First though, we need a buffer pointer (address) that is valid
803
804 // We needn't call CcZeroData 'cause udf_info.cpp will care about it
805 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
806 if(!SystemBuffer)
808 ASSERT(SystemBuffer);
809 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
810 PerfPrint(("UDFCommonWrite: CcCopyWrite %x bytes at %x\n", TruncatedLength, ByteOffset.LowPart));
811 MmPrint((" CcCopyWrite()\n"));
812 if(!CcCopyWrite(FileObject, &(ByteOffset), TruncatedLength, CanWait, SystemBuffer)) {
813 // The caller was not prepared to block and data is not immediately
814 // available in the system cache
815 // Mark Irp Pending ...
817 }
818
819 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
820 // We have the data
821 RC = STATUS_SUCCESS;
822 NumberBytesWritten = TruncatedLength;
823
824 try_return(RC);
825
826 } else {
827
828 MmPrint((" Write NonBufferedIo\n"));
829
830 // We needn't call CcZeroData here (like in Fat driver)
831 // 'cause we've already done it above
832 // (see call to UDFZeroDataEx() )
833 if (!RecursiveWriteThrough &&
834 !IsThisADeferredWrite &&
835 (OldVDL < ByteOffset.QuadPart)) {
836#ifdef UDF_DBG
837 ASSERT(!ZeroBlockDone);
838#endif //UDF_DBG
840 OldVDL,
841 /*ByteOffset.QuadPart*/ ByteOffset.QuadPart - OldVDL,
842 CanWait, Vcb, FileObject);
843 }
844 if(OldVDL < (ByteOffset.QuadPart + TruncatedLength)) {
845 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = ByteOffset.QuadPart + TruncatedLength;
846 }
847
848#if 1
850 UDFPrint(("FSRTL_MOD_WRITE_TOP_LEVEL_IRP => CanWait\n"));
851 CanWait = TRUE;
852 } else
853 if((ULONG_PTR)TopIrp == FSRTL_CACHE_TOP_LEVEL_IRP) {
854 UDFPrint(("FSRTL_CACHE_TOP_LEVEL_IRP => CanWait\n"));
855 CanWait = TRUE;
856 }
857
858 if(NtReqFcb->AcqSectionCount || NtReqFcb->AcqFlushCount) {
859 MmPrint((" AcqCount (%d/%d)=> CanWait ?\n", NtReqFcb->AcqSectionCount, NtReqFcb->AcqFlushCount));
860 CanWait = TRUE;
861 } else
862 {}
863/* if((TopIrp != Irp)) {
864 UDFPrint(("(TopIrp != Irp) => CanWait\n"));
865 CanWait = TRUE;
866 } else*/
867#endif
869 MmPrint((" !PASSIVE_LEVEL\n"));
870 CanWait = FALSE;
872 }
873 // Successful check will cause WCache lock
874 if(!CanWait && UDFIsFileCached__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength, TRUE)) {
875 UDFPrint(("UDFCommonWrite: Cached => CanWait\n"));
876 CacheLocked = TRUE;
877 CanWait = TRUE;
878 }
879 // Send the request to lower level drivers
880 if(!CanWait) {
881 UDFPrint(("UDFCommonWrite: Post physical write %x bytes at %x\n", TruncatedLength, ByteOffset.LowPart));
882
884 }
885
886 if(!Res2Acq) {
887 if(UDFAcquireResourceExclusiveWithCheck(&(NtReqFcb->PagingIoResource))) {
888 PtrResourceAcquired2 = &(NtReqFcb->PagingIoResource);
889 }
890 }
891
892 PerfPrint(("UDFCommonWrite: Physical write %x bytes at %x\n", TruncatedLength, ByteOffset.LowPart));
893
894 // Lock the callers buffer
895 if (!NT_SUCCESS(RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, TruncatedLength))) {
896 try_return(RC);
897 }
898
899 SystemBuffer = UDFGetCallersBuffer(PtrIrpContext, Irp);
900 if(!SystemBuffer) {
902 }
903 NtReqFcb->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
904 RC = UDFWriteFile__(Vcb, Fcb->FileInfo, ByteOffset.QuadPart, TruncatedLength,
905 CacheLocked, (PCHAR)SystemBuffer, &NumberBytesWritten);
906
907 UDFUnlockCallersBuffer(PtrIrpContext, Irp, SystemBuffer);
908
909#if defined(_MSC_VER) && !defined(__clang__)
910/* FIXME */
911 if(PagingIo) {
912 CollectStatistics(Vcb, UserDiskWrites);
913 } else {
914 CollectStatistics2(Vcb, NonCachedDiskWrites);
915 }
916#endif
917 WriteFileSizeToDirNdx = TRUE;
918
919 try_return(RC);
920 }
921
922try_exit: NOTHING;
923
924 } _SEH2_FINALLY {
925
926 if(CacheLocked) {
927 WCacheEODirect__(&(Vcb->FastCache), Vcb);
928 }
929
930 // Release any resources acquired here ...
931 if(PtrResourceAcquired2) {
932 UDFReleaseResource(PtrResourceAcquired2);
933 }
934 if(PtrResourceAcquired) {
935 if(NtReqFcb &&
936 (PtrResourceAcquired ==
937 &(NtReqFcb->MainResource))) {
939 }
940 UDFReleaseResource(PtrResourceAcquired);
941 }
942 if(VcbAcquired) {
943 UDFReleaseResource(&(Vcb->VCBResource));
944 }
945
946 // Post IRP if required
947 if(RC == STATUS_PENDING) {
948
949 // Lock the callers buffer here. Then invoke a common routine to
950 // perform the post operation.
951 if (!(IrpSp->MinorFunction & IRP_MN_MDL)) {
952 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, FALSE, WriteLength);
953 ASSERT(NT_SUCCESS(RC));
954 }
955 if(PagingIo) {
956 if(Res1Acq) {
958 }
959 if(Res2Acq) {
961 }
962 }
963
964 // Perform the post operation which will mark the IRP pending
965 // and will return STATUS_PENDING back to us
966 RC = UDFPostRequest(PtrIrpContext, Irp);
967
968 } else {
969 // For synchronous I/O, the FSD must maintain the current byte offset
970 // Do not do this however, if I/O is marked as paging-io
971 if (SynchronousIo && !PagingIo && NT_SUCCESS(RC)) {
972 FileObject->CurrentByteOffset.QuadPart = ByteOffset.QuadPart + NumberBytesWritten;
973 }
974 // If the write completed successfully and this was not a paging-io
975 // operation, set a flag in the CCB that indicates that a write was
976 // performed and that the file time should be updated at cleanup
977 if (NT_SUCCESS(RC) && !PagingIo) {
978 Ccb->CCBFlags |= UDF_CCB_MODIFIED;
979 // If the file size was changed, set a flag in the FCB indicating that
980 // this occurred.
982 if(Resized) {
983 if(!WriteFileSizeToDirNdx) {
985 } else {
986 ASize = UDFGetFileAllocationSize(Vcb, Fcb->FileInfo);
987 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, &ASize);
988 }
989 }
990 // Update ValidDataLength
991 if(!IsThisADeferredWrite &&
992 NtReqFcb) {
993 if(NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart < (ByteOffset.QuadPart + NumberBytesWritten)) {
994
995 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart =
996 min(NtReqFcb->CommonFCBHeader.FileSize.QuadPart,
997 ByteOffset.QuadPart + NumberBytesWritten);
998 }
999 }
1000 }
1001
1002 // If the request failed, and we had done some nasty stuff like
1003 // extending the file size (including informing the Cache Manager
1004 // about the new file size), and allocating on-disk space etc., undo
1005 // it at this time.
1006
1007 // Can complete the IRP here if no exception was encountered
1009 Irp) {
1010 Irp->IoStatus.Status = RC;
1011 Irp->IoStatus.Information = NumberBytesWritten;
1012 // complete the IRP
1013 MmPrint((" Complete Irp, MDL=%x\n", Irp->MdlAddress));
1014 if(Irp->MdlAddress) {
1015 UDFTouch(Irp->MdlAddress);
1016 }
1018 }
1019 // Free up the Irp Context
1020 UDFReleaseIrpContext(PtrIrpContext);
1021
1022 } // can we complete the IRP ?
1023 } _SEH2_END; // end of "__finally" processing
1024
1025 UDFPrint(("\n"));
1026 return(RC);
1027} // end UDFCommonWrite()
ULONG WriteLength
Definition: CcPinRead_drv.c:40
#define CcIsFileCached(FO)
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PerfPrint(_x_)
Definition: env_spec_w32.h:291
#define UDFAcquireSharedStarveExclusive(Resource, CanWait)
Definition: env_spec_w32.h:669
#define ThPrint(_x_)
Definition: env_spec_w32.h:293
#define FILE_WRITE_TO_END_OF_FILE
Definition: ext2fs.h:278
BOOLEAN NTAPI FsRtlCheckLockForWriteAccess(IN PFILE_LOCK FileLock, IN PIRP Irp)
Definition: filelock.c:710
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG
Definition: fsrtltypes.h:65
#define min(a, b)
Definition: monoChain.cc:55
BOOLEAN NTAPI CcCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN PVOID Buffer)
Definition: copysup.c:129
BOOLEAN NTAPI CcCanIWrite(IN PFILE_OBJECT FileObject, IN ULONG BytesToWrite, IN BOOLEAN Wait, IN UCHAR Retrying)
Definition: copysup.c:214
VOID NTAPI CcDeferWrite(IN PFILE_OBJECT FileObject, IN PCC_POST_DEFERRED_WRITE PostRoutine, IN PVOID Context1, IN PVOID Context2, IN ULONG BytesToWrite, IN BOOLEAN Retrying)
Definition: copysup.c:225
#define STATUS_TOO_LATE
Definition: ntstatus.h:626
OSSTATUS UDFTWrite(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
Definition: phys_lib.cpp:453
#define UDFZeroDataEx(NtReqFcb, Offset, Length, CanWait, Vcb, FileObject)
Definition: protos.h:1146
NTSTATUS UDFLockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, BOOLEAN IsReadOperation, uint32 Length)
Definition: read.cpp:936
VOID UDFMdlComplete(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PIO_STACK_LOCATION IrpSp, BOOLEAN ReadCompletion)
Definition: read.cpp:1117
PVOID UDFGetCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:871
NTSTATUS UDFUnlockCallersBuffer(PtrUDFIrpContext PtrIrpContext, PIRP Irp, PVOID SystemBuffer)
Definition: read.cpp:1034
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
VOID UDFVVerify(IN PVCB Vcb, IN ULONG Flags)
Definition: remap.cpp:601
#define UDF_IRP_CONTEXT_DEFERRED_WRITE
Definition: struct.h:388
#define UDF_IRP_CONTEXT_WRITE_THROUGH
Definition: struct.h:386
#define UDF_CCB_MODIFIED
Definition: struct.h:150
#define UDF_VCB_FLAGS_VOLUME_LOCKED
Definition: udf_common.h:460
OSSTATUS UDFWriteFile__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, IN SIZE_T Length, IN BOOLEAN Direct, IN int8 *Buffer, OUT PSIZE_T WrittenBytes)
Definition: udf_info.cpp:1605
#define UDF_MAX_VERIFY_CACHE
Definition: udf_info.h:1255
#define UFD_VERIFY_FLAG_WAIT
Definition: udf_info.h:1303
#define UDF_SYS_CACHE_STOP_THR
Definition: udf_info.h:1258
VOID NTAPI UDFDeferredWriteCallBack(IN PVOID Context1, IN PVOID Context2)
Definition: write.cpp:1048
#define FILE_NOTIFY_CHANGE_SIZE
#define IO_TYPE_IRP
#define FILE_NOTIFY_CHANGE_STREAM_WRITE
#define FILE_NOTIFY_CHANGE_STREAM_SIZE
#define IRP_SYNCHRONOUS_PAGING_IO

Referenced by UDFCommonDispatch(), and UDFWrite().

◆ UDFCompareVcb()

NTSTATUS UDFCompareVcb ( IN PVCB  OldVcb,
IN PVCB  NewVcb,
IN BOOLEAN  PhysicalOnly 
)

Definition at line 849 of file verfysup.cpp.

854{
855 NTSTATUS RC;
856 UDF_FILE_INFO RootFileInfo;
857 BOOLEAN SimpleLogicalCheck = FALSE;
858
859 UDFPrint(("UDFCompareVcb:\n"));
861 UDFPrint((" WRONG_VOLUME\n"));
862 return STATUS_WRONG_VOLUME;
863 }
864
865#define VCB_NE(x) (OldVcb->x != NewVcb->x)
866
867 // compare physical parameters
868 if(PhysicalOnly) {
869 UDFPrint((" PhysicalOnly\n"));
870 if(VCB_NE(FirstLBA) ||
871 VCB_NE(LastLBA) ||
872 VCB_NE(FirstTrackNum) ||
873 VCB_NE(LastTrackNum) ||
874 VCB_NE(NWA) ||
875 VCB_NE(LastPossibleLBA) ||
876 VCB_NE(PhSerialNumber) ||
877 VCB_NE(PhErasable) ||
878 VCB_NE(PhDiskType) ||
879 VCB_NE(MediaClassEx) ||
880
881 /* We cannot compare these flags, because NewVcb is in unconditional ReadOnly */
882
883 /*((OldVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY)) ||
884 ((OldVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) != (NewVcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) ||*/
885
887 // VCB_NE(xxx) ||
888 // VCB_NE(xxx) ||
889 VCB_NE(LastSession) ) {
890
891 UDFPrint((" WRONG_VOLUME (2)\n"));
892 return STATUS_WRONG_VOLUME;
893 }
894 // Note, MRWStatus can change while media is mounted (stoppped/in-progress/complete)
895 // We can compare only (Vcb->MRWStatus == 0) values
896 if((OldVcb->MRWStatus == 0) != (NewVcb->MRWStatus == 0)) {
897 UDFPrint((" WRONG_VOLUME (4), missmatch MRW status\n"));
898 }
899 for(uint32 i=OldVcb->FirstTrackNum; i<=OldVcb->LastTrackNum; i++) {
900 if(VCB_NE(TrackMap[i].FirstLba) ||
901 VCB_NE(TrackMap[i].LastLba) ||
902 VCB_NE(TrackMap[i].PacketSize) ||
903 VCB_NE(TrackMap[i].TrackParam) ||
904 VCB_NE(TrackMap[i].DataParam) ||
905 VCB_NE(TrackMap[i].NWA_V) ) {
906 UDFPrint((" WRONG_VOLUME (3), missmatch trk %d\n", i));
907 return STATUS_WRONG_VOLUME;
908 }
909 }
910 UDFPrint((" Vcb compare Ok\n"));
911 return STATUS_SUCCESS;
912 }
913
914 // Something is nasty!!! We perform verify for not flushed volume
915 // This should never happen, but some devices/buses and their drivers
916 // can lead us to such condition. For example with help of RESET.
917 // Now, we hope, that nobody changed media.
918 // We shall make simplified logical structure check
919 if(OldVcb->Modified) {
920 UDFPrint((" Vcb SIMPLE compare on !!!MODIFIED!!! volume\n"));
921 ASSERT(FALSE);
922 SimpleLogicalCheck = TRUE;
923 }
924
925 // compare logical structure
926 if(!SimpleLogicalCheck && (OldVcb->InitVatCount != NewVcb->InitVatCount)) {
927 UDFPrint((" InitVatCount %d != %d \n", OldVcb->InitVatCount, NewVcb->InitVatCount));
928 return STATUS_WRONG_VOLUME;
929 }
930
931 // Compare volume creation time
932 if(OldVcb->VolCreationTime != NewVcb->VolCreationTime) {
933 UDFPrint((" VolCreationTime %I64x != %I64x \n", OldVcb->VolCreationTime, NewVcb->VolCreationTime));
934 return STATUS_WRONG_VOLUME;
935 }
936 // Compare serial numbers
937 if(OldVcb->SerialNumber != NewVcb->SerialNumber) {
938 UDFPrint((" SerialNumber %x != %x \n", OldVcb->SerialNumber, NewVcb->SerialNumber));
939 return STATUS_WRONG_VOLUME;
940 }
941 // Compare volume idents
942 if(!SimpleLogicalCheck &&
943 RtlCompareUnicodeString(&(OldVcb->VolIdent),&(NewVcb->VolIdent),FALSE)) {
944 UDFPrint((" VolIdent missmatch \n"));
945 return STATUS_WRONG_VOLUME;
946 }
947 if(SimpleLogicalCheck) {
948 // do not touch RootDir. It can be partially recorded
949 UDFPrint((" SimpleLogicalCheck Ok\n"));
950 return STATUS_SUCCESS;
951 }
952
953 RC = UDFOpenRootFile__(NewVcb, &(NewVcb->RootLbAddr), &RootFileInfo);
954 if(!NT_SUCCESS(RC)) {
955 UDFPrint((" Can't open root file, status %x\n", RC));
956 UDFCleanUpFile__(NewVcb, &RootFileInfo);
957 return STATUS_WRONG_VOLUME;
958 }
959 // perform exhaustive check
960 if(!(OldVcb->RootDirFCB)) {
961 UDFPrint((" !(OldVcb->RootDirFCB)\n"));
962wr_vol:
963 UDFCloseFile__(NewVcb, &RootFileInfo);
964 UDFCleanUpFile__(NewVcb, &RootFileInfo);
965 return STATUS_WRONG_VOLUME;
966 }
967
968 if(!UDFCompareFileInfo(&RootFileInfo, OldVcb->RootDirFCB->FileInfo)) {
969 UDFPrint((" !UDFCompareFileInfo\n"));
970 goto wr_vol;
971 }
972 UDFCloseFile__(NewVcb, &RootFileInfo);
973 UDFCleanUpFile__(NewVcb, &RootFileInfo);
974
975 UDFPrint(("UDFCompareVcb: Ok\n"));
976 return STATUS_SUCCESS;
977
978#undef VCB_NE
979
980} // end UDFCompareVcb()
unsigned int uint32
Definition: types.h:32
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
IN OUT PVCB IN PDEVICE_OBJECT TargetDeviceObject
Definition: fatprocs.h:1674
#define UDF_DATA_FLAGS_BEING_UNLOADED
Definition: udf_common.h:636
OSSTATUS UDFOpenRootFile__(IN PVCB Vcb, IN lb_addr *RootLoc, OUT PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:2187
BOOLEAN UDFCompareFileInfo(IN PUDF_FILE_INFO f1, IN PUDF_FILE_INFO f2)
Definition: udf_info.cpp:4218
#define STATUS_WRONG_VOLUME
Definition: udferr_usr.h:140
#define VCB_NE(x)
_In_ USHORT PacketSize
Definition: iofuncs.h:1058

Referenced by UDFVerifyVolume().

◆ UDFCompleteMount()

NTSTATUS UDFCompleteMount ( IN PVCB  Vcb)

Definition at line 913 of file fscntrl.cpp.

916{
917 NTSTATUS RC;// = STATUS_SUCCESS;
919 PFSRTL_COMMON_FCB_HEADER PtrCommonFCBHeader = NULL;
920 UNICODE_STRING LocalPath;
921 PtrUDFObjectName RootName;
922 PtrUDFFCB RootFcb;
923
924 UDFPrint(("UDFCompleteMount:\n"));
925 Vcb->ZBuffer = (PCHAR)DbgAllocatePoolWithTag(NonPagedPool, max(Vcb->LBlockSize, PAGE_SIZE), 'zNWD');
926 if(!Vcb->ZBuffer) return STATUS_INSUFFICIENT_RESOURCES;
927 RtlZeroMemory(Vcb->ZBuffer, Vcb->LBlockSize);
928
929 UDFPrint(("UDFCompleteMount: alloc Root FCB\n"));
930 // Create the root index and reference it in the Vcb.
931 RootFcb =
932 Vcb->RootDirFCB = UDFAllocateFCB();
933 if(!RootFcb) return STATUS_INSUFFICIENT_RESOURCES;
934
935 UDFPrint(("UDFCompleteMount: alloc Root ObjName\n"));
936 // Allocate and set root FCB unique name
937 RootName = UDFAllocateObjectName();
938 if(!RootName) {
939 UDFCleanUpFCB(RootFcb);
940 Vcb->RootDirFCB = NULL;
942 }
944 if(!NT_SUCCESS(RC))
945 goto insuf_res_1;
946
948 if(!RootFcb->FileInfo) {
950insuf_res_1:
951 MyFreePool__(RootName->ObjectName.Buffer);
952 UDFReleaseObjectName(RootName);
953 UDFCleanUpFCB(RootFcb);
954 Vcb->RootDirFCB = NULL;
955 return RC;
956 }
957 UDFPrint(("UDFCompleteMount: open Root Dir\n"));
958 // Open Root Directory
959 RC = UDFOpenRootFile__( Vcb, &(Vcb->RootLbAddr), RootFcb->FileInfo );
960 if(!NT_SUCCESS(RC)) {
961insuf_res_2:
962 UDFCleanUpFile__(Vcb, RootFcb->FileInfo);
963 MyFreePool__(RootFcb->FileInfo);
964 goto insuf_res_1;
965 }
966 RootFcb->FileInfo->Fcb = RootFcb;
967
968 if(!(RootFcb->NTRequiredFCB = RootFcb->FileInfo->Dloc->CommonFcb)) {
969 UDFPrint(("UDFCompleteMount: alloc Root ObjName (2)\n"));
970 if(!(RootFcb->NTRequiredFCB =
973 goto insuf_res_2;
974 }
976 RootFcb->FileInfo->Dloc->CommonFcb = RootFcb->NTRequiredFCB;
977 }
978 UDFPrint(("UDFCompleteMount: init FCB\n"));
980 if(!NT_SUCCESS(RC)) {
981 // if we get here, no resources are inited
982 RootFcb->OpenHandleCount =
983 RootFcb->ReferenceCount =
984 RootFcb->NTRequiredFCB->CommonRefCount = 0;
985
986 UDFCleanUpFile__(Vcb, RootFcb->FileInfo);
987 MyFreePool__(RootFcb->FileInfo);
988 MyFreePool__(RootFcb->NTRequiredFCB);
989 UDFCleanUpFCB(RootFcb);
990 Vcb->RootDirFCB = NULL;
991 return RC;
992 }
993
994 // this is a part of UDF_RESIDUAL_REFERENCE
995 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
996 RootFcb->OpenHandleCount =
997 RootFcb->ReferenceCount =
998 RootFcb->NTRequiredFCB->CommonRefCount = 1;
999
1000 UDFGetFileXTime(RootFcb->FileInfo,
1001 &(RootFcb->NTRequiredFCB->CreationTime.QuadPart),
1003 &(RootFcb->NTRequiredFCB->ChangeTime.QuadPart),
1004 &(RootFcb->NTRequiredFCB->LastWriteTime.QuadPart) );
1005
1006 if(Vcb->SysStreamLbAddr.logicalBlockNum) {
1007 Vcb->SysSDirFileInfo = (PUDF_FILE_INFO)MyAllocatePool__(NonPagedPool,sizeof(UDF_FILE_INFO));
1008 if(!Vcb->SysSDirFileInfo) {
1010 goto unwind_1;
1011 }
1012 // Open System SDir Directory
1013 RC = UDFOpenRootFile__( Vcb, &(Vcb->SysStreamLbAddr), Vcb->SysSDirFileInfo );
1014 if(!NT_SUCCESS(RC)) {
1015 UDFCleanUpFile__(Vcb, Vcb->SysSDirFileInfo);
1016 MyFreePool__(Vcb->SysSDirFileInfo);
1017 Vcb->SysSDirFileInfo = NULL;
1018 goto unwind_1;
1019 } else {
1020 Vcb->SysSDirFileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY;
1021 }
1022 }
1023
1024 // Open Unallocatable space stream
1025 // Generally, it should be placed in SystemStreamDirectory, but some
1026 // stupid apps think that RootDirectory is much better place.... :((
1028 if(NT_SUCCESS(RC)) {
1029 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &(Vcb->NonAllocFileInfo), NULL);
1030 MyFreePool__(LocalPath.Buffer);
1031 }
1032 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1033
1034//unwind_2:
1035 UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1036 Vcb->NonAllocFileInfo = NULL;
1037 // this was a part of UDF_RESIDUAL_REFERENCE
1038 UDFInterlockedDecrement((PLONG)&(Vcb->VCBOpenCount));
1039unwind_1:
1040
1041 // UDFCloseResidual() will clean up everything
1042
1043 return RC;
1044 }
1045
1046 /* process Non-allocatable */
1047 if(NT_SUCCESS(RC)) {
1048 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1049 UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1050 } else {
1051 /* try to read Non-allocatable from alternate locations */
1053 if(!NT_SUCCESS(RC)) {
1054 goto unwind_1;
1055 }
1056 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &(Vcb->NonAllocFileInfo), NULL);
1057 MyFreePool__(LocalPath.Buffer);
1058 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1059 goto unwind_1;
1060 }
1061 if(NT_SUCCESS(RC)) {
1062 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1063 UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1064 } else
1065 if(Vcb->SysSDirFileInfo) {
1067 if(!NT_SUCCESS(RC)) {
1068 goto unwind_1;
1069 }
1070 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &(Vcb->NonAllocFileInfo), NULL);
1071 MyFreePool__(LocalPath.Buffer);
1072 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1073 goto unwind_1;
1074 }
1075 if(NT_SUCCESS(RC)) {
1076 UDFMarkSpaceAsXXX(Vcb, Vcb->NonAllocFileInfo->Dloc, Vcb->NonAllocFileInfo->Dloc->DataLoc.Mapping, AS_USED); // used
1077// UDFDirIndex(UDFGetDirIndexByFileInfo(Vcb->NonAllocFileInfo), Vcb->NonAllocFileInfo->Index)->FI_Flags |= UDF_FI_FLAG_FI_INTERNAL;
1078 } else {
1079 RC = STATUS_SUCCESS;
1080 }
1081 } else {
1082 RC = STATUS_SUCCESS;
1083 }
1084 }
1085
1086 /* Read SN UID mapping */
1087 if(Vcb->SysSDirFileInfo) {
1088 RC = MyInitUnicodeString(&LocalPath, UDF_SN_UID_MAPPING);
1089 if(!NT_SUCCESS(RC))
1090 goto unwind_3;
1091 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, Vcb->SysSDirFileInfo , &(Vcb->UniqueIDMapFileInfo), NULL);
1092 MyFreePool__(LocalPath.Buffer);
1093 if(!NT_SUCCESS(RC) && (RC != STATUS_OBJECT_NAME_NOT_FOUND)) {
1094unwind_3:
1095// UDFCloseFile__(Vcb, Vcb->NonAllocFileInfo);
1096// UDFCleanUpFile__(Vcb, Vcb->NonAllocFileInfo);
1097// if(Vcb->NonAllocFileInfo)
1098// MyFreePool__(Vcb->NonAllocFileInfo);
1099// Vcb->NonAllocFileInfo = NULL;
1100 goto unwind_1;
1101 } else {
1102 Vcb->UniqueIDMapFileInfo->Dloc->DataLoc.Flags |= EXTENT_FLAG_VERIFY;
1103 }
1104 RC = STATUS_SUCCESS;
1105 }
1106
1107#define DWN_MAX_CFG_FILE_SIZE 0x10000
1108
1109 /* Read DWN config file from disk with disk-specific options */
1111 if(NT_SUCCESS(RC)) {
1112
1113 int8* buff;
1114 SIZE_T len;
1115 PUDF_FILE_INFO CfgFileInfo = NULL;
1116
1117 RC = UDFOpenFile__(Vcb, FALSE, TRUE, &LocalPath, RootFcb->FileInfo, &CfgFileInfo, NULL);
1118 if(OS_SUCCESS(RC)) {
1119
1120 len = (ULONG)UDFGetFileSize(CfgFileInfo);
1121 if(len && len < DWN_MAX_CFG_FILE_SIZE) {
1123 if(buff) {
1124 RC = UDFReadFile__(Vcb, CfgFileInfo, 0, len, FALSE, buff, &len);
1125 if(OS_SUCCESS(RC)) {
1126 // parse config
1127 Vcb->Cfg = (PUCHAR)buff;
1128 Vcb->CfgLength = len;
1129 UDFReadRegKeys(Vcb, TRUE /*update*/, TRUE /*cfg*/);
1130 Vcb->Cfg = NULL;
1131 Vcb->CfgLength = 0;
1132 Vcb->CfgVersion = 0;
1133 }
1135 }
1136 }
1137
1138 UDFCloseFile__(Vcb, CfgFileInfo);
1139 }
1140 if(CfgFileInfo) {
1141 UDFCleanUpFile__(Vcb, CfgFileInfo);
1142 }
1143 MyFreePool__(LocalPath.Buffer);
1144 }
1145 RC = STATUS_SUCCESS;
1146
1147 // clear Modified flags. It was not real modify, just
1148 // bitmap construction
1149 Vcb->BitmapModified = FALSE;
1150 //Vcb->Modified = FALSE;
1153 // this is a part of UDF_RESIDUAL_REFERENCE
1154 UDFInterlockedIncrement((PLONG)&(Vcb->VCBOpenCount));
1155
1156 NtReqFcb = RootFcb->NTRequiredFCB;
1157
1158 // Start initializing the fields contained in the CommonFCBHeader.
1159 PtrCommonFCBHeader = &(NtReqFcb->CommonFCBHeader);
1160
1161 // DisAllow fast-IO for now.
1162// PtrCommonFCBHeader->IsFastIoPossible = FastIoIsNotPossible;
1163 PtrCommonFCBHeader->IsFastIoPossible = FastIoIsPossible;
1164
1165 // Initialize the MainResource and PagingIoResource pointers in
1166 // the CommonFCBHeader structure to point to the ERESOURCE structures we
1167 // have allocated and already initialized above.
1168// PtrCommonFCBHeader->Resource = &(NtReqFcb->MainResource);
1169// PtrCommonFCBHeader->PagingIoResource = &(NtReqFcb->PagingIoResource);
1170
1171 // Initialize the file size values here.
1172 PtrCommonFCBHeader->AllocationSize.QuadPart = 0;
1173 PtrCommonFCBHeader->FileSize.QuadPart = 0;
1174
1175 // The following will disable ValidDataLength support.
1176// PtrCommonFCBHeader->ValidDataLength.QuadPart = 0x7FFFFFFFFFFFFFFFI64;
1177 PtrCommonFCBHeader->ValidDataLength.QuadPart = 0;
1178
1179 if(!NT_SUCCESS(RC))
1180 return RC;
1181 UDFAssignAcl(Vcb, NULL, RootFcb, NtReqFcb);
1182/*
1183 Vcb->CDBurnerVolumeValid = true;
1184
1185 len =
1186 Vcb->CDBurnerVolume.Length = 256;
1187 Vcb->CDBurnerVolume.MaximumLength = 256;
1188 Vcb->CDBurnerVolume.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, 256);
1189 RC = RegTGetStringValue(NULL, REG_CD_BURNER_KEY_NAME, REG_CD_BURNER_VOLUME_NAME, Vcb->CDBurnerVolume.Buffer,
1190 len);
1191 Vcb->CDBurnerVolume.Length = (USHORT)(wcslen(Vcb->CDBurnerVolume.Buffer)*sizeof(WCHAR));
1192
1193 if(RC != STATUS_OBJECT_NAME_NOT_FOUND && !NT_SUCCESS(RC) )
1194 return RC;
1195
1196 if (NT_SUCCESS(RC)) {
1197 RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
1198 REG_CD_BURNER_KEY_NAME, REG_CD_BURNER_VOLUME_NAME,
1199 REG_SZ,L"",sizeof(L"")+1);
1200
1201 } else {
1202 Vcb->CDBurnerVolumeValid = false;
1203 RC = STATUS_SUCCESS;
1204 }
1205*/
1206 ASSERT(!Vcb->Modified);
1207
1208 return RC;
1209} // end UDFCompleteMount()
VOID UDFGetFileXTime(IN PUDF_FILE_INFO FileInfo, OUT LONGLONG *CrtTime, OUT LONGLONG *AccTime, OUT LONGLONG *AttrTime, OUT LONGLONG *ChgTime)
char int8
Definition: platform.h:10
NTSTATUS UDFInitializeFCB(IN PtrUDFFCB PtrNewFcb, IN PVCB Vcb, IN PtrUDFObjectName PtrObjectName, IN ULONG Flags, IN PFILE_OBJECT FileObject)
Definition: create.cpp:2517
PtrUDFObjectName UDFAllocateObjectName(VOID)
Definition: misc.cpp:611
PtrUDFFCB UDFAllocateFCB(VOID)
Definition: misc.cpp:854
#define DbgAllocatePoolWithTag(a, b, c)
Definition: env_spec_w32.h:333
NTSTATUS MyInitUnicodeString(IN PUNICODE_STRING Str1, IN PCWSTR Str2)
static unsigned char buff[32768]
Definition: fatten.c:17
#define DWN_MAX_CFG_FILE_SIZE
@ FastIoIsPossible
Definition: fsrtltypes.h:241
GLenum GLsizei len
Definition: glext.h:6722
VOID UDFPreClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:18
VOID UDFClrModified(IN PVCB Vcb)
Definition: misc_common.cpp:26
#define UDF_FN_NON_ALLOCATABLE_2
Definition: osta_misc.h:322
#define UDF_FN_NON_ALLOCATABLE
Definition: osta_misc.h:321
#define UDF_SN_UID_MAPPING
Definition: osta_misc.h:330
#define UDF_SN_NON_ALLOCATABLE
Definition: osta_misc.h:331
NTSTATUS UDFAssignAcl(IN PVCB Vcb, IN PFILE_OBJECT FileObject, IN PtrUDFFCB Fcb, IN PtrUDFNTRequiredFCB NtReqFcb)
Definition: secursup.cpp:706
uint8 FI_Flags
Definition: udf_rel.h:199
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
LARGE_INTEGER ValidDataLength
Definition: env_spec_w32.h:757
PtrUDFNTRequiredFCB NTRequiredFCB
Definition: struct.h:255
uint32 OpenHandleCount
Definition: struct.h:282
uint32 ReferenceCount
Definition: struct.h:281
PUDF_FILE_INFO FileInfo
Definition: struct.h:257
LARGE_INTEGER CreationTime
Definition: struct.h:210
LARGE_INTEGER LastWriteTime
Definition: struct.h:212
ULONG CommonRefCount
Definition: struct.h:218
LARGE_INTEGER LastAccessTime
Definition: struct.h:211
LARGE_INTEGER ChangeTime
Definition: struct.h:213
UNICODE_STRING ObjectName
Definition: struct.h:94
struct _UDFNTRequiredFCB * CommonFcb
Definition: udf_rel.h:255
#define max(a, b)
Definition: svc.c:63
int64 UDFGetFileSize(IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1236
OSSTATUS UDFOpenFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN BOOLEAN NotDeleted, IN PUNICODE_STRING fn, IN PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo, IN uint_di *IndexToOpen)
Definition: udf_info.cpp:2004
#define AS_USED
Definition: udf_info.h:327
#define UDFMarkSpaceAsXXX(Vcb, FileInfo, Map, asXXX)
Definition: udf_info.h:322
#define UDF_ROOTDIR_NAME
Definition: udf_reg.h:48
#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 EXTENT_FLAG_VERIFY
Definition: udf_rel.h:81
struct _UDF_FILE_INFO * PUDF_FILE_INFO
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define UDF_CONFIG_STREAM_NAME_W
Definition: udfpubl.h:82

Referenced by UDFMountVolume().

◆ UDFCreate()

NTSTATUS NTAPI UDFCreate ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

◆ UDFDeassignAcl()

VOID UDFDeassignAcl ( IN PtrUDFNTRequiredFCB  NtReqFcb,
IN BOOLEAN  AutoInherited 
)

Definition at line 772 of file secursup.cpp.

776{
777#ifdef UDF_ENABLE_SECURITY
778// NTSTATUS RC = STATUS_SUCCESS;
779
780// UDFPrint((" UDFDeassignAcl\n"));
781 if(!NtReqFcb->SecurityDesc)
782 return;
783
784 if(AutoInherited) {
785 NtReqFcb->SecurityDesc = NULL;
786 return;
787 }
788
789 SeDeassignSecurity(&(NtReqFcb->SecurityDesc));
790 NtReqFcb->SecurityDesc = NULL; // HA BCRK CLU4
791#endif //UDF_ENABLE_SECURITY
792 return;
793} // end UDFDeassignAcl()

Referenced by UDFCleanUpFcbChain(), and UDFSetAccessRights().

◆ UDFDebugAcquireResourceExclusiveLite()

BOOLEAN UDFDebugAcquireResourceExclusiveLite ( IN PERESOURCE  Resource,
IN BOOLEAN  Wait,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugAcquireResourceSharedLite()

BOOLEAN UDFDebugAcquireResourceSharedLite ( IN PERESOURCE  Resource,
IN BOOLEAN  Wait,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugAcquireSharedStarveExclusive()

BOOLEAN UDFDebugAcquireSharedStarveExclusive ( IN PERESOURCE  Resource,
IN BOOLEAN  Wait,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugAcquireSharedWaitForExclusive()

BOOLEAN UDFDebugAcquireSharedWaitForExclusive ( IN PERESOURCE  Resource,
IN BOOLEAN  Wait,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugConvertExclusiveToSharedLite()

VOID UDFDebugConvertExclusiveToSharedLite ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  ResourceThreadId,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugDeleteResource()

VOID UDFDebugDeleteResource ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  ResourceThreadId,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugInitializeResourceLite()

NTSTATUS UDFDebugInitializeResourceLite ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  ResourceThreadId,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugInterlockedDecrement()

LONG UDFDebugInterlockedDecrement ( IN PLONG  addr,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugInterlockedExchangeAdd()

LONG UDFDebugInterlockedExchangeAdd ( IN PLONG  addr,
IN LONG  i,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugInterlockedIncrement()

LONG UDFDebugInterlockedIncrement ( IN PLONG  addr,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDebugReleaseResourceForThreadLite()

VOID UDFDebugReleaseResourceForThreadLite ( IN PERESOURCE  Resource,
IN ERESOURCE_THREAD  ResourceThreadId,
ULONG  BugCheckId,
ULONG  Line 
)

◆ UDFDeferredWriteCallBack()

VOID NTAPI UDFDeferredWriteCallBack ( VOID Context1,
VOID Context2 
)

◆ UDFDelayedClose()

VOID NTAPI UDFDelayedClose ( PVOID  unused = NULL)

Definition at line 690 of file close.cpp.

693{
695 PtrUDFIrpContextLite NextIrpContextLite;
696
697 AdPrint((" UDFDelayedClose\n"));
698 // Acquire DelayedCloseResource
699 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
700
701 while (UDFGlobalData.ReduceDelayedClose &&
702 (UDFGlobalData.DelayedCloseCount > UDFGlobalData.MinDelayedCloseCount)) {
703
704 Entry = UDFGlobalData.DelayedCloseQueue.Flink;
705
706 if (!IsListEmpty(Entry)) {
707 // Extract the IrpContext.
708 NextIrpContextLite = CONTAINING_RECORD( Entry,
710 DelayedCloseLinks );
711
713 UDFGlobalData.DelayedCloseCount--;
714 UDFDoDelayedClose(NextIrpContextLite);
715 } else {
716 BrutePoint();
717 }
718 }
719
720 while (UDFGlobalData.ReduceDirDelayedClose &&
721 (UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MinDirDelayedCloseCount)) {
722
723 Entry = UDFGlobalData.DirDelayedCloseQueue.Flink;
724
725 if (!IsListEmpty(Entry)) {
726 // Extract the IrpContext.
727 NextIrpContextLite = CONTAINING_RECORD( Entry,
729 DelayedCloseLinks );
730
732 UDFGlobalData.DirDelayedCloseCount--;
733 UDFDoDelayedClose(NextIrpContextLite);
734 } else {
735 BrutePoint();
736 }
737 }
738
739 UDFGlobalData.FspCloseActive = FALSE;
740 UDFGlobalData.ReduceDelayedClose = FALSE;
741 UDFGlobalData.ReduceDirDelayedClose = FALSE;
742
743 // Release DelayedCloseResource
744 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
745
746 return;
747} // end UDFDelayedClose()
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
base of all file and directory entries
Definition: entries.h:83

Referenced by DriverEntry().

◆ UDFDestroyZones()

VOID UDFDestroyZones ( VOID  )

Definition at line 177 of file misc.cpp.

178{
179// BrutePoint();
180
181 _SEH2_TRY {
182 // free up each of the pools
183 if(UDFGlobalData.ObjectNameZone) {
184 DbgFreePool(UDFGlobalData.ObjectNameZone);
185 UDFGlobalData.ObjectNameZone = NULL;
186 }
187 if(UDFGlobalData.CCBZone) {
188 DbgFreePool(UDFGlobalData.CCBZone);
189 UDFGlobalData.CCBZone = NULL;
190 }
191 if(UDFGlobalData.IrpContextZone) {
192 DbgFreePool(UDFGlobalData.IrpContextZone);
193 UDFGlobalData.IrpContextZone = NULL;
194 }
195
196//try_exit: NOTHING;
197
198 } _SEH2_FINALLY {
199 UDFGlobalData.UDFFlags &= ~UDF_DATA_FLAGS_ZONES_INITIALIZED;
200 } _SEH2_END;
201
202 return;
203}

Referenced by DriverEntry(), UDFCommonDeviceControl(), and UDFInitializeZones().

◆ UDFDeviceControl()

NTSTATUS NTAPI UDFDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 81 of file devcntrl.cpp.

84{
86 PtrUDFIrpContext PtrIrpContext = NULL;
87 BOOLEAN AreWeTopLevel = FALSE;
88
89 TmPrint(("UDFDeviceControl: \n"));
90
93 ASSERT(Irp);
94
95 // set the top level context
96 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
97 //ASSERT(!UDFIsFSDevObj(DeviceObject));
98
99 _SEH2_TRY {
100
101 // get an IRP context structure and issue the request
102 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
103 if(PtrIrpContext) {
104 RC = UDFCommonDeviceControl(PtrIrpContext, Irp);
105 } else {
107 Irp->IoStatus.Status = RC;
108 Irp->IoStatus.Information = 0;
109 // complete the IRP
111 }
112
114
115 RC = UDFExceptionHandler(PtrIrpContext, Irp);
116
118 } _SEH2_END;
119
120 if (AreWeTopLevel) {
122 }
123
125
126 return(RC);
127} // end UDFDeviceControl()
NTSTATUS NTAPI UDFCommonDeviceControl(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: devcntrl.cpp:149

Referenced by UDFInitializeFunctionPointers().

◆ UDFDevIoctlCompletion()

NTSTATUS NTAPI UDFDevIoctlCompletion ( PDEVICE_OBJECT  PtrDeviceObject,
PIRP  Irp,
PVOID  Context 
)

◆ UDFDirControl()

NTSTATUS NTAPI UDFDirControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 57 of file dircntrl.cpp.

61{
63 PtrUDFIrpContext PtrIrpContext = NULL;
64 BOOLEAN AreWeTopLevel = FALSE;
65
66 TmPrint(("UDFDirControl: \n"));
67
70 ASSERT(Irp);
71
72 // set the top level context
73 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
74 ASSERT(!UDFIsFSDevObj(DeviceObject));
75
76 _SEH2_TRY {
77
78 // get an IRP context structure and issue the request
79 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
80 if(PtrIrpContext) {
81 RC = UDFCommonDirControl(PtrIrpContext, Irp);
82 } else {
84 Irp->IoStatus.Status = RC;
85 Irp->IoStatus.Information = 0;
86 // complete the IRP
88 }
89
91
92 RC = UDFExceptionHandler(PtrIrpContext, Irp);
93
95 } _SEH2_END;
96
97 if (AreWeTopLevel) {
99 }
100
102
103 return(RC);
104} // end UDFDirControl()
NTSTATUS NTAPI UDFCommonDirControl(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: dircntrl.cpp:127

Referenced by UDFInitializeFunctionPointers().

◆ UDFDismountVcb()

BOOLEAN UDFDismountVcb ( IN PVCB  Vcb,
IN BOOLEAN  VcbAcquired 
)

Definition at line 727 of file verfysup.cpp.

731{
732
733 PVPB OldVpb;
734 PVPB NewVpb;
735 BOOLEAN VcbPresent = TRUE;
736 KIRQL SavedIrql;
737
738 BOOLEAN FinalReference;
739
740 UDFPrint(("UDFDismountVcb:\n"));
741 // We should only take this path once.
742 ASSERT( !(Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) );
743
744 // Mark the Vcb as DismountInProgress.
746
747 // Allocate a new Vpb in case we will need it.
748 NewVpb = (PVPB)DbgAllocatePoolWithTag( NonPagedPool, sizeof( VPB ), 'bpvU' );
749 if(!NewVpb) {
750 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_BEING_DISMOUNTED;
751 return TRUE;
752 }
753
754 RtlZeroMemory( NewVpb, sizeof(VPB) );
755
756 OldVpb = Vcb->Vpb;
757
758 // Remove the mount volume reference.
760 // the only residual reference is cleaned above
761
762 // Acquire the Vpb spinlock to check for Vpb references.
763 IoAcquireVpbSpinLock(&SavedIrql);
764
765 // Remember if this is the last reference on this Vcb. We incremented
766 // the count on the Vpb earlier so we get one last crack it. If our
767 // reference has gone to zero but the vpb reference count is greater
768 // than zero then the Io system will be responsible for deleting the
769 // Vpb.
770 FinalReference = (BOOLEAN)(OldVpb->ReferenceCount == 1);
771
772 // There is a reference count in the Vpb and in the Vcb. We have
773 // incremented the reference count in the Vpb to make sure that
774 // we have last crack at it. If this is a failed mount then we
775 // want to return the Vpb to the IO system to use for the next
776 // mount request.
777 if (OldVpb->RealDevice->Vpb == OldVpb) {
778
779 // If not the final reference then swap out the Vpb.
780 if (!FinalReference) {
781
782 NewVpb->Type = IO_TYPE_VPB;
783 NewVpb->Size = sizeof( VPB );
784 NewVpb->RealDevice = OldVpb->RealDevice;
785
786 NewVpb->RealDevice->Vpb = NewVpb;
787
788 NewVpb = NULL;
789 IoReleaseVpbSpinLock(SavedIrql);
790 // We want to leave the Vpb for the IO system. Mark it
791 // as being not mounted. Go ahead and delete the Vcb as
792 // well.
793 } else {
794
795 // Make sure to remove the last reference on the Vpb.
796
797 OldVpb->ReferenceCount--;
798
799 OldVpb->DeviceObject = NULL;
800 Vcb->Vpb->Flags &= ~VPB_MOUNTED;
801
802 // Clear the Vpb flag so we know not to delete it.
803 Vcb->Vpb = NULL;
804
805 IoReleaseVpbSpinLock(SavedIrql);
806 if(VcbAcquired)
807 UDFReleaseResource(&(Vcb->VCBResource));
810 VcbPresent = FALSE;
811 }
812
813 // Someone has already swapped in a new Vpb. If this is the final reference
814 // then the file system is responsible for deleting the Vpb.
815 } else if (FinalReference) {
816
817 // Make sure to remove the last reference on the Vpb.
818 OldVpb->ReferenceCount--;
819
820 IoReleaseVpbSpinLock( SavedIrql );
821 if(VcbAcquired)
822 UDFReleaseResource(&(Vcb->VCBResource));
825 VcbPresent = FALSE;
826
827 // The current Vpb is no longer the Vpb for the device (the IO system
828 // has already allocated a new one). We leave our reference in the
829 // Vpb and will be responsible for deleting it at a later time.
830 } else {
831
832 OldVpb->DeviceObject = NULL;
833 Vcb->Vpb->Flags &= ~VPB_MOUNTED;
834
835 IoReleaseVpbSpinLock( SavedIrql );
836 }
837
838 // Deallocate the new Vpb if we don't need it.
839 if (NewVpb != NULL) {
840 DbgFreePool( NewVpb );
841 }
842
843 // Let our caller know whether the Vcb is still present.
844 return VcbPresent;
845} // end UDFDismountVcb()
VOID UDFCloseResidual(IN PVCB Vcb)
Definition: fscntrl.cpp:1349
#define BOOLEAN
Definition: pedump.c:73
Definition: iotypes.h:189
CSHORT Type
Definition: iotypes.h:190
CSHORT Size
Definition: iotypes.h:191
struct _DEVICE_OBJECT * DeviceObject
Definition: iotypes.h:194
ULONG ReferenceCount
Definition: iotypes.h:197
struct _DEVICE_OBJECT * RealDevice
Definition: iotypes.h:195
struct _VPB * PVPB
#define IO_TYPE_VPB
struct _VPB VPB

Referenced by UDFCheckForDismount(), and UDFMountVolume().

◆ UDFDismountVolume()

NTSTATUS UDFDismountVolume ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) ||

Definition at line 1942 of file fscntrl.cpp.

1946{
1947 NTSTATUS RC;
1948
1950
1951 PVCB Vcb;
1952 PtrUDFFCB Fcb;
1953 PtrUDFCCB Ccb;
1955 BOOLEAN VcbAcquired = FALSE;
1956
1957 UDFPrint(("\n ### UDFDismountVolume ###\n\n"));
1958
1959 // Decode the file object, the only type of opens we accept are
1960 // user volume opens.
1961 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1962 if(!Ccb) {
1963 UDFPrintErr((" !Ccb\n"));
1964 Irp->IoStatus.Information = 0;
1965 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1967 }
1968 Fcb = Ccb->Fcb;
1969 Vcb = Fcb->Vcb;
1970
1971 // Check for volume open
1972 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1973 Irp->IoStatus.Information = 0;
1974 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1976 }
1977
1979
1980 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
1981 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
1982#ifdef UDF_DELAYED_CLOSE
1984#endif //UDF_DELAYED_CLOSE
1985
1986 // Acquire exclusive access to the Vcb.
1987 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1988 VcbAcquired = TRUE;
1989
1990 _SEH2_TRY {
1991
1992 // Mark the volume as needs to be verified, but only do it if
1993 // the vcb is locked by this handle and the volume is currently mounted.
1994
1995 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
1996 // disable Eject Request Waiter if any
1997 UDFReleaseResource( &(Vcb->VCBResource) );
1998 VcbAcquired = FALSE;
1999
2001 RC = STATUS_SUCCESS;
2002 } else
2003 if(
2004 !(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) ||
2005 (Vcb->VCBOpenCount > (UDF_RESIDUAL_REFERENCE+1))) {
2006
2007 RC = STATUS_NOT_LOCKED;
2008 } else
2009 if((Vcb->VolumeLockFileObject != IrpSp->FileObject)) {
2010
2012
2013 } else {
2014
2015 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
2019 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
2020 Vcb->WriteSecurity = FALSE;
2021 // disable Eject Request Waiter if any
2022 UDFReleaseResource( &(Vcb->VCBResource) );
2023 VcbAcquired = FALSE;
2024
2026 RC = STATUS_SUCCESS;
2027 }
2028try_exit: NOTHING;
2029 } _SEH2_FINALLY {
2030 // Free memory
2031 if(Buf) MyFreePool__(Buf);
2032 // Release all of our resources
2033 if(VcbAcquired)
2034 UDFReleaseResource( &(Vcb->VCBResource) );
2035 } _SEH2_END;
2036
2037 if(!NT_SUCCESS(RC)) {
2039 }
2040
2041 // Complete the request if there haven't been any exceptions.
2042 Irp->IoStatus.Information = 0;
2043 Irp->IoStatus.Status = RC;
2044 return RC;
2045} // end UDFDismountVolume()
#define FSRTL_VOLUME_DISMOUNT_FAILED
Definition: ntifs_ex.h:440
#define FSRTL_VOLUME_DISMOUNT
Definition: ntifs_ex.h:439
#define STATUS_NOT_LOCKED
Definition: ntstatus.h:279

Referenced by UDFUserFsCtrlRequest().

◆ UDFDriverUnload()

VOID NTAPI UDFDriverUnload ( IN PDRIVER_OBJECT  DriverObject)

Definition at line 10 of file unload.cpp.

13{
14// UNICODE_STRING uniWin32NameString;
15 LARGE_INTEGER delay;
16
17 //
18 // All *THIS* driver needs to do is to delete the device object and the
19 // symbolic link between our device name and the Win32 visible name.
20 //
21 // Almost every other driver ever written would need to do a
22 // significant amount of work here deallocating stuff.
23 //
24
25 UDFPrint( ("UDF: Unloading!!\n") );
26
27 // prevent mount oparations
29
30 // wait for all volumes to be dismounted
31 delay.QuadPart = 10*1000*1000*10;
32 while(TRUE) {
33 UDFPrint(("Poll...\n"));
35 }
36
37 // Create counted string version of our Win32 device name.
38
39
40// RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
41
42
43 // Delete the link from our device name to a name in the Win32 namespace.
44
45
46// IoDeleteSymbolicLink( &uniWin32NameString );
47
48
49 // Finally delete our device object
50
51
52// IoDeleteDevice( DriverObject->DeviceObject );
53}

Referenced by UDFInitializeFunctionPointers().

◆ UDFExceptionFilter()

long UDFExceptionFilter ( PtrUDFIrpContext  PtrIrpContext,
PEXCEPTION_POINTERS  PtrExceptionPointers 
)

Definition at line 265 of file misc.cpp.

269{
270 long ReturnCode = EXCEPTION_EXECUTE_HANDLER;
272#if defined UDF_DBG || defined PRINT_ALWAYS
273 ULONG i;
274
275 UDFPrint(("UDFExceptionFilter\n"));
276 UDFPrint((" Ex. Code: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionCode));
277 UDFPrint((" Ex. Addr: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionAddress));
278 UDFPrint((" Ex. Flag: %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionFlags));
279 UDFPrint((" Ex. Pnum: %x\n",PtrExceptionPointers->ExceptionRecord->NumberParameters));
280 for(i=0;i<PtrExceptionPointers->ExceptionRecord->NumberParameters;i++) {
281 UDFPrint((" %x\n",PtrExceptionPointers->ExceptionRecord->ExceptionInformation[i]));
282 }
283#ifdef _X86_
284 UDFPrint(("Exception context:\n"));
285 if(PtrExceptionPointers->ContextRecord->ContextFlags & CONTEXT_INTEGER) {
286 UDFPrint(("EAX=%8.8x ",PtrExceptionPointers->ContextRecord->Eax));
287 UDFPrint(("EBX=%8.8x ",PtrExceptionPointers->ContextRecord->Ebx));
288 UDFPrint(("ECX=%8.8x ",PtrExceptionPointers->ContextRecord->Ecx));
289 UDFPrint(("EDX=%8.8x\n",PtrExceptionPointers->ContextRecord->Edx));
290
291 UDFPrint(("ESI=%8.8x ",PtrExceptionPointers->ContextRecord->Esi));
292 UDFPrint(("EDI=%8.8x ",PtrExceptionPointers->ContextRecord->Edi));
293 }
294 if(PtrExceptionPointers->ContextRecord->ContextFlags & CONTEXT_CONTROL) {
295 UDFPrint(("EBP=%8.8x ",PtrExceptionPointers->ContextRecord->Esp));
296 UDFPrint(("ESP=%8.8x\n",PtrExceptionPointers->ContextRecord->Ebp));
297
298 UDFPrint(("EIP=%8.8x\n",PtrExceptionPointers->ContextRecord->Eip));
299 }
300// UDFPrint(("Flags: %s %s ",PtrExceptionPointers->ContextRecord->Eip));
301#endif //_X86_
302
303#endif // UDF_DBG
304
305 // figure out the exception code
306 ExceptionCode = PtrExceptionPointers->ExceptionRecord->ExceptionCode;
307
308 if ((ExceptionCode == STATUS_IN_PAGE_ERROR) && (PtrExceptionPointers->ExceptionRecord->NumberParameters >= 3)) {
309 ExceptionCode = PtrExceptionPointers->ExceptionRecord->ExceptionInformation[2];
310 }
311
312 if (PtrIrpContext) {
313 PtrIrpContext->SavedExceptionCode = ExceptionCode;
315 }
316
317 // check if we should propagate this exception or not
319
320 // better free up the IrpContext now ...
321 if (PtrIrpContext) {
322 UDFPrint((" UDF Driver internal error\n"));
323 BrutePoint();
324 } else {
325 // we are not ok, propagate this exception.
326 // NOTE: we will bring down the machine ...
327 ReturnCode = EXCEPTION_CONTINUE_SEARCH;
328 }
329 }
330
331
332 // return the appropriate code
333 return(ReturnCode);
334} // end UDFExceptionFilter()
_Inout_ PIRP _In_ NTSTATUS ExceptionCode
Definition: cdprocs.h:1774
#define EXCEPTION_CONTINUE_SEARCH
Definition: excpt.h:86
#define CONTEXT_CONTROL
Definition: nt_native.h:1369
#define CONTEXT_INTEGER
Definition: nt_native.h:1370
BOOLEAN NTAPI FsRtlIsNtstatusExpected(IN NTSTATUS NtStatus)
Definition: filter.c:61
#define STATUS_IN_PAGE_ERROR
Definition: ntstatus.h:243
#define UDF_IRP_CONTEXT_EXCEPTION
Definition: struct.h:387
ULONG Esp
Definition: nt_native.h:1479
ULONG Edx
Definition: nt_native.h:1466
ULONG Esi
Definition: nt_native.h:1464
ULONG Ebp
Definition: nt_native.h:1475
ULONG ContextFlags
Definition: nt_native.h:1426
ULONG Ecx
Definition: nt_native.h:1467
ULONG Eip
Definition: nt_native.h:1476
ULONG Eax
Definition: nt_native.h:1468
ULONG Ebx
Definition: nt_native.h:1465
ULONG Edi
Definition: nt_native.h:1463
PEXCEPTION_RECORD ExceptionRecord
Definition: rtltypes.h:200
PCONTEXT ContextRecord
Definition: rtltypes.h:201
DWORD ExceptionCode
Definition: compat.h:208
DWORD NumberParameters
Definition: compat.h:212
DWORD ExceptionFlags
Definition: compat.h:209
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]
Definition: compat.h:213
PVOID ExceptionAddress
Definition: compat.h:211
NTSTATUS SavedExceptionCode
Definition: struct.h:376

Referenced by UDFCleanup(), UDFClose(), UDFCommonDispatch(), UDFCreate(), UDFDeviceControl(), UDFDirControl(), UDFFastIoQueryBasicInfo(), UDFFastIoQueryStdInfo(), UDFFileInfo(), UDFFlush(), UDFFSControl(), UDFGetVolumeBitmap(), UDFLockControl(), UDFPerformVerify(), UDFPnp(), UDFQueryVolInfo(), UDFRead(), UDFSetVolInfo(), UDFShutdown(), UDFStackOverflowRead(), and UDFWrite().

◆ UDFExceptionHandler()

NTSTATUS UDFExceptionHandler ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 358 of file misc.cpp.

362{
363// NTSTATUS RC;
366 PVPB Vpb;
368
369 UDFPrint(("UDFExceptionHandler \n"));
370
371// ASSERT(Irp);
372
373 if (!Irp) {
374 UDFPrint((" !Irp, return\n"));
375 ASSERT(!PtrIrpContext);
376 return ExceptionCode;
377 }
378 // If it was a queued close (or something like this) then we need not
379 // completing it because of MUST_SUCCEED requirement.
380
381 if (PtrIrpContext) {
382 ExceptionCode = PtrIrpContext->SavedExceptionCode;
383 // Free irp context here
384// UDFReleaseIrpContext(PtrIrpContext);
385 } else {
386 UDFPrint((" complete Irp and return\n"));
387 // must be insufficient resources ...?
389 Irp->IoStatus.Status = ExceptionCode;
391 // complete the IRP
393
394 return ExceptionCode;
395 }
396
397 // Check if we are posting this request. One of the following must be true
398 // if we are to post a request.
399 //
400 // - Status code is STATUS_CANT_WAIT and the request is asynchronous
401 // or we are forcing this to be posted.
402 //
403 // - Status code is STATUS_VERIFY_REQUIRED and we are at APC level
404 // or higher. Can't wait for IO in the verify path in this case.
405 //
406 // Set the MORE_PROCESSING flag in the IrpContext to keep if from being
407 // deleted if this is a retryable condition.
408
410 if (KeGetCurrentIrql() >= APC_LEVEL) {
411 UDFPrint((" use UDFPostRequest()\n"));
412 ExceptionCode = UDFPostRequest( PtrIrpContext, Irp );
413 }
414 }
415
416 // If we posted the request or our caller will retry then just return here.
417 if ((ExceptionCode == STATUS_PENDING) ||
419
420 UDFPrint((" STATUS_PENDING/STATUS_CANT_WAIT, return\n"));
421 return ExceptionCode;
422 }
423
424 // Store this error into the Irp for posting back to the Io system.
427
428 // Check for the various error conditions that can be caused by,
429 // and possibly resolved my the user.
431
432 // Now we are at the top level file system entry point.
433 //
434 // If we have already posted this request then the device to
435 // verify is in the original thread. Find this via the Irp.
436 Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread );
437 IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL );
438
439 // If there is no device in that location then check in the
440 // current thread.
441 if (Device == NULL) {
442
445
446 ASSERT( Device != NULL );
447
448 // Let's not BugCheck just because the driver screwed up.
449 if (Device == NULL) {
450
451 UDFPrint((" Device == NULL, return\n"));
453 Irp->IoStatus.Status = ExceptionCode;
455 // complete the IRP
457
458 UDFReleaseIrpContext(PtrIrpContext);
459
460 return ExceptionCode;
461 }
462 }
463
464 UDFPrint((" use UDFPerformVerify()\n"));
465 // UDFPerformVerify() will do the right thing with the Irp.
466 // If we return STATUS_CANT_WAIT then the current thread
467 // can retry the request.
468 return UDFPerformVerify( PtrIrpContext, Irp, Device );
469 }
470
471 //
472 // The other user induced conditions generate an error unless
473 // they have been disabled for this request.
474 //
475
477
478 UDFPrint((" DISABLE_POPUPS, complete Irp and return\n"));
479 Irp->IoStatus.Status = ExceptionCode;
481 // complete the IRP
483
484 UDFReleaseIrpContext(PtrIrpContext);
485 return ExceptionCode;
486 } else {
487
488 // Generate a pop-up
490
492 } else {
493
494 Vpb = NULL;
495 }
496 // The device to verify is either in my thread local storage
497 // or that of the thread that owns the Irp.
498 Thread = Irp->Tail.Overlay.Thread;
500
501 if (Device == NULL) {
502
505 ASSERT( Device != NULL );
506
507 // Let's not BugCheck just because the driver screwed up.
508 if (Device == NULL) {
509 UDFPrint((" Device == NULL, return(2)\n"));
510 Irp->IoStatus.Status = ExceptionCode;
512 // complete the IRP
514
515 UDFReleaseIrpContext(PtrIrpContext);
516
517 return ExceptionCode;
518 }
519 }
520
521 // This routine actually causes the pop-up. It usually
522 // does this by queuing an APC to the callers thread,
523 // but in some cases it will complete the request immediately,
524 // so it is very important to IoMarkIrpPending() first.
527
528 // We will be handing control back to the caller here, so
529 // reset the saved device object.
530
531 UDFPrint((" use IoSetDeviceToVerify()\n"));
533 // The Irp will be completed by Io or resubmitted. In either
534 // case we must clean up the IrpContext here.
535
536 UDFReleaseIrpContext(PtrIrpContext);
537 return STATUS_PENDING;
538 }
539 }
540
541 // If it was a normal request from IOManager then complete it
542 if (Irp) {
543 UDFPrint((" complete Irp\n"));
544 // set the error code in the IRP
545 Irp->IoStatus.Status = ExceptionCode;
547
548 // complete the IRP
550
551 UDFReleaseIrpContext(PtrIrpContext);
552 }
553
554 UDFPrint((" return from exception handler with code %x\n", ExceptionCode));
555 return(ExceptionCode);
556} // end UDFExceptionHandler()
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
IN OUT PVCB IN PDEVICE_OBJECT IN PVPB Vpb
Definition: fatprocs.h:1675
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
IoMarkIrpPending(Irp)
VOID NTAPI IoRaiseHardError(IN PIRP Irp, IN PVPB Vpb, IN PDEVICE_OBJECT RealDeviceObject)
Definition: error.c:664
VOID NTAPI IoSetDeviceToVerify(IN PETHREAD Thread, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:304
PDEVICE_OBJECT NTAPI IoGetDeviceToVerify(IN PETHREAD Thread)
Definition: util.c:336
#define STATUS_CANT_WAIT
Definition: ntstatus.h:452
NTSTATUS UDFPerformVerify(IN PtrUDFIrpContext IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
Definition: verfysup.cpp:472
#define UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS
Definition: struct.h:391
IO_STATUS_BLOCK IoStatus
#define STATUS_DRIVER_INTERNAL_ERROR
Definition: udferr_usr.h:177
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
_Must_inspect_result_ _In_ WDFDEVICE Device
Definition: wdfchildlist.h:474
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817

Referenced by UDFCleanup(), UDFClose(), UDFCommonDispatch(), UDFCreate(), UDFDeviceControl(), UDFDirControl(), UDFFastIoQueryBasicInfo(), UDFFastIoQueryStdInfo(), UDFFileInfo(), UDFFlush(), UDFFSControl(), UDFLockControl(), UDFPerformVerify(), UDFPnp(), UDFQueryVolInfo(), UDFRead(), UDFSetVolInfo(), UDFShutdown(), UDFStackOverflowRead(), and UDFWrite().

◆ UDFFastIoAcqCreateSec()

VOID NTAPI UDFFastIoAcqCreateSec ( IN PFILE_OBJECT  FileObject)

Definition at line 342 of file fastio.cpp.

345{
347
348 MmPrint((" AcqForCreateSection()\n"));
349 // Acquire the MainResource exclusively for the file stream
350 if(!ExIsResourceAcquiredExclusiveLite(&(NtReqFcb->MainResource)) ||
351 !ExIsResourceAcquiredExclusiveLite(&(NtReqFcb->PagingIoResource)) ) {
353 } else {
354 MmPrint((" already acquired\n"));
355 }
356 UDFAcquireResourceExclusive(&(NtReqFcb->MainResource), TRUE);
357
358 // Although this is typically not required, the UDF FSD will
359 // also acquire the PagingIoResource exclusively at this time
360 // to conform with the resource acquisition described in the set
361 // file information routine. Once again though, we will probably
362 // not need to do this.
363 UDFAcquireResourceExclusive(&(NtReqFcb->PagingIoResource), TRUE);
364 NtReqFcb->AcqSectionCount++;
365
366 return;
367} // end UDFFastIoAcqCreateSec()

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastIoCheckIfPossible()

BOOLEAN NTAPI UDFFastIoCheckIfPossible ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
IN BOOLEAN  CheckForReadOperation,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 42 of file fastio.cpp.

52{
53 BOOLEAN ReturnedStatus = FALSE;
56 LARGE_INTEGER IoLength;
57
58 // Obtain a pointer to the FCB and CCB for the file stream.
59 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
60 ASSERT(Ccb);
61 Fcb = Ccb->Fcb;
62 ASSERT(Fcb);
63
64 // Validate that this is a fast-IO request to a regular file.
65 // The UDF FSD for example, will not allow fast-IO requests
66 // to volume objects, or to directories.
67 if ((Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
68 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
69 // This is not allowed.
71 MmPrint((" UDFFastIoCheckIfPossible() TRUE, Failed\n"));
72 return FALSE;
73 }
74/*
75 // back pressure for very smart and fast system cache ;)
76 if(Fcb->Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
77 AdPrint((" Verify queue overflow -> UDFFastIoCheckIfPossible() = FALSE\n"));
78 return FALSE;
79 }
80*/
81 IoLength.QuadPart = Length;
82
83 // The FSD can determine the checks that it needs to perform.
84 // Typically, a FSD will check whether there exist any byte-range
85 // locks that would prevent a fast-IO operation from proceeding.
86
87 // ... (FSD specific checks go here).
88
90 // The following routine is exported by the FSRTL
91 // package and it returns TRUE if the read operation should be
92 // allowed to proceed based on the status of the current byte-range
93 // locks on the file stream. If we do not use the FSRTL package
94 // for byte-range locking support, then we must substitute our
95 // own checks over here.
96 ReturnedStatus = FsRtlFastCheckLockForRead(&(Fcb->NTRequiredFCB->FileLock),
97 FileOffset, &IoLength, LockKey, FileObject,
99 } else {
100// if(Fcb->Vcb->VCBFlags );
101 // This is a write request. Invoke the FSRTL byte-range lock package
102 // to see whether the write should be allowed to proceed.
103 ReturnedStatus = FsRtlFastCheckLockForWrite(&(Fcb->NTRequiredFCB->FileLock),
104 FileOffset, &IoLength, LockKey, FileObject,
106 }
107
108 MmPrint((" UDFFastIoCheckIfPossible() %s\n", ReturnedStatus ? "TRUE" : "FALSE"));
109 return(ReturnedStatus);
110// return FALSE;
111
112} // end UDFFastIoCheckIfPossible()
_In_ PFCB _In_ LONGLONG FileOffset
Definition: cdprocs.h:160
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG LockKey
Definition: fatprocs.h:2665
IN PLARGE_INTEGER IN ULONG IN BOOLEAN IN ULONG IN BOOLEAN CheckForReadOperation
Definition: fatprocs.h:2666
BOOLEAN NTAPI FsRtlFastCheckLockForWrite(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:782
BOOLEAN NTAPI FsRtlFastCheckLockForRead(IN PFILE_LOCK FileLock, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID Process)
Definition: filelock.c:748
FILE_LOCK FileLock
Definition: fatstruc.h:1071
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastIoQueryBasicInfo()

BOOLEAN NTAPI UDFFastIoQueryBasicInfo ( IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Wait,
OUT PFILE_BASIC_INFORMATION  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 159 of file fastio.cpp.

166{
167 BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
169 PtrUDFIrpContext PtrIrpContext = NULL;
174 BOOLEAN MainResourceAcquired = FALSE;
175
177
178 UDFPrint(("UDFFastIo \n"));
179 // if the file is already opended we can satisfy this request
180 // immediately 'cause all the data we need must be cached
181 _SEH2_TRY {
182
183 _SEH2_TRY {
184
185 // Get the FCB and CCB pointers.
186 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
187 ASSERT(Ccb);
188 Fcb = Ccb->Fcb;
189 ASSERT(Fcb);
190 NtReqFcb = Fcb->NTRequiredFCB;
191 //Fcb->Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
192
193 if (!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
194 // Acquire the MainResource shared.
196 if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait)) {
198 }
199 MainResourceAcquired = TRUE;
200 }
201
202 ReturnedStatus =
204
206
207 RC = UDFExceptionHandler(PtrIrpContext, NULL);
208
210
211 } _SEH2_END;
212try_exit: NOTHING;
213 } _SEH2_FINALLY {
214 if (MainResourceAcquired) {
216 UDFReleaseResource(&(NtReqFcb->MainResource));
217 MainResourceAcquired = FALSE;
218 }
219 IoStatus->Status = RC;
220 if(ReturnedStatus) {
221 IoStatus->Information = sizeof(FILE_BASIC_INFORMATION);
222 } else {
223 IoStatus->Information = 0;
224 }
225 } _SEH2_END;
226
228
229 return(ReturnedStatus);
230} // end UDFFastIoQueryBasicInfo()
Definition: bufpool.h:45
#define FILE_BASIC_INFORMATION
Definition: disk.h:53

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastIoQueryStdInfo()

BOOLEAN NTAPI UDFFastIoQueryStdInfo ( IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Wait,
OUT PFILE_STANDARD_INFORMATION  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 250 of file fastio.cpp.

256{
257 BOOLEAN ReturnedStatus = FALSE; // fast i/o failed/not allowed
259 PtrUDFIrpContext PtrIrpContext = NULL;
263// PtrUDFNTRequiredFCB NtReqFcb = NULL;
264// BOOLEAN MainResourceAcquired = FALSE;
265
267
268 UDFPrint(("UDFFastIo \n"));
269 // if the file is already opended we can satisfy this request
270 // immediately 'cause all the data we need must be cached
271 _SEH2_TRY {
272
273 _SEH2_TRY {
274
275 // Get the FCB and CCB pointers.
276 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
277 ASSERT(Ccb);
278 Fcb = Ccb->Fcb;
279 ASSERT(Fcb);
280// NtReqFcb = Fcb->NTRequiredFCB;
281 //Fcb->Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
282
283/*
284 if (!(Fcb->FCBFlags & UDF_FCB_PAGE_FILE)) {
285 // Acquire the MainResource shared.
286 UDF_CHECK_PAGING_IO_RESOURCE(NtReqFcb);
287 if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), Wait)) {
288 try_return(RC = STATUS_CANT_WAIT);
289 }
290 MainResourceAcquired = TRUE;
291 }
292*/
293 ReturnedStatus =
295
297
298 RC = UDFExceptionHandler(PtrIrpContext, NULL);
299
301
302 } _SEH2_END;
303//try_exit: NOTHING;
304 } _SEH2_FINALLY {
305/*
306 if (MainResourceAcquired) {
307 UDFReleaseResource(&(NtReqFcb->MainResource));
308 MainResourceAcquired = FALSE;
309 }
310*/
311 IoStatus->Status = RC;
312 if(ReturnedStatus) {
313 IoStatus->Information = sizeof(FILE_STANDARD_INFORMATION);
314 } else {
315 IoStatus->Information = 0;
316 }
317 } _SEH2_END;
318
320
321 return(ReturnedStatus);
322} // end UDFFastIoQueryStdInfo()
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastIoRelCreateSec()

VOID NTAPI UDFFastIoRelCreateSec ( IN PFILE_OBJECT  FileObject)

Definition at line 387 of file fastio.cpp.

389{
391
392 MmPrint((" RelFromCreateSection()\n"));
393
394 NtReqFcb->AcqSectionCount--;
395 // Release the PagingIoResource for the file stream
396 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
397
398 // Release the MainResource for the file stream
399 UDFReleaseResource(&(NtReqFcb->MainResource));
400
401 return;
402} // end UDFFastIoRelCreateSec()

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastLock()

BOOLEAN NTAPI UDFFastLock ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PLARGE_INTEGER  Length,
PEPROCESS  ProcessId,
ULONG  Key,
BOOLEAN  FailImmediately,
BOOLEAN  ExclusiveLock,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 205 of file lockctrl.cpp.

216{
217 BOOLEAN Results = FALSE;
218
219// BOOLEAN AcquiredFCB = FALSE;
222
223 UDFPrint(("UDFFastLock\n"));
224 // Decode the type of file object we're being asked to process and make
225 // sure it is only a user file open.
226
227
228 // Get the FCB and CCB pointers.
229 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
230 ASSERT(Ccb);
231 Fcb = Ccb->Fcb;
232 ASSERT(Fcb);
233 // Validate the sent-in FCB
234 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
235 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
236
238 IoStatus->Information = 0;
239 return TRUE;
240 }
241
242 // Acquire exclusive access to the Fcb this operation can always wait
243
245
246 // BUGBUG: kenr
247 // (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );
248
249 _SEH2_TRY {
250
251 // We check whether we can proceed
252 // based on the state of the file oplocks.
253
254 // Now call the FsRtl routine to do the actual processing of the
255 // Lock request
256 if ((Results = FsRtlFastLock( &(Fcb->NTRequiredFCB->FileLock),
259 Length,
260 ProcessId,
261 Key,
264 IoStatus,
265 NULL,
266 FALSE ))) {
267
268 // Set the flag indicating if Fast I/O is possible
269 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
270 }
271
272//try_exit: NOTHING;
273 } _SEH2_FINALLY {
274
275 // Release the Fcb, and return to our caller
276
277 // BUGBUG: kenr
278 // UDFReleaseResource( (Fcb)->Header.Resource );
279
281
282 } _SEH2_END;
283
284 return Results;
285} // end UDFFastLock()
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN BOOLEAN ExclusiveLock
Definition: fatprocs.h:2714
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ULONG BOOLEAN FailImmediately
Definition: fatprocs.h:2713
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
#define FsRtlFastLock(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)
Definition: fsrtlfuncs.h:1581

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastUnlockAll()

BOOLEAN NTAPI UDFFastUnlockAll ( IN PFILE_OBJECT  FileObject,
PEPROCESS  ProcessId,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 404 of file lockctrl.cpp.

411{
412 BOOLEAN Results = FALSE;
413
414// BOOLEAN AcquiredFCB = FALSE;
417
418 UDFPrint(("UDFFastUnlockAll\n"));
419
420 IoStatus->Information = 0;
421 // Decode the type of file object we're being asked to process and make
422 // sure it is only a user file open.
423
424 // Get the FCB and CCB pointers.
425 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
426 ASSERT(Ccb);
427 Fcb = Ccb->Fcb;
428 ASSERT(Fcb);
429 // Validate the sent-in FCB
430 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
431 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
432
434 return TRUE;
435 }
436
437 // Acquire shared access to the Fcb this operation can always wait
438
440
441 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
442 UDFAcquireResourceShared( &(Fcb->NTRequiredFCB->MainResource),TRUE );
443
444 _SEH2_TRY {
445
446 // We check whether we can proceed
447 // based on the state of the file oplocks.
448
449 // Now call the FsRtl routine to do the actual processing of the
450 // Lock request
451 Results = TRUE;
452 IoStatus->Status = FsRtlFastUnlockAll( &(Fcb->NTRequiredFCB->FileLock),
454 ProcessId,
455 NULL );
456
457 // Set the flag indicating if Fast I/O is questionable
458
459 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible( Fcb );
460
461//try_exit: NOTHING;
462 } _SEH2_FINALLY {
463
464 // Release the Fcb, and return to our caller
465
466 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
467 UDFReleaseResource(&(Fcb->NTRequiredFCB->MainResource));
469
470 } _SEH2_END;
471
472 return Results;
473} // end UDFFastUnlockAll()

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastUnlockAllByKey()

BOOLEAN NTAPI UDFFastUnlockAllByKey ( IN PFILE_OBJECT  FileObject,
PEPROCESS  ProcessId,
ULONG  Key,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 494 of file lockctrl.cpp.

502{
503 BOOLEAN Results = FALSE;
504
505// BOOLEAN AcquiredFCB = FALSE;
508
509 UDFPrint(("UDFFastUnlockAllByKey\n"));
510
511 IoStatus->Information = 0;
512 // Decode the type of file object we're being asked to process and make
513 // sure it is only a user file open.
514
515 // Get the FCB and CCB pointers.
516 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
517 ASSERT(Ccb);
518 Fcb = Ccb->Fcb;
519 ASSERT(Fcb);
520 // Validate the sent-in FCB
521 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
522 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
523
525 return TRUE;
526 }
527
528 // Acquire shared access to the Fcb this operation can always wait
529
531
532 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
533 UDFAcquireResourceShared( &(Fcb->NTRequiredFCB->MainResource),TRUE );
534
535 _SEH2_TRY {
536
537 // We check whether we can proceed
538 // based on the state of the file oplocks.
539
540 // Now call the FsRtl routine to do the actual processing of the
541 // Lock request
542 Results = TRUE;
543 IoStatus->Status = FsRtlFastUnlockAllByKey( &(Fcb->NTRequiredFCB->FileLock),
545 ProcessId,
546 Key,
547 NULL );
548
549 // Set the flag indicating if Fast I/O is possible
550
551 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible( Fcb );
552
553//try_exit: NOTHING;
554 } _SEH2_FINALLY {
555
556 // Release the Fcb, and return to our caller
557
558 UDF_CHECK_PAGING_IO_RESOURCE(Fcb->NTRequiredFCB);
559 UDFReleaseResource(&(Fcb->NTRequiredFCB->MainResource));
561
562 } _SEH2_END;
563
564 return Results;
565} // end UDFFastUnlockAllByKey()
NTSTATUS NTAPI FsRtlFastUnlockAllByKey(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS Process, IN ULONG Key, IN PVOID Context OPTIONAL)
Definition: filelock.c:1086

Referenced by UDFInitializeFunctionPointers().

◆ UDFFastUnlockSingle()

BOOLEAN NTAPI UDFFastUnlockSingle ( IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PLARGE_INTEGER  Length,
PEPROCESS  ProcessId,
ULONG  Key,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject 
)

Definition at line 309 of file lockctrl.cpp.

319{
320 BOOLEAN Results = FALSE;
321
322// BOOLEAN AcquiredFCB = FALSE;
325
326 UDFPrint(("UDFFastUnlockSingle\n"));
327 // Decode the type of file object we're being asked to process and make
328 // sure it is only a user file open.
329
330 IoStatus->Information = 0;
331
332 // Get the FCB and CCB pointers.
333 Ccb = (PtrUDFCCB)(FileObject->FsContext2);
334 ASSERT(Ccb);
335 Fcb = Ccb->Fcb;
336 ASSERT(Fcb);
337 // Validate the sent-in FCB
338 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
339 (Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
340
342 return TRUE;
343 }
344
345 // Acquire exclusive access to the Fcb this operation can always wait
346
348
349 // BUGBUG: kenr
350 // (VOID) ExAcquireResourceShared( Fcb->Header.Resource, TRUE );
351
352 _SEH2_TRY {
353
354 // We check whether we can proceed
355 // based on the state of the file oplocks.
356
357 // Now call the FsRtl routine to do the actual processing of the
358 // Lock request
359 Results = TRUE;
360 IoStatus->Status = FsRtlFastUnlockSingle( &(Fcb->NTRequiredFCB->FileLock),
363 Length,
364 ProcessId,
365 Key,
366 NULL,
367 FALSE );
368 // Set the flag indicating if Fast I/O is possible
369 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
370
371//try_exit: NOTHING;
372 } _SEH2_FINALLY {
373
374 // Release the Fcb, and return to our caller
375
376 // BUGBUG: kenr
377 // UDFReleaseResource( (Fcb)->Header.Resource );
378
380
381 } _SEH2_END;
382
383 return Results;
384} // end UDFFastUnlockSingle()
NTSTATUS NTAPI FsRtlFastUnlockSingle(IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS Process, IN ULONG Key, IN PVOID Context OPTIONAL, IN BOOLEAN AlreadySynchronized)
Definition: filelock.c:825

Referenced by UDFInitializeFunctionPointers().

◆ UDFFileInfo()

NTSTATUS NTAPI UDFFileInfo ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 46 of file fileinfo.cpp.

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()
NTSTATUS UDFCommonFileInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fileinfo.cpp:114

Referenced by UDFInitializeFunctionPointers().

◆ UDFFirstOpenFile()

NTSTATUS UDFFirstOpenFile ( IN PVCB  Vcb,
IN PFILE_OBJECT  PtrNewFileObject,
OUT PtrUDFFCB PtrNewFcb,
IN PUDF_FILE_INFO  RelatedFileInfo,
IN PUDF_FILE_INFO  NewFileInfo,
IN PUNICODE_STRING  LocalPath,
IN PUNICODE_STRING  CurName 
)

Definition at line 2281 of file create.cpp.

2290{
2291// DIR_INDEX NewFileIndex;
2292 PtrUDFObjectName NewFCBName;
2294 NTSTATUS RC;
2296 PDIR_INDEX_HDR hDirIndex;
2297 PDIR_INDEX_ITEM DirIndex;
2298
2299 AdPrint(("UDFFirstOpenFile\n"));
2300
2301 if(!((*PtrNewFcb) = UDFAllocateFCB())) {
2302 AdPrint(("Can't allocate FCB\n"));
2304 }
2305
2306 // Allocate and set new FCB unique name (equal to absolute path name)
2307 if(!(NewFCBName = UDFAllocateObjectName())) return STATUS_INSUFFICIENT_RESOURCES;
2308
2309 if(RelatedFileInfo && RelatedFileInfo->Fcb &&
2310 !(RelatedFileInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)) {
2311 RC = MyCloneUnicodeString(&(NewFCBName->ObjectName), &(RelatedFileInfo->Fcb->FCBName->ObjectName));
2312 } else {
2313 RC = MyInitUnicodeString(&(NewFCBName->ObjectName), L"");
2314 }
2315 if(!NT_SUCCESS(RC))
2317 if( (CurName->Buffer[0] != L':') &&
2318 (!LocalPath->Length ||
2319 ((LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L':') /*&&
2320 (LocalPath->Buffer[LocalPath->Length/sizeof(WCHAR)-1] != L'\\')*/) )) {
2321 RC = MyAppendUnicodeToString(&(NewFCBName->ObjectName), L"\\");
2322 if(!NT_SUCCESS(RC)) {
2323 UDFReleaseObjectName(NewFCBName);
2325 }
2326 }
2327
2328 // Make link between Fcb and FileInfo
2329 (*PtrNewFcb)->FileInfo = NewFileInfo;
2330 NewFileInfo->Fcb = (*PtrNewFcb);
2331 (*PtrNewFcb)->ParentFcb = RelatedFileInfo->Fcb;
2332
2333 if(!((*PtrNewFcb)->NTRequiredFCB = NewFileInfo->Dloc->CommonFcb)) {
2334 (*PtrNewFcb)->NTRequiredFCB = (PtrUDFNTRequiredFCB)MyAllocatePool__(NonPagedPool, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2335 if(!((*PtrNewFcb)->NTRequiredFCB)) {
2336 UDFReleaseObjectName(NewFCBName);
2338 }
2339
2340 UDFPrint(("UDFAllocateNtReqFCB: %x\n", (*PtrNewFcb)->NTRequiredFCB));
2341 RtlZeroMemory((*PtrNewFcb)->NTRequiredFCB, UDFQuadAlign(sizeof(UDFNTRequiredFCB)));
2342 (*PtrNewFcb)->FileInfo->Dloc->CommonFcb = (*PtrNewFcb)->NTRequiredFCB;
2343 Linked = FALSE;
2344 } else {
2345 if(!(NewFileInfo->Dloc->CommonFcb->NtReqFCBFlags & UDF_NTREQ_FCB_VALID)) {
2346 (*PtrNewFcb)->NTRequiredFCB = NULL;
2347 BrutePoint();
2348 UDFReleaseObjectName(NewFCBName);
2349 return STATUS_ACCESS_DENIED;
2350 }
2351 }
2352
2353 NtReqFcb = (*PtrNewFcb)->NTRequiredFCB;
2354 // Set times
2355 if(!Linked) {
2356 UDFGetFileXTime((*PtrNewFcb)->FileInfo,
2357 &(NtReqFcb->CreationTime.QuadPart),
2358 &(NtReqFcb->LastAccessTime.QuadPart),
2359 &(NtReqFcb->ChangeTime.QuadPart),
2360 &(NtReqFcb->LastWriteTime.QuadPart) );
2361
2362 // Set the allocation size for the object is specified
2363 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart =
2364 UDFSysGetAllocSize(Vcb, NewFileInfo->Dloc->DataLoc.Length);
2365// NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart = UDFGetFileAllocationSize(Vcb, NewFileInfo);
2366 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
2367 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = NewFileInfo->Dloc->DataLoc.Length;
2368 }
2369 // begin transaction
2370 UDFAcquireResourceExclusive(&(Vcb->FcbListResource), TRUE);
2371
2372 RC = UDFInitializeFCB(*PtrNewFcb, Vcb, NewFCBName,
2373 UDFIsADirectory(NewFileInfo) ? UDF_FCB_DIRECTORY : 0, PtrNewFileObject);
2374 if(!NT_SUCCESS(RC)) {
2375 if(!Linked) {
2376 MyFreePool__((*PtrNewFcb)->NTRequiredFCB);
2377 (*PtrNewFcb)->NTRequiredFCB = NULL;
2378 }
2379 UDFReleaseResource(&(Vcb->FcbListResource));
2380 return RC;
2381 }
2382 // set Read-only attribute
2383 if(!UDFIsAStreamDir(NewFileInfo)) {
2384 hDirIndex = UDFGetDirIndexByFileInfo(NewFileInfo);
2385#ifdef UDF_DBG
2386 if(!hDirIndex) {
2387 BrutePoint();
2388 } else {
2389#endif // UDF_DBG
2390 if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, NewFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2391 (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2392 }
2393 MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), &(DirIndex->FName), MEM_USOBJ_TAG);
2394#ifdef UDF_DBG
2395 }
2396#endif // UDF_DBG
2397 } else if (RelatedFileInfo->ParentFile) {
2398 hDirIndex = UDFGetDirIndexByFileInfo(RelatedFileInfo);
2399 if(UDFAttributesToNT(DirIndex = UDFDirIndex(hDirIndex, RelatedFileInfo->Index),NULL) & FILE_ATTRIBUTE_READONLY) {
2400 (*PtrNewFcb)->FCBFlags |= UDF_FCB_READ_ONLY;
2401 }
2402 RC = MyAppendUnicodeStringToStringTag(&(NewFCBName->ObjectName), CurName, MEM_USOBJ_TAG);
2403// } else {
2404// BrutePoint();
2405 }
2406 // do not allocate CCB if it is internal Create/Open
2407 if(NT_SUCCESS(RC)) {
2408 if(PtrNewFileObject) {
2409 RC = UDFOpenFile(Vcb, PtrNewFileObject, *PtrNewFcb);
2410 } else {
2411 RC = STATUS_SUCCESS;
2412 }
2413 }
2414 UDFReleaseResource(&(Vcb->FcbListResource));
2415 // end transaction
2416
2417// if(!NT_SUCCESS(RC)) return RC;
2418
2419 return RC;
2420} // end UDFFirstOpenFile()
NTSTATUS MyCloneUnicodeString(IN PUNICODE_STRING Str1, IN PUNICODE_STRING Str2)
static const WCHAR Linked[]
Definition: interface.c:30
#define MEM_USOBJ_TAG
Definition: create.cpp:26
NTSTATUS UDFOpenFile(PVCB Vcb, PFILE_OBJECT PtrNewFileObject, PtrUDFFCB PtrNewFcb)
Definition: create.cpp:2437
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define L(x)
Definition: ntvdm.h:50
#define UDF_NTREQ_FCB_VALID
Definition: struct.h:237
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by UDFCommonCreate().

◆ UDFFlush()

NTSTATUS NTAPI UDFFlush ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 42 of file flush.cpp.

45{
47 PtrUDFIrpContext PtrIrpContext = NULL;
48 BOOLEAN AreWeTopLevel = FALSE;
49
50 UDFPrint(("UDFFlush: \n"));
51
54 ASSERT(Irp);
55
56 // set the top level context
57 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
58 ASSERT(!UDFIsFSDevObj(DeviceObject));
59
60 _SEH2_TRY {
61
62 // get an IRP context structure and issue the request
63 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
64 if(PtrIrpContext) {
65 RC = UDFCommonFlush(PtrIrpContext, Irp);
66 } else {
68 Irp->IoStatus.Status = RC;
69 Irp->IoStatus.Information = 0;
70 // complete the IRP
72 }
73
75
76 RC = UDFExceptionHandler(PtrIrpContext, Irp);
77
79 } _SEH2_END;
80
81 if (AreWeTopLevel) {
83 }
84
86
87 return(RC);
88} // end UDFFlush()
NTSTATUS UDFCommonFlush(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: flush.cpp:110

Referenced by UDFInitializeFunctionPointers().

◆ UDFFlushADirectory()

ULONG UDFFlushADirectory ( IN PVCB  Vcb,
IN PUDF_FILE_INFO  FI,
OUT PIO_STATUS_BLOCK  PtrIoStatus,
ULONG  FlushFlags = 0 
)

◆ UDFFlushAFile()

ULONG UDFFlushAFile ( PtrUDFFCB  Fcb,
PtrUDFCCB  Ccb,
PIO_STATUS_BLOCK  PtrIoStatus,
IN ULONG  FlushFlags = 0 
)

◆ UDFFlushCompletion()

NTSTATUS NTAPI UDFFlushCompletion ( PDEVICE_OBJECT  PtrDeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 578 of file flush.cpp.

583{
584// NTSTATUS RC = STATUS_SUCCESS;
585
586 UDFPrint(("UDFFlushCompletion: \n"));
587
588 if (Irp->PendingReturned) {
590 }
591
592 if (Irp->IoStatus.Status == STATUS_INVALID_DEVICE_REQUEST) {
593 // cannot do much here, can we?
594 Irp->IoStatus.Status = STATUS_SUCCESS;
595 }
596
597 return(STATUS_SUCCESS);
598} // end UDFFlushCompletion()

Referenced by UDFCommonFlush().

◆ UDFFlushIsBreaking()

BOOLEAN UDFFlushIsBreaking ( IN PVCB  Vcb,
IN ULONG  FlushFlags = 0 
)

Definition at line 605 of file flush.cpp.

609{
610 BOOLEAN ret_val = FALSE;
611// if(!(FlushFlags & UDF_FLUSH_FLAGS_BREAKABLE))
612 return FALSE;
613 UDFAcquireResourceExclusive(&(Vcb->FlushResource),TRUE);
614 ret_val = (Vcb->VCBFlags & UDF_VCB_FLAGS_FLUSH_BREAK_REQ) ? TRUE : FALSE;
615 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_FLUSH_BREAK_REQ;
616 UDFReleaseResource(&(Vcb->FlushResource));
617 return ret_val;
618} // end UDFFlushIsBreaking()
#define UDF_VCB_FLAGS_FLUSH_BREAK_REQ
Definition: udf_common.h:483

Referenced by UDFFlushADirectory().

◆ UDFFlushLogicalVolume()

ULONG UDFFlushLogicalVolume ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVCB  Vcb,
ULONG  FlushFlags = 0 
)

◆ UDFFlushTryBreak()

VOID UDFFlushTryBreak ( IN PVCB  Vcb)

Definition at line 625 of file flush.cpp.

628{
629 UDFAcquireResourceExclusive(&(Vcb->FlushResource),TRUE);
631 UDFReleaseResource(&(Vcb->FlushResource));
632} // end UDFFlushTryBreak()

Referenced by UDFCommonCreate(), UDFCommonDirControl(), UDFCommonFileInfo(), and UDFCommonQueryVolInfo().

◆ UDFFSControl()

NTSTATUS NTAPI UDFFSControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 39 of file fscntrl.cpp.

43{
45 PtrUDFIrpContext PtrIrpContext;
46 BOOLEAN AreWeTopLevel = FALSE;
47
48 UDFPrint(("\nUDFFSControl: \n\n"));
49
52 ASSERT(Irp);
53
54 // set the top level context
55 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
56
57 _SEH2_TRY {
58
59 // get an IRP context structure and issue the request
60 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
61 if(PtrIrpContext) {
62 RC = UDFCommonFSControl(PtrIrpContext, Irp);
63 } else {
65 Irp->IoStatus.Status = RC;
66 Irp->IoStatus.Information = 0;
67 // complete the IRP
69 }
70
72
73 UDFPrintErr(("UDFFSControl: exception ***"));
74 RC = UDFExceptionHandler(PtrIrpContext, Irp);
75
77 } _SEH2_END;
78
79 if(AreWeTopLevel) {
81 }
82
84
85 return(RC);
86} // end UDFFSControl()
NTSTATUS NTAPI UDFCommonFSControl(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: fscntrl.cpp:103

Referenced by UDFInitializeFunctionPointers().

◆ UDFFsNotification()

VOID NTAPI UDFFsNotification ( IN PDEVICE_OBJECT  DeviceObject,
IN BOOLEAN  FsActive 
)

Definition at line 779 of file udfinit.cpp.

812{
813 // Begin by determine whether or not the file system is a cdrom-based file
814 // system. If not, then this driver is not concerned with it.
815 if (!FsRegistered ||
817 return;
818 }
819
820 // Begin by determining whether this file system is registering or
821 // unregistering as an active file system.
822 if (FsActive
823 && UDFGlobalData.UDFDeviceObject_CD != DeviceObject
824#ifdef UDF_HDD_SUPPORT
825 && UDFGlobalData.UDFDeviceObject_HDD != DeviceObject
826#endif // UDF_HDD_SUPPORT
827 ) {
828 UDFPrint(("\n*** UDFFSNotification \n\n"));
829
830 // Acquire GlobalDataResource
831 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
832
834
836
837 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject_CD);
838 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_CD);
839
840#ifdef UDF_HDD_SUPPORT
841 IoUnregisterFileSystem(UDFGlobalData.UDFDeviceObject_HDD);
842 IoRegisterFileSystem(UDFGlobalData.UDFDeviceObject_HDD);
843#endif // UDF_HDD_SUPPORT
844
846
847 } else {
848 UDFPrint(("\n*** recursive UDFFSNotification call,\n can't become top-level UDF FSD \n\n"));
849 }
850
851 // Release the global resource.
852 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
853
854
855 }
856}
VOID NTAPI IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
Definition: volume.c:987
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM
Definition: winioctl.h:109
PVOID HANDLE
Definition: typedefs.h:73
#define UDF_HDD_SUPPORT
Definition: udffs.h:45
HANDLE FsNotification_ThreadId
Definition: udfinit.cpp:51
UDFData UDFGlobalData
Definition: udfinit.cpp:25
ULONG FsRegistered
Definition: udfinit.cpp:45
_In_ BOOLEAN FsActive
Definition: iotypes.h:7360

Referenced by DriverEntry().

◆ UDFGetAltNameInformation()

NTSTATUS UDFGetAltNameInformation ( IN PtrUDFFCB  Fcb,
IN PFILE_NAME_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 869 of file fileinfo.cpp.

874{
875 PDIR_INDEX_ITEM DirNdx;
878 WCHAR ShortNameBuffer[13];
879
880 AdPrint(("UDFGetAltNameInformation: \n"));
881
882 *PtrReturnedLength -= FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]);
883 DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index);
884
885 ShortName.MaximumLength = 13 * sizeof(WCHAR);
886 ShortName.Buffer = (PWCHAR)&ShortNameBuffer;
887
888 UDFDOSName__(Fcb->Vcb, &ShortName, &(DirNdx->FName), Fcb->FileInfo);
889
890 if(*PtrReturnedLength < ShortName.Length) {
892 } else {
893 BytesToCopy = ShortName.Length;
894 *PtrReturnedLength -= ShortName.Length;
895 }
896
897 RtlCopyMemory( &(PtrBuffer->FileName),
898 ShortName.Buffer,
899 BytesToCopy );
900
901 PtrBuffer->FileNameLength = ShortName.Length;
902
903 return(STATUS_SUCCESS);
904} // end UDFGetAltNameInformation()
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1306
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
#define UDFDOSName__(Vcb, DosName, UdfName, FileInfo)
Definition: udf_info.h:217

Referenced by UDFCommonFileInfo().

◆ UDFGetBasicInformation()

NTSTATUS UDFGetBasicInformation ( IN PFILE_OBJECT  FileObject,
IN PtrUDFFCB  Fcb,
IN PFILE_BASIC_INFORMATION  PtrBuffer,
IN OUT LONG PtrReturnedLength 
)

Definition at line 532 of file fileinfo.cpp.

538{
541 PDIR_INDEX_ITEM DirNdx;
542
543 AdPrint(("UDFGetBasicInformation: \n"));
544
545 _SEH2_TRY {
546
547 if(*PtrReturnedLength < (LONG)sizeof(FILE_BASIC_INFORMATION)) {
549 }
550
551 // Zero out the supplied buffer.
552 RtlZeroMemory(PtrBuffer, sizeof(FILE_BASIC_INFORMATION));
553
554 // Get information from the FCB and update TimesCache in DirIndex
555 FileInfo = Fcb->FileInfo;
556
557 if(!FileInfo) {
558 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
559 AdPrint(("!!!! GetBasicInfo to unopened file !!!!\n"));
561 }
562
564
565 PtrBuffer->CreationTime = Fcb->NTRequiredFCB->CreationTime;
566 DirNdx->CreationTime = PtrBuffer->CreationTime.QuadPart;
567
568 PtrBuffer->LastAccessTime = Fcb->NTRequiredFCB->LastAccessTime;
569 DirNdx->LastAccessTime = PtrBuffer->LastAccessTime.QuadPart;
570
571 PtrBuffer->LastWriteTime = Fcb->NTRequiredFCB->LastWriteTime;
572 DirNdx->LastWriteTime = PtrBuffer->LastWriteTime.QuadPart;
573
574 PtrBuffer->ChangeTime = Fcb->NTRequiredFCB->ChangeTime;
575 DirNdx->ChangeTime = PtrBuffer->ChangeTime.QuadPart;
576
577 // Now fill in the attributes.
578 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
579 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
580#ifdef UDF_DBG
581 if(!FileInfo->Dloc->DirIndex) AdPrint(("*****!!!!! Directory has no DirIndex !!!!!*****\n"));
582#endif
583 }
584 // Similarly, fill in attributes indicating a hidden file, system
585 // file, compressed file, temporary file, etc. if the FSD supports
586 // such file attribute values.
587 PtrBuffer->FileAttributes |= UDFAttributesToNT(DirNdx,NULL);
588 if(FileObject->Flags & FO_TEMPORARY_FILE) {
589 PtrBuffer->FileAttributes |= FILE_ATTRIBUTE_TEMPORARY;
590 } else {
591 PtrBuffer->FileAttributes &= ~FILE_ATTRIBUTE_TEMPORARY;
592 }
593 if(!PtrBuffer->FileAttributes) {
594 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
595 }
596
597try_exit: NOTHING;
598
599 } _SEH2_FINALLY {
600
601 if(NT_SUCCESS(RC)) {
602 // Return the amount of information filled in.
603 (*PtrReturnedLength) -= sizeof(FILE_BASIC_INFORMATION);
604 }
605 } _SEH2_END;
606 return(RC);
607} // end UDFGetBasicInformation()
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
int64 CreationTime
Definition: udf_rel.h:209
int64 LastAccessTime
Definition: udf_rel.h:211
int64 LastWriteTime
Definition: udf_rel.h:210
int64 ChangeTime
Definition: udf_rel.h:212
LONGLONG CreationTime
Definition: cdstruc.h:1030
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:922
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:921
#define FO_TEMPORARY_FILE
Definition: iotypes.h:1791

Referenced by UDFCommonFileInfo(), and UDFFastIoQueryBasicInfo().

◆ UDFGetCallersBuffer()

PVOID UDFGetCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 871 of file read.cpp.

875{
876 VOID *ReturnedBuffer = NULL;
877
878 UDFPrint(("UDFGetCallersBuffer: \n"));
879
880 // If an MDL is supplied, use it.
881 if(Irp->MdlAddress) {
882 MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(Irp->MdlAddress) MDL=%x\n", Irp->MdlAddress));
883// ReturnedBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
884 ReturnedBuffer = MmGetSystemAddressForMdlSafer(Irp->MdlAddress);
885 } else
886 if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
887 // Free buffer
888#ifndef POST_LOCK_PAGES
889 MmPrint((" UDFGetCallersBuffer: MmGetSystemAddressForMdl(PtrIrpContext->PtrMdl) MDL=%x\n", PtrIrpContext->PtrMdl));
890 ReturnedBuffer = MmGetSystemAddressForMdlSafe(PtrIrpContext->PtrMdl, NormalPagePriority);
891#else //POST_LOCK_PAGES
892 if(PtrIrpContext->TransitionBuffer) {
893 MmPrint((" UDFGetCallersBuffer: TransitionBuffer\n"));
894 return PtrIrpContext->TransitionBuffer;
895 }
896
897 _SEH2_TRY {
898 MmPrint((" MmProbeAndLockPages()\n"));
899 MmProbeAndLockPages(PtrIrpContext->PtrMdl, Irp->RequestorMode,
900 ((PtrIrpContext->MajorFunction == IRP_MJ_READ) ? IoWriteAccess:IoReadAccess));
901#ifdef UDF_DBG
902 LockBufferCounter++;
903#endif //UDF_DBG
905 //RC = STATUS_INVALID_USER_BUFFER;
906 BrutePoint();
907 return NULL;
908 } _SEH2_END;
909
910 MmPrint((" MmGetSystemAddressForMdlSafer()\n"));
911 ReturnedBuffer = MmGetSystemAddressForMdlSafer(PtrIrpContext->PtrMdl);
912#endif //POST_LOCK_PAGES
913 } else {
914 MmPrint((" UDFGetCallersBuffer: Irp->UserBuffer\n"));
915 ReturnedBuffer = Irp->UserBuffer;
916 }
917
918 return(ReturnedBuffer);
919} // end UDFGetCallersBuffer()
VOID NTAPI MmProbeAndLockPages(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN LOCK_OPERATION Operation)
Definition: mdlsup.c:931
@ NormalPagePriority
Definition: imports.h:56
__inline PVOID MmGetSystemAddressForMdlSafer(IN PMDL Mdl)
Definition: ntifs_ex.h:101
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define UDF_IRP_CONTEXT_BUFFER_LOCKED
Definition: struct.h:398
PMDL PtrMdl
Definition: struct.h:380
PCHAR TransitionBuffer
Definition: struct.h:381
@ IoReadAccess
Definition: ketypes.h:863
@ IoWriteAccess
Definition: ketypes.h:864
#define MmGetSystemAddressForMdlSafe(_Mdl, _Priority)

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFGetVolumeBitmap().

◆ UDFGetCfgParameter()

ULONG UDFGetCfgParameter ( IN PVCB  Vcb,
IN PCWSTR  Name,
IN ULONG  DefValue 
)

Definition at line 2000 of file misc.cpp.

2005{
2006 ULONG len;
2007 CHAR NameA[128];
2008 ULONG ret_val=0;
2009 CHAR a;
2010 BOOLEAN wait_name=TRUE;
2011 BOOLEAN wait_val=FALSE;
2012 BOOLEAN wait_nl=FALSE;
2013 ULONG radix=10;
2014 ULONG i;
2015
2016 PUCHAR Cfg = Vcb->Cfg;
2017 ULONG Length = Vcb->CfgLength;
2018
2019 if(!Cfg || !Length)
2020 return DefValue;
2021
2022 len = wcslen(Name);
2023 if(len >= sizeof(NameA))
2024 return DefValue;
2025 sprintf(NameA, "%S", Name);
2026
2027 for(i=0; i<Length; i++) {
2028 a=Cfg[i];
2029 switch(a) {
2030 case '\n':
2031 case '\r':
2032 case ',':
2033 if(wait_val)
2034 return DefValue;
2035 continue;
2036 case ';':
2037 case '#':
2038 case '[': // ignore sections for now, treat as comment
2039 if(!wait_name)
2040 return DefValue;
2041 wait_nl = TRUE;
2042 continue;
2043 case '=':
2044 if(!wait_val)
2045 return DefValue;
2046 continue;
2047 case ' ':
2048 case '\t':
2049 continue;
2050 default:
2051 if(wait_nl)
2052 continue;
2053 }
2054 if(wait_name) {
2055 if(i+len+2 > Length)
2056 return DefValue;
2057 if(RtlCompareMemory(Cfg+i, NameA, len) == len) {
2058 a=Cfg[i+len];
2059 switch(a) {
2060 case '\n':
2061 case '\r':
2062 case ',':
2063 case ';':
2064 case '#':
2065 return DefValue;
2066 case '=':
2067 case ' ':
2068 case '\t':
2069 break;
2070 default:
2071 wait_nl = TRUE;
2072 wait_val = FALSE;
2073 i+=len;
2074 continue;
2075 }
2076 wait_name = FALSE;
2077 wait_nl = FALSE;
2078 wait_val = TRUE;
2079 i+=len;
2080
2081 } else {
2082 wait_nl = TRUE;
2083 }
2084 continue;
2085 }
2086 if(wait_val) {
2087 if(i+3 > Length) {
2088 if(a=='0' && Cfg[i+1]=='x') {
2089 i+=2;
2090 radix=16;
2091 }
2092 }
2093 if(i >= Length) {
2094 return DefValue;
2095 }
2096 while(i<Length) {
2097 a=Cfg[i];
2098 switch(a) {
2099 case '\n':
2100 case '\r':
2101 case ' ':
2102 case '\t':
2103 case ',':
2104 case ';':
2105 case '#':
2106 if(wait_val)
2107 return DefValue;
2108 return ret_val;
2109 }
2110 if(a >= '0' && a <= '9') {
2111 a -= '0';
2112 } else {
2113 if(radix != 16)
2114 return DefValue;
2115 if(a >= 'a' && a <= 'f') {
2116 a -= 'a';
2117 } else
2118 if(a >= 'A' && a <= 'F') {
2119 a -= 'A';
2120 } else {
2121 return DefValue;
2122 }
2123 a += 0x0a;
2124 }
2125 ret_val = ret_val*radix + a;
2126 wait_val = FALSE;
2127 i++;
2128 }
2129 return ret_val;
2130 }
2131 }
2132 return DefValue;
2133
2134} // end UDFGetCfgParameter()
#define RtlCompareMemory(s1, s2, l)
Definition: env_spec_w32.h:465
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define a
Definition: ke_i.h:78
#define sprintf(buf, format,...)
Definition: sprintf.c:55
char CHAR
Definition: xmlstorage.h:175

Referenced by UDFReadRegKeys(), and UDFUpdateCompatOption().

◆ UDFGetEaInformation()

NTSTATUS UDFGetEaInformation ( PtrUDFIrpContext  PtrIrpContext,
IN PtrUDFFCB  Fcb,
IN PFILE_EA_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 801 of file fileinfo.cpp.

807{
809
810 AdPrint(("UDFGetEaInformation\n"));
811
812 _SEH2_TRY {
813
814 if(*PtrReturnedLength < (LONG)sizeof(FILE_EA_INFORMATION)) {
816 }
817
818 // Zero out the supplied buffer.
819 PtrBuffer->EaSize = 0;
820
821try_exit: NOTHING;
822
823 } _SEH2_FINALLY {
824 if(NT_SUCCESS(RC)) {
825 // Return the amount of information filled in.
826 *PtrReturnedLength -= sizeof(FILE_EA_INFORMATION);
827 }
828 } _SEH2_END;
829 return(RC);
830} // end UDFGetEaInformation()
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION

Referenced by UDFCommonFileInfo().

◆ UDFGetFileStreamInformation()

NTSTATUS UDFGetFileStreamInformation ( IN PtrUDFFCB  Fcb,
IN PFILE_STREAM_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 930 of file fileinfo.cpp.

935{
938 PUDF_FILE_INFO SDirInfo;
939 PVCB Vcb;
940 BOOLEAN FcbAcquired = FALSE;
941 uint_di i;
942 LONG l;
943 PDIR_INDEX_HDR hSDirIndex;
944 PDIR_INDEX_ITEM SDirIndex;
945 PFILE_BOTH_DIR_INFORMATION NTFileInfo = NULL;
946
947 AdPrint(("UDFGetFileStreamInformation\n"));
948
949 _SEH2_TRY {
950
951 UDFAcquireResourceExclusive(&(Fcb->Vcb->FileIdResource), TRUE);
952 FcbAcquired = TRUE;
953
954 FileInfo = Fcb->FileInfo;
955 if(!FileInfo) {
956 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
957 AdPrint(("!!!! UDFGetFileStreamInformation to unopened file !!!!\n"));
959 }
960 Vcb = Fcb->Vcb;
961 // Zero out the supplied buffer.
962 RtlZeroMemory(PtrBuffer, *PtrReturnedLength);
963 if(!(SDirInfo = FileInfo->Dloc->SDirInfo) ||
964 UDFIsSDirDeleted(SDirInfo) ) {
965 (*PtrReturnedLength) -= (sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR));
967 }
968
969 hSDirIndex = SDirInfo->Dloc->DirIndex;
971 if(!NTFileInfo) try_return(RC = STATUS_INSUFFICIENT_RESOURCES);
972
973 for(i=2; (SDirIndex = UDFDirIndex(hSDirIndex,i)); i++) {
974 if((SDirIndex->FI_Flags & UDF_FI_FLAG_FI_INTERNAL) ||
975 UDFIsDeleted(SDirIndex) ||
976 !SDirIndex->FName.Buffer )
977 continue;
978 // copy data to buffer
979 if(*PtrReturnedLength < (l = ((sizeof(FILE_STREAM_INFORMATION) - sizeof(WCHAR)) +
980 SDirIndex->FName.Length + 3) & (~3)) ) {
982 }
983 RC = UDFFileDirInfoToNT(Vcb, SDirIndex, NTFileInfo);
984
985 PtrBuffer->NextEntryOffset = l;
986 PtrBuffer->StreamNameLength = SDirIndex->FName.Length;
987 PtrBuffer->StreamSize = NTFileInfo->EndOfFile;
988 PtrBuffer->StreamAllocationSize = NTFileInfo->AllocationSize;
989 RtlCopyMemory(&(PtrBuffer->StreamName), SDirIndex->FName.Buffer, SDirIndex->FName.Length);
990 *PtrReturnedLength -= l;
991 *((PCHAR*)(&PtrBuffer)) += l;
992 }
993
994try_exit: NOTHING;
995
996 } _SEH2_FINALLY {
997 if(FcbAcquired)
998 UDFReleaseResource(&(Fcb->Vcb->FileIdResource));
999 if(NTFileInfo)
1000 MyFreePool__(NTFileInfo);
1001 } _SEH2_END;
1002 return(RC);
1003} // end UDFGetFileStreamInformation()
NTSTATUS UDFFileDirInfoToNT(IN PVCB Vcb, IN PDIR_INDEX_ITEM FileDirNdx, OUT PFILE_BOTH_DIR_INFORMATION NTFileInfo)
r l[0]
Definition: byte_order.h:168
struct _FILE_BOTH_DIR_INFORMATION * PFILE_BOTH_DIR_INFORMATION
struct _FILE_STREAM_INFORMATION FILE_STREAM_INFORMATION
#define UDF_NAME_LEN
Definition: osta_misc.h:314
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
PDIR_INDEX_HDR DirIndex
Definition: udf_rel.h:312
#define UDFIsDeleted(DirNdx)
Definition: udf_info.h:788
uint32 uint_di
Definition: udf_rel.h:29

Referenced by UDFCommonFileInfo().

◆ UDFGetFullNameInformation()

NTSTATUS UDFGetFullNameInformation ( IN PFILE_OBJECT  FileObject,
IN PFILE_NAME_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 836 of file fileinfo.cpp.

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()

Referenced by UDFCommonFileInfo().

◆ UDFGetInstallTime()

BOOLEAN UDFGetInstallTime ( PULONG  iTime)

◆ UDFGetInstallVersion()

BOOLEAN UDFGetInstallVersion ( PULONG  iVer)

◆ UDFGetInternalInformation()

NTSTATUS UDFGetInternalInformation ( PtrUDFIrpContext  PtrIrpContext,
IN PtrUDFFCB  Fcb,
IN PtrUDFCCB  Ccb,
IN PFILE_INTERNAL_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 747 of file fileinfo.cpp.

754{
757 PVCB Vcb;
758
759 AdPrint(("UDFGetInternalInformation\n"));
760
761 _SEH2_TRY {
762
763 if(*PtrReturnedLength < (LONG)sizeof(FILE_INTERNAL_INFORMATION)) {
765 }
766
767 // Zero out the supplied buffer.
768 RtlZeroMemory(PtrBuffer, sizeof(FILE_INTERNAL_INFORMATION));
769
770 FileInfo = Fcb->FileInfo;
771
772 if(!FileInfo) {
773 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
774 AdPrint(("!!!! UDFGetInternalInformation to unopened file !!!!\n"));
776 }
777
778 Vcb = Fcb->Vcb;
779 PtrBuffer->IndexNumber.QuadPart = UDFGetNTFileId(Vcb, FileInfo, &(Fcb->FCBName->ObjectName));
780
781 UDFAcquireResourceExclusive(&(Fcb->Vcb->FileIdResource), TRUE);
782 // remember File Id & full path
783 UDFStoreFileId(Fcb->Vcb, Ccb, FileInfo, PtrBuffer->IndexNumber.QuadPart);
784 UDFReleaseResource(&(Fcb->Vcb->FileIdResource));
785
786try_exit: NOTHING;
787
788 } _SEH2_FINALLY {
789 if(NT_SUCCESS(RC)) {
790 // Return the amount of information filled in.
791 *PtrReturnedLength -= sizeof(FILE_INTERNAL_INFORMATION);
792 }
793 } _SEH2_END;
794 return(RC);
795} // end UDFGetInternalInformation()
NTSTATUS UDFStoreFileId(IN PVCB Vcb, IN PtrUDFCCB Ccb, IN PUDF_FILE_INFO fi, IN LONGLONG Id)
Definition: fileinfo.cpp:2417
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION

Referenced by UDFCommonFileInfo().

◆ UDFGetNetworkInformation()

NTSTATUS UDFGetNetworkInformation ( IN PtrUDFFCB  Fcb,
IN PFILE_NETWORK_OPEN_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 676 of file fileinfo.cpp.

681{
684
685 AdPrint(("UDFGetNetworkInformation: \n"));
686
687 _SEH2_TRY {
688
689 if(*PtrReturnedLength < (LONG)sizeof(FILE_NETWORK_OPEN_INFORMATION)) {
691 }
692
693 // Zero out the supplied buffer.
695
696 // Get information from the FCB.
697 PtrBuffer->CreationTime = Fcb->NTRequiredFCB->CreationTime;
698 PtrBuffer->LastAccessTime = Fcb->NTRequiredFCB->LastAccessTime;
699 PtrBuffer->LastWriteTime = Fcb->NTRequiredFCB->LastWriteTime;
700 PtrBuffer->ChangeTime = Fcb->NTRequiredFCB->ChangeTime;
701
702 FileInfo = Fcb->FileInfo;
703
704 if(!FileInfo) {
705 AdPrint(("!!!!!!!! Bu-u-u-u-u-g !!!!!!!!!!!\n"));
706 AdPrint(("!!!! UDFGetNetworkInformation to unopened file !!!!\n"));
708 }
709 // Now fill in the attributes.
710 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
711 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
712#ifdef UDF_DBG
713 if(!FileInfo->Dloc->DirIndex) AdPrint(("*****!!!!! Directory has no DirIndex !!!!!*****\n"));
714#endif
715 } else {
716 if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.LowPart == 0xffffffff) {
717 Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart =
718 UDFSysGetAllocSize(Fcb->Vcb, UDFGetFileSize(FileInfo));
719 }
720 PtrBuffer->AllocationSize = Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize;
721 PtrBuffer->EndOfFile = Fcb->NTRequiredFCB->CommonFCBHeader.FileSize;
722 }
723 // Similarly, fill in attributes indicating a hidden file, system
724 // file, compressed file, temporary file, etc. if the FSD supports
725 // such file attribute values.
727 if(!PtrBuffer->FileAttributes) {
728 PtrBuffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
729 }
730
731try_exit: NOTHING;
732
733 } _SEH2_FINALLY {
734 if(NT_SUCCESS(RC)) {
735 // Return the amount of information filled in.
736 (*PtrReturnedLength) -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
737 }
738 } _SEH2_END;
739 return(RC);
740} // end UDFGetNetworkInformation()
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
ULONG FileAttributes
Definition: cdstruc.h:977

Referenced by UDFCommonFileInfo().

◆ UDFGetOpenParamsByFileId()

NTSTATUS UDFGetOpenParamsByFileId ( IN PVCB  Vcb,
IN LONGLONG  Id,
OUT PUNICODE_STRING FName,
OUT BOOLEAN CaseSens 
)

Definition at line 2472 of file fileinfo.cpp.

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()
DWORD Id
LONG UDFFindFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2380
#define STATUS_NOT_FOUND
Definition: shellext.h:72

Referenced by UDFCommonCreate().

◆ UDFGetPositionInformation()

NTSTATUS UDFGetPositionInformation ( IN PFILE_OBJECT  FileObject,
IN PFILE_POSITION_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

Definition at line 910 of file fileinfo.cpp.

915{
916 if(*PtrReturnedLength < (LONG)sizeof(FILE_POSITION_INFORMATION)) {
918 }
919 PtrBuffer->CurrentByteOffset = FileObject->CurrentByteOffset;
920 // Modify the local variable for BufferLength appropriately.
921 *PtrReturnedLength -= sizeof(FILE_POSITION_INFORMATION);
922
923 return(STATUS_SUCCESS);
924} // end UDFGetAltNameInformation()
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION

Referenced by UDFCommonFileInfo().

◆ UDFGetRegParameter()

ULONG UDFGetRegParameter ( IN PVCB  Vcb,
IN PCWSTR  Name,
IN ULONG  DefValue = 0 
)

Definition at line 1986 of file misc.cpp.

1991{
1993 Name,
1994 Vcb ? &(Vcb->TargetDevName) : NULL,
1995 Vcb ? Vcb->DefaultRegName : NULL,
1996 DefValue);
1997} // end UDFGetRegParameter()
ULONG UDFRegCheckParameterValue(IN PUNICODE_STRING RegistryPath, IN PCWSTR Name, IN PUNICODE_STRING PtrVolumePath, IN PCWSTR DefaultPath, IN ULONG DefValue)
Definition: misc.cpp:2225
UNICODE_STRING SavedRegPath
Definition: udf_common.h:615

Referenced by UDFMountVolume(), UDFReadRegKeys(), and UDFUpdateCompatOption().

◆ UDFGetRetrievalPointers()

NTSTATUS UDFGetRetrievalPointers ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp,
IN ULONG  Special 
)

Definition at line 2205 of file fscntrl.cpp.

2210{
2211 NTSTATUS RC;
2212
2215
2216 PVCB Vcb;
2217 PtrUDFFCB Fcb;
2218 PtrUDFCCB Ccb;
2220
2223
2226
2227 LARGE_INTEGER StartingVcn;
2229
2230 PEXTENT_MAP SubMapping = NULL;
2231 ULONG SubExtInfoSz;
2232 ULONG i;
2233 ULONG LBS;
2234 ULONG LBSh;
2235 ULONG L2BSh;
2236
2237 UDFPrint(("UDFGetRetrievalPointers\n"));
2238
2239 // Decode the file object, the only type of opens we accept are
2240 // user volume opens.
2241 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2242 if(!Ccb) {
2243 UDFPrintErr((" !Ccb\n"));
2244 Irp->IoStatus.Information = 0;
2245 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2247 }
2248 Fcb = Ccb->Fcb;
2249 Vcb = Fcb->Vcb;
2250
2251 // Get the input and output buffer lengths and pointers.
2252 // Initialize some variables.
2253 InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
2254 OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
2255
2256 //OutputBuffer = (PRETRIEVAL_POINTERS_BUFFER)UDFGetCallersBuffer( IrpContext, Irp );
2257 if(Special) {
2258 OutputBuffer = (PRETRIEVAL_POINTERS_BUFFER)Irp->AssociatedIrp.SystemBuffer;
2259 } else {
2261 }
2262 InputBuffer = (PSTARTING_VCN_INPUT_BUFFER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer;
2263 if(!InputBuffer) {
2265 }
2266
2267 _SEH2_TRY {
2268
2269 Irp->IoStatus.Information = 0;
2270 // Check for a minimum length on the input and ouput buffers.
2273
2275 }
2276
2277 _SEH2_TRY {
2278
2279 if (Irp->RequestorMode != KernelMode) {
2280 ProbeForRead( IrpSp->Parameters.FileSystemControl.Type3InputBuffer,
2282 sizeof(UCHAR) );
2284 }
2285 StartingVcn = InputBuffer->StartingVcn;
2286
2288
2290 RC = FsRtlIsNtstatusExpected(RC) ?
2292 try_return(RC);
2293 } _SEH2_END;
2294
2295 switch(Special) {
2296 case 0:
2297 FileInfo = Fcb->FileInfo;
2298 break;
2299 case 1:
2300 FileInfo = Vcb->NonAllocFileInfo;
2301 break;
2302 default:
2304 }
2305
2306 if(!FileInfo) {
2308 }
2309
2311
2312 LBS = Vcb->LBlockSize;
2313 LBSh = Vcb->LBlockSizeBits;
2314 L2BSh = Vcb->LB2B_Bits;
2315
2316 if (StartingVcn.HighPart ||
2317 StartingVcn.LowPart >= (ULONG)(AllocationSize >> LBSh)) {
2318
2320 }
2321
2322 SubExtInfoSz = (OutputBufferLength - FIELD_OFFSET(RETRIEVAL_POINTERS_BUFFER, Extents[0])) / (sizeof(LARGE_INTEGER)*2);
2323 // re-use AllocationSize as NextVcn
2324 RC = UDFReadFileLocation__(Vcb, FileInfo, StartingVcn.QuadPart << LBSh,
2325 &SubMapping, &SubExtInfoSz, &AllocationSize);
2326 if(!NT_SUCCESS(RC))
2327 try_return(RC);
2328
2329 OutputBuffer->ExtentCount = SubExtInfoSz;
2330 OutputBuffer->StartingVcn = StartingVcn;
2331 for(i=0; i<SubExtInfoSz; i++) {
2332 // assume, that
2333 // for not-allocated extents we have start Lba = -1
2334 // for not-recorded extents start Lba.LowPart contains real Lba, Lba.HighPart = 0x80000000
2335 // for recorded extents Lba.LowPart contains real Lba, Lba.HighPart = 0
2336 if(SubMapping[i].extLocation == LBA_NOT_ALLOCATED) {
2337 OutputBuffer->Extents[i].Lcn.QuadPart = (int64)(-1);
2338 } else
2339 if(SubMapping[i].extLocation & 0x80000000) {
2340 OutputBuffer->Extents[i].Lcn.LowPart = (SubMapping[i].extLocation & 0x7fffffff) >> L2BSh;
2341 OutputBuffer->Extents[i].Lcn.HighPart = 0x80000000;
2342 } else {
2343 OutputBuffer->Extents[i].Lcn.LowPart = SubMapping[i].extLocation >> L2BSh;
2344 OutputBuffer->Extents[i].Lcn.HighPart = 0;
2345 }
2346 // alignment for last sector
2347 SubMapping[i].extLength += LBS-1;
2348 StartingVcn.QuadPart += SubMapping[i].extLength >> LBSh;
2349 OutputBuffer->Extents[i].NextVcn = StartingVcn;
2350 }
2351
2352 Irp->IoStatus.Information = FIELD_OFFSET(RETRIEVAL_POINTERS_BUFFER, Extents[0]) + i * sizeof(LARGE_INTEGER) * 2;
2353
2354try_exit: NOTHING;
2355 } _SEH2_FINALLY {
2356
2357 if(SubMapping)
2358 MyFreePool__(SubMapping);
2359 Irp->IoStatus.Status = RC;
2360 } _SEH2_END;
2361
2362 return RC;
2363} // end UDFGetRetrievalPointers()
long long int64
Definition: platform.h:13
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:322
struct RETRIEVAL_POINTERS_BUFFER * PRETRIEVAL_POINTERS_BUFFER
struct STARTING_VCN_INPUT_BUFFER * PSTARTING_VCN_INPUT_BUFFER
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
uint32 extLength
Definition: ecma_167.h:128
uint32 extLocation
Definition: ecma_167.h:129
union _LARGE_INTEGER LARGE_INTEGER
__inline OSSTATUS UDFReadFileLocation__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, IN int64 Offset, OUT PEXTENT_MAP *SubExtInfo, IN OUT uint32 *SubExtInfoSz, OUT int64 *NextOffset)
Definition: udf_info.h:683
#define LBA_NOT_ALLOCATED
Definition: udf_rel.h:427
#define PEXTENDED_IO_STACK_LOCATION
Definition: udffs.h:121
_In_ WDFREQUEST _In_ size_t OutputBufferLength
Definition: wdfio.h:320
_In_ WDFREQUEST _In_ size_t _In_ size_t InputBufferLength
Definition: wdfio.h:322
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR OutputBuffer
Definition: wdfiotarget.h:863
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR InputBuffer
Definition: wdfiotarget.h:953

Referenced by UDFCommonDeviceControl(), and UDFUserFsCtrlRequest().

◆ UDFGetSecurity()

NTSTATUS UDFGetSecurity ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

◆ UDFGetStandardInformation()

NTSTATUS UDFGetStandardInformation ( IN PtrUDFFCB  Fcb,
IN PFILE_STANDARD_INFORMATION  PtrBuffer,
IN OUT PLONG  PtrReturnedLength 
)

◆ UDFGetStatistics()

NTSTATUS UDFGetStatistics ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 1601 of file fscntrl.cpp.

1605{
1608 PVCB Vcb;
1609
1612 ULONG StatsSize;
1614
1615 UDFPrint(("UDFGetStatistics\n"));
1616
1617 // Extract the buffer
1618 BufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
1619 // Get a pointer to the output buffer.
1620 Buffer = (PFILE_SYSTEM_STATISTICS)(Irp->AssociatedIrp.SystemBuffer);
1621
1622 // Make sure the buffer is big enough for at least the common part.
1623 if (BufferLength < sizeof(FILESYSTEM_STATISTICS)) {
1625 Irp->IoStatus.Information = 0;
1626 goto EO_stat;
1627 }
1628
1629 // Now see how many bytes we can copy.
1630 StatsSize = sizeof(FILE_SYSTEM_STATISTICS) * KeNumberProcessors;
1631 if (BufferLength < StatsSize) {
1634 } else {
1635 BytesToCopy = StatsSize;
1637 }
1638
1639 Vcb = (PVCB)(((PDEVICE_OBJECT)IrpSp->DeviceObject)->DeviceExtension);
1640 // Fill in the output buffer
1641 RtlCopyMemory( Buffer, Vcb->Statistics, BytesToCopy );
1642 Irp->IoStatus.Information = BytesToCopy;
1643EO_stat:
1644 Irp->IoStatus.Status = status;
1645
1646 return status;
1647} // end UDFGetStatistics()
FILE_SYSTEM_STATISTICS * PFILE_SYSTEM_STATISTICS
Definition: fatstruc.h:612
struct _FILE_SYSTEM_STATISTICS FILE_SYSTEM_STATISTICS
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
Definition: ps.c:97

Referenced by UDFUserFsCtrlRequest().

◆ UDFGetTrialEnd()

BOOLEAN UDFGetTrialEnd ( PULONG  iTrial)

◆ UDFGetVolumeBitmap()

NTSTATUS UDFGetVolumeBitmap ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 2069 of file fscntrl.cpp.

2073{
2074// NTSTATUS RC;
2075
2078
2079 PVCB Vcb;
2080 PtrUDFFCB Fcb;
2081 PtrUDFCCB Ccb;
2082
2083 UDFPrint(("UDFGetVolumeBitmap\n"));
2084
2086 ULONG TotalClusters;
2087 ULONG DesiredClusters;
2088 ULONG StartingCluster;
2091 LARGE_INTEGER StartingLcn;
2093 ULONG i, lim;
2094 PULONG FSBM;
2095// PULONG Dest;
2096 ULONG LSh;
2097
2098 // Decode the file object, the only type of opens we accept are
2099 // user volume opens.
2100 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2101 if(!Ccb) {
2102 UDFPrintErr((" !Ccb\n"));
2103 Irp->IoStatus.Information = 0;
2104 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2106 }
2107 Fcb = Ccb->Fcb;
2108 Vcb = Fcb->Vcb;
2109
2110 InputBufferLength = IrpSp->Parameters.FileSystemControl.InputBufferLength;
2111 OutputBufferLength = IrpSp->Parameters.FileSystemControl.OutputBufferLength;
2112
2114 if(!OutputBuffer)
2116
2117 // Check for a minimum length on the input and output buffers.
2120
2122 Irp->IoStatus.Information = 0;
2123 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
2125 }
2126
2127 // Check if a starting cluster was specified.
2128 TotalClusters = Vcb->FSBM_BitCount;
2129 StartingLcn = ((PSTARTING_LCN_INPUT_BUFFER)IrpSp->Parameters.FileSystemControl.Type3InputBuffer)->StartingLcn;
2130
2131 if (StartingLcn.HighPart || StartingLcn.LowPart >= TotalClusters) {
2132
2134 Irp->IoStatus.Information = 0;
2135 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2137
2138 } else {
2139
2140 StartingCluster = StartingLcn.LowPart & ~7;
2141 }
2142
2144 DesiredClusters = TotalClusters - StartingCluster;
2145
2146 if (OutputBufferLength < (DesiredClusters + 7) / 8) {
2147
2149// RC = STATUS_BUFFER_OVERFLOW;
2150
2151 } else {
2152
2153 BytesToCopy = (DesiredClusters + 7) / 8;
2154// RC = STATUS_SUCCESS;
2155 }
2156
2157 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
2158
2159 _SEH2_TRY {
2160
2161 // Fill in the fixed part of the output buffer
2162 OutputBuffer->StartingLcn.QuadPart = StartingCluster;
2163 OutputBuffer->BitmapSize.QuadPart = DesiredClusters;
2164
2165 RtlZeroMemory( &OutputBuffer->Buffer[0], BytesToCopy );
2166 lim = BytesToCopy * 8;
2167 FSBM = (PULONG)(Vcb->FSBM_Bitmap);
2168 LSh = Vcb->LB2B_Bits;
2169// Dest = (PULONG)(&OutputBuffer->Buffer[0]);
2170
2171 for(i=StartingCluster & ~7; i<lim; i++) {
2172 if(UDFGetFreeBit(FSBM, i<<LSh))
2173 UDFSetFreeBit(FSBM, i);
2174 }
2175
2177
2178 BrutePoint();
2179 UDFPrintErr(("UDFGetVolumeBitmap: Exception\n"));
2180// UDFUnlockCallersBuffer(IrpContext, Irp, OutputBuffer);
2181 BrutePoint();
2182// RC = UDFExceptionHandler(IrpContext, Irp);
2183 UDFReleaseResource(&(Vcb->VCBResource));
2185
2186 Irp->IoStatus.Information = 0;
2187 Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
2189 } _SEH2_END;
2190
2191 UDFReleaseResource(&(Vcb->VCBResource));
2192
2194 Irp->IoStatus.Information = FIELD_OFFSET(VOLUME_BITMAP_BUFFER, Buffer) +
2196 Irp->IoStatus.Status = STATUS_SUCCESS;
2197
2198 return STATUS_SUCCESS;
2199
2200
2201} // end UDFGetVolumeBitmap()
struct VOLUME_BITMAP_BUFFER * PVOLUME_BITMAP_BUFFER
struct STARTING_LCN_INPUT_BUFFER * PSTARTING_LCN_INPUT_BUFFER
uint32_t * PULONG
Definition: typedefs.h:59
#define UDFSetFreeBit(arr, bit)
Definition: udf_info.h:1201
#define UDFGetFreeBit(arr, bit)
Definition: udf_info.h:1199

Referenced by UDFUserFsCtrlRequest().

◆ UDFHandleQueryPath()

NTSTATUS NTAPI UDFHandleQueryPath ( PVOID  BufferPointer)

◆ UDFHardLink()

NTSTATUS UDFHardLink ( IN PIO_STACK_LOCATION  PtrSp,
IN PtrUDFFCB  Fcb1,
IN PtrUDFCCB  Ccb1,
IN PFILE_OBJECT  FileObject1,
IN PFILE_LINK_INFORMATION  PtrBuffer 
)

Definition at line 2494 of file fileinfo.cpp.

2501{
2502 // Target Directory
2503 PFILE_OBJECT DirObject2 = PtrSp->Parameters.SetFile.FileObject;
2504 // Overwite Flag
2505 BOOLEAN Replace = PtrSp->Parameters.SetFile.ReplaceIfExists &&
2506 PtrBuffer->ReplaceIfExists;
2507 NTSTATUS RC;
2508 PVCB Vcb = Fcb1->Vcb;
2509 PtrUDFFCB Fcb2;
2510 BOOLEAN ic;
2511 BOOLEAN AcquiredVcb = TRUE;
2512 BOOLEAN AcquiredVcbEx = FALSE;
2513 BOOLEAN AcquiredDir1 = FALSE;
2514 BOOLEAN AcquiredFcb1 = FALSE;
2515 BOOLEAN SingleDir = TRUE;
2516
2517 PUDF_FILE_INFO File1;
2518 PUDF_FILE_INFO Dir1 = NULL;
2519 PUDF_FILE_INFO Dir2;
2520
2522 UNICODE_STRING LocalPath;
2523// PtrUDFCCB CurCcb = NULL;
2524
2525 AdPrint(("UDFHardLink\n"));
2526
2527 LocalPath.Buffer = NULL;
2528
2529 _SEH2_TRY {
2530
2531 // do we try to link Volume ?
2532 if(!(File1 = Fcb1->FileInfo))
2534
2535 // do we try to link RootDir ?
2536 if(!(Dir1 = File1->ParentFile))
2538
2539 // do we try to link Stream / Stream Dir ?
2540#ifdef UDF_ALLOW_LINKS_TO_STREAMS
2541 if(UDFIsAStreamDir(File1))
2543#else //UDF_ALLOW_LINKS_TO_STREAMS
2544 if(UDFIsAStream(File1) || UDFIsAStreamDir(File1) /*||
2545 UDFIsADirectory(File1) || UDFHasAStreamDir(File1)*/)
2547#endif // UDF_ALLOW_LINKS_TO_STREAMS
2548
2549 // do we try to link to RootDir or Volume ?
2550 if(!DirObject2) {
2551 Dir2 = File1->ParentFile;
2552 DirObject2 = FileObject1->RelatedFileObject;
2553 } else
2554 if(DirObject2->FsContext2 &&
2555 (Fcb2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb)) {
2556 Dir2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb->FileInfo;
2557 } else {
2559 }
2560
2561 // check target dir
2562 if(!Dir2) try_return (RC = STATUS_ACCESS_DENIED);
2563
2564 // Stream can't be a Dir or have Streams
2565 if(UDFIsAStreamDir(Dir2)) {
2567/* if(UDFIsADirectory(File1) ||
2568 UDFHasAStreamDir(File1)) {
2569 BrutePoint();
2570 try_return (RC = STATUS_ACCESS_DENIED);
2571 }*/
2572 }
2573
2574/* if(UDFIsAStreamDir(Dir2))
2575 try_return (RC = STATUS_ACCESS_DENIED);*/
2576
2577 RC = UDFPrepareForRenameMoveLink(Vcb, &AcquiredVcb, &AcquiredVcbEx,
2578 &SingleDir,
2579 &AcquiredDir1, &AcquiredFcb1,
2580 Ccb1, File1,
2581 Dir1, Dir2,
2582 TRUE); // it is HLink operation
2583 if(!NT_SUCCESS(RC))
2584 try_return(RC);
2585
2586 // check if the source file is used
2587 if(!DirObject2) {
2588 // Make sure the name is of legal length.
2589 if(PtrBuffer->FileNameLength > UDF_NAME_LEN*sizeof(WCHAR)) {
2591 }
2592 NewName.Length = NewName.MaximumLength = (USHORT)(PtrBuffer->FileNameLength);
2593 NewName.Buffer = (PWCHAR)&(PtrBuffer->FileName);
2594 } else {
2595 // This name is by definition legal.
2596 NewName = *((PUNICODE_STRING)&DirObject2->FileName);
2597 }
2598
2599 ic = (Ccb1->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? FALSE : TRUE;
2600
2601 AdPrint((" %ws ->\n %ws\n",
2602 Fcb1->FCBName->ObjectName.Buffer,
2603 NewName.Buffer));
2604
2605 RC = UDFHardLinkFile__(Vcb, ic, &Replace, &NewName, Dir1, Dir2, File1);
2606 if(!NT_SUCCESS(RC)) try_return (RC);
2607
2608 // Update Parent Objects (mark 'em as modified)
2609 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) {
2610 if(DirObject2) {
2611 DirObject2->Flags |= FO_FILE_MODIFIED;
2612 if(!Replace)
2613 DirObject2->Flags |= FO_FILE_SIZE_CHANGED;
2614 }
2615 }
2616 // report changes
2621
2622 RC = MyCloneUnicodeString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2624 &(Dir2->Fcb->FCBName->ObjectName));
2625 if(!NT_SUCCESS(RC)) try_return (RC);
2626/* RC = MyAppendUnicodeStringToString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? &(UDFGlobalData.UnicodeStrRoot) : &(Dir2->Fcb->FCBName->ObjectName));
2627 if(!NT_SUCCESS(RC)) try_return (RC);*/
2628 // if Dir2 is a RootDir, we shoud not append '\\' because
2629 // it will be the 2nd '\\' character (RootDir's name is also '\\')
2630 if(Dir2->ParentFile) {
2631 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
2632 if(!NT_SUCCESS(RC)) try_return (RC);
2633 }
2634 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &NewName, MEM_USHL_TAG);
2635 if(!NT_SUCCESS(RC)) try_return (RC);
2636
2637 if(!Replace) {
2638/* UDFNotifyFullReportChange( Vcb, File2,
2639 UDFIsADirectory(File1) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2640 FILE_ACTION_ADDED );*/
2641 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2642 (PSTRING)&LocalPath,
2643 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2644 NULL,NULL,
2647 NULL);
2648 } else {
2649/* UDFNotifyFullReportChange( Vcb, File2,
2650 FILE_NOTIFY_CHANGE_ATTRIBUTES |
2651 FILE_NOTIFY_CHANGE_SIZE |
2652 FILE_NOTIFY_CHANGE_LAST_WRITE |
2653 FILE_NOTIFY_CHANGE_LAST_ACCESS |
2654 FILE_NOTIFY_CHANGE_CREATION |
2655 FILE_NOTIFY_CHANGE_EA,
2656 FILE_ACTION_MODIFIED );*/
2657 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2658 (PSTRING)&LocalPath,
2659 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2660 NULL,NULL,
2668 NULL);
2669 }
2670
2671 RC = STATUS_SUCCESS;
2672
2673try_exit: NOTHING;
2674
2675 } _SEH2_FINALLY {
2676
2677 if(AcquiredFcb1) {
2678 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2679 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2680 }
2681 if(AcquiredDir1) {
2682 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2683 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2684 }
2685 if(AcquiredVcb) {
2686 if(AcquiredVcbEx)
2687 UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
2688 } else {
2689 // caller assumes Vcb to be acquired shared
2690 BrutePoint();
2691 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
2692 }
2693
2694 if(LocalPath.Buffer) {
2695 MyFreePool__(LocalPath.Buffer);
2696 }
2697 } _SEH2_END;
2698
2699 return RC;
2700} // end UDFHardLink()
void Replace(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LONG radius)
Definition: drawing.cpp:132
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define UDFConvertExclusiveToSharedLite(Resource)
Definition: env_spec_w32.h:665
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
#define MEM_USHL_TAG
Definition: fileinfo.cpp:26
VOID NTAPI FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext)
Definition: notify.c:1552
unsigned short USHORT
Definition: pedump.c:61
#define UDF_CCB_CASE_SENSETIVE
Definition: struct.h:159
UNICODE_STRING UnicodeStrRoot
Definition: udf_common.h:616
struct _UDF_FILE_INFO * ParentFile
Definition: udf_rel.h:381
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UDF_VCB_IC_UPDATE_DIR_WRITE
Definition: udf_common.h:497
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 STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define FILE_NOTIFY_CHANGE_CREATION
#define FILE_NOTIFY_CHANGE_EA
#define FILE_ACTION_ADDED
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203

Referenced by UDFCommonFileInfo().

◆ UDFInitializeFCB()

NTSTATUS UDFInitializeFCB ( IN PtrUDFFCB  PtrNewFcb,
IN PVCB  Vcb,
IN PtrUDFObjectName  PtrObjectName,
IN ULONG  Flags,
IN PFILE_OBJECT  FileObject 
)

Definition at line 2517 of file create.cpp.

2523{
2524 AdPrint(("UDFInitializeFCB\n"));
2527
2528 if(!PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource) {
2529 // record signature
2530 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode = UDF_NODE_TYPE_NT_REQ_FCB;
2531 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeByteSize = sizeof(UDFNTRequiredFCB);
2532 // Initialize the ERESOURCE objects
2533 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->MainResource)))) {
2534 AdPrint((" Can't init resource\n"));
2535 return status;
2536 }
2537 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->NTRequiredFCB->PagingIoResource)))) {
2538 AdPrint((" Can't init resource (2)\n"));
2539 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2540 return status;
2541 }
2542 // Fill NT required Fcb part
2543 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource = &(PtrNewFcb->NTRequiredFCB->MainResource);
2544 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = &(PtrNewFcb->NTRequiredFCB->PagingIoResource);
2545 // Itialize byte-range locks support structure
2546 FsRtlInitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock),NULL,NULL);
2547 // Init reference counter
2548 PtrNewFcb->NTRequiredFCB->CommonRefCount = 0;
2549 Linked = FALSE;
2550 } else {
2551 ASSERT(PtrNewFcb->NTRequiredFCB->CommonFCBHeader.NodeTypeCode == UDF_NODE_TYPE_NT_REQ_FCB);
2552 }
2553 if(!NT_SUCCESS(status = UDFInitializeResourceLite(&(PtrNewFcb->CcbListResource)))) {
2554 AdPrint((" Can't init resource (3)\n"));
2555 BrutePoint();
2556 if(!Linked) {
2557 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->PagingIoResource));
2558 UDFDeleteResource(&(PtrNewFcb->NTRequiredFCB->MainResource));
2559 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.Resource =
2560 PtrNewFcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource = NULL;
2561 FsRtlUninitializeFileLock(&(PtrNewFcb->NTRequiredFCB->FileLock));
2562 }
2563 return status;
2564 }
2565
2566 // caller MUST ensure that VCB has been acquired exclusively
2567 InsertTailList(&(Vcb->NextFCB), &(PtrNewFcb->NextFCB));
2568
2569 // initialize the various list heads
2570 InitializeListHead(&(PtrNewFcb->NextCCB));
2571
2572 PtrNewFcb->ReferenceCount = 0;
2573 PtrNewFcb->OpenHandleCount = 0;
2574
2575 PtrNewFcb->FCBFlags = Flags | UDF_FCB_INITIALIZED_CCB_LIST_RESOURCE;
2576
2577 PtrNewFcb->FCBName = PtrObjectName;
2578
2579 PtrNewFcb->Vcb = Vcb;
2580
2581 return STATUS_SUCCESS;
2582} // end UDFInitializeFCB()
#define InsertTailList(ListHead, Entry)
#define UDFInitializeResourceLite(Resource)
Definition: env_spec_w32.h:667
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID NTAPI FsRtlInitializeFileLock(IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
Definition: filelock.c:1262
struct _UDFNTRequiredFCB UDFNTRequiredFCB
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by UDFBlankMount(), UDFCompleteMount(), and UDFFirstOpenFile().

◆ UDFInitializeFunctionPointers()

VOID NTAPI UDFInitializeFunctionPointers ( PDRIVER_OBJECT  DriverObject)

Definition at line 444 of file udfinit.cpp.

447{
448 PFAST_IO_DISPATCH PtrFastIoDispatch = NULL;
449
450 // initialize the function pointers for the IRP major
451 // functions that this FSD is prepared to handle ...
452 // NT Version 4.0 has 28 possible functions that a
453 // kernel mode driver can handle.
454 // NT Version 3.51 and before has only 22 such functions,
455 // of which 18 are typically interesting to most FSD's.
456
457 // The only interesting new functions that a FSD might
458 // want to respond to beginning with Version 4.0 are the
459 // IRP_MJ_QUERY_QUOTA and the IRP_MJ_SET_QUOTA requests.
460
461 // The code below does not handle quota manipulation, neither
462 // does the NT Version 4.0 operating system (or I/O Manager).
463 // However, you should be on the lookout for any such new
464 // functionality that the FSD might have to implement in
465 // the near future.
466
467 DriverObject->MajorFunction[IRP_MJ_CREATE] = UDFCreate;
468 DriverObject->MajorFunction[IRP_MJ_CLOSE] = UDFClose;
469 DriverObject->MajorFunction[IRP_MJ_READ] = UDFRead;
470#ifndef UDF_READ_ONLY_BUILD
471 DriverObject->MajorFunction[IRP_MJ_WRITE] = UDFWrite;
472#endif //UDF_READ_ONLY_BUILD
473
475#ifndef UDF_READ_ONLY_BUILD
477#endif //UDF_READ_ONLY_BUILD
478
479#ifndef UDF_READ_ONLY_BUILD
481#endif //UDF_READ_ONLY_BUILD
482 // To implement support for querying and modifying volume attributes
483 // (volume information query/set operations), enable initialization
484 // of the following two function pointers and then implement the supporting
485 // functions.
487#ifndef UDF_READ_ONLY_BUILD
489#endif //UDF_READ_ONLY_BUILD
491 // To implement support for file system IOCTL calls, enable initialization
492 // of the following function pointer and implement appropriate support.
495 DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = UDFShutdown;
496 // For byte-range lock support, enable initialization of the following
497 // function pointer and implement appropriate support.
499 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = UDFCleanup;
500#ifdef UDF_HANDLE_EAS
502#ifndef UDF_READ_ONLY_BUILD
503 DriverObject->MajorFunction[IRP_MJ_SET_EA] = UDFQuerySetEA;
504#endif //UDF_READ_ONLY_BUILD
505#endif //UDF_HANDLE_EAS
506 // If the FSD supports security attributes, we should provide appropriate
507 // dispatch entry points and initialize the function pointers as given below.
508
509#ifdef UDF_ENABLE_SECURITY
511#ifndef UDF_READ_ONLY_BUILD
513#endif //UDF_READ_ONLY_BUILD
514#endif //UDF_ENABLE_SECURITY
515
516// if(MajorVersion >= 0x05) {
517 // w2k and higher
518// DriverObject->MajorFunction[IRP_MJ_PNP] = UDFPnp;
519// }
520
521 // Now, it is time to initialize the fast-io stuff ...
522 PtrFastIoDispatch = DriverObject->FastIoDispatch = &(UDFGlobalData.UDFFastIoDispatch);
523
524 // initialize the global fast-io structure
525 // NOTE: The fast-io structure has undergone a substantial revision
526 // in Windows NT Version 4.0. The structure has been extensively expanded.
527 // Therefore, if the driver needs to work on both V3.51 and V4.0+,
528 // we will have to be able to distinguish between the two versions at compile time.
529
530 RtlZeroMemory(PtrFastIoDispatch, sizeof(FAST_IO_DISPATCH));
531
532 PtrFastIoDispatch->SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH);
534 PtrFastIoDispatch->FastIoRead = FsRtlCopyRead;
535#ifndef UDF_READ_ONLY_BUILD
536 PtrFastIoDispatch->FastIoWrite = UDFFastIoCopyWrite /*FsRtlCopyWrite*/;
537#endif //UDF_READ_ONLY_BUILD
540 PtrFastIoDispatch->FastIoLock = UDFFastLock; // Lock
541 PtrFastIoDispatch->FastIoUnlockSingle = UDFFastUnlockSingle; // UnlockSingle
542 PtrFastIoDispatch->FastIoUnlockAll = UDFFastUnlockAll; // UnlockAll
543 PtrFastIoDispatch->FastIoUnlockAllByKey = (unsigned char (__stdcall *)(struct _FILE_OBJECT *,
544 PVOID ,unsigned long,struct _IO_STATUS_BLOCK *,struct _DEVICE_OBJECT *))UDFFastUnlockAllByKey; // UnlockAllByKey
545
548
549// PtrFastIoDispatch->FastIoDeviceControl = UDFFastIoDeviceControl;
550
551 // the remaining are only valid under NT Version 4.0 and later
552#if(_WIN32_WINNT >= 0x0400)
553
554 PtrFastIoDispatch->FastIoQueryNetworkOpenInfo = UDFFastIoQueryNetInfo;
555
556 PtrFastIoDispatch->AcquireForModWrite = UDFFastIoAcqModWrite;
557 PtrFastIoDispatch->ReleaseForModWrite = UDFFastIoRelModWrite;
558 PtrFastIoDispatch->AcquireForCcFlush = UDFFastIoAcqCcFlush;
559 PtrFastIoDispatch->ReleaseForCcFlush = UDFFastIoRelCcFlush;
560
561/* // MDL functionality
562
563 PtrFastIoDispatch->MdlRead = UDFFastIoMdlRead;
564 PtrFastIoDispatch->MdlReadComplete = UDFFastIoMdlReadComplete;
565 PtrFastIoDispatch->PrepareMdlWrite = UDFFastIoPrepareMdlWrite;
566 PtrFastIoDispatch->MdlWriteComplete = UDFFastIoMdlWriteComplete;*/
567
568 // this FSD does not support compressed read/write functionality,
569 // NTFS does, and if we design a FSD that can provide such functionality,
570 // we should consider initializing the fast io entry points for reading
571 // and/or writing compressed data ...
572#endif // (_WIN32_WINNT >= 0x0400)
573
574 // last but not least, initialize the Cache Manager callback functions
575 // which are used in CcInitializeCacheMap()
576
577 UDFGlobalData.CacheMgrCallBacks.AcquireForLazyWrite = UDFAcqLazyWrite;
578 UDFGlobalData.CacheMgrCallBacks.ReleaseFromLazyWrite = UDFRelLazyWrite;
579 UDFGlobalData.CacheMgrCallBacks.AcquireForReadAhead = UDFAcqReadAhead;
580 UDFGlobalData.CacheMgrCallBacks.ReleaseFromReadAhead = UDFRelReadAhead;
581
582 DriverObject->DriverUnload = UDFDriverUnload;
583
584 return;
585} // end UDFInitializeFunctionPointers()
NTSTATUS NTAPI UDFCleanup(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: cleanup.cpp:43
NTSTATUS NTAPI UDFClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: close.cpp:62
NTSTATUS NTAPI UDFDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: devcntrl.cpp:81
NTSTATUS NTAPI UDFDirControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: dircntrl.cpp:57
unsigned char
Definition: typeof.h:29
NTSTATUS NTAPI UDFCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: create.cpp:48
NTSTATUS NTAPI UDFQuerySetEA(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: misc.cpp:2484
BOOLEAN NTAPI UDFAcqReadAhead(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:514
VOID NTAPI UDFFastIoRelCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:387
BOOLEAN NTAPI UDFFastIoCopyWrite(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:1160
VOID NTAPI UDFRelReadAhead(IN PVOID Context)
Definition: fastio.cpp:558
BOOLEAN NTAPI UDFAcqLazyWrite(IN PVOID Context, IN BOOLEAN Wait)
Definition: fastio.cpp:423
BOOLEAN NTAPI UDFFastIoQueryStdInfo(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:250
VOID NTAPI UDFRelLazyWrite(IN PVOID Context)
Definition: fastio.cpp:472
VOID NTAPI UDFFastIoAcqCreateSec(IN PFILE_OBJECT FileObject)
Definition: fastio.cpp:342
BOOLEAN NTAPI UDFFastIoQueryBasicInfo(IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:159
BOOLEAN NTAPI UDFFastIoCheckIfPossible(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN BOOLEAN CheckForReadOperation, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.cpp:42
NTSTATUS NTAPI UDFFileInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fileinfo.cpp:46
NTSTATUS NTAPI UDFFlush(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: flush.cpp:42
NTSTATUS NTAPI UDFFSControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: fscntrl.cpp:39
BOOLEAN NTAPI UDFFastUnlockSingle(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:309
NTSTATUS NTAPI UDFLockControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: lockctrl.cpp:38
BOOLEAN NTAPI UDFFastLock(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, PEPROCESS ProcessId, ULONG Key, BOOLEAN FailImmediately, BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:205
BOOLEAN NTAPI UDFFastUnlockAllByKey(IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:494
BOOLEAN NTAPI UDFFastUnlockAll(IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: lockctrl.cpp:404
BOOLEAN NTAPI FsRtlCopyRead(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
Definition: fastio.c:64
NTSTATUS NTAPI UDFQueryVolInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volinfo.cpp:86
OSSTATUS NTAPI UDFRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: read.cpp:53
NTSTATUS NTAPI UDFWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: write.cpp:42
VOID NTAPI UDFDriverUnload(IN PDRIVER_OBJECT DriverObject)
Definition: unload.cpp:10
NTSTATUS UDFSetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS UDFGetSecurity(PDEVICE_OBJECT DeviceObject, PIRP Irp)
NTSTATUS NTAPI UDFShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: shutdown.cpp:47
NTSTATUS NTAPI UDFSetVolInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: volinfo.cpp:617
#define long
Definition: qsort.c:33
#define IRP_MJ_DIRECTORY_CONTROL
Definition: rdpdr.c:51
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_QUERY_VOLUME_INFORMATION
Definition: rdpdr.c:50
#define IRP_MJ_LOCK_CONTROL
Definition: rdpdr.c:53
PFAST_IO_ACQUIRE_FOR_MOD_WRITE AcquireForModWrite
Definition: iotypes.h:1748
PFAST_IO_QUERY_STANDARD_INFO FastIoQueryStandardInfo
Definition: iotypes.h:1738
PFAST_IO_UNLOCK_ALL_BY_KEY FastIoUnlockAllByKey
Definition: iotypes.h:1742
PFAST_IO_RELEASE_FOR_CCFLUSH ReleaseForCcFlush
Definition: iotypes.h:1760
PFAST_IO_WRITE FastIoWrite
Definition: iotypes.h:1736
PFAST_IO_UNLOCK_ALL FastIoUnlockAll
Definition: iotypes.h:1741
PFAST_IO_QUERY_NETWORK_OPEN_INFO FastIoQueryNetworkOpenInfo
Definition: iotypes.h:1747
PFAST_IO_ACQUIRE_FOR_CCFLUSH AcquireForCcFlush
Definition: iotypes.h:1759
ULONG SizeOfFastIoDispatch
Definition: iotypes.h:1733
PFAST_IO_ACQUIRE_FILE AcquireFileForNtCreateSection
Definition: iotypes.h:1744
PFAST_IO_READ FastIoRead
Definition: iotypes.h:1735
PFAST_IO_QUERY_BASIC_INFO FastIoQueryBasicInfo
Definition: iotypes.h:1737
PFAST_IO_LOCK FastIoLock
Definition: iotypes.h:1739
PFAST_IO_UNLOCK_SINGLE FastIoUnlockSingle
Definition: iotypes.h:1740
PFAST_IO_RELEASE_FILE ReleaseFileForNtCreateSection
Definition: iotypes.h:1745
PFAST_IO_RELEASE_FOR_MOD_WRITE ReleaseForModWrite
Definition: iotypes.h:1758
PFAST_IO_CHECK_IF_POSSIBLE FastIoCheckIfPossible
Definition: iotypes.h:1734
void * PVOID
Definition: typedefs.h:50
#define __stdcall
Definition: typedefs.h:25
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define IRP_MJ_QUERY_EA
#define IRP_MJ_FILE_SYSTEM_CONTROL
#define IRP_MJ_SET_VOLUME_INFORMATION
#define IRP_MJ_QUERY_SECURITY
#define IRP_MJ_SET_EA
struct _FAST_IO_DISPATCH FAST_IO_DISPATCH
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_SET_SECURITY
#define IRP_MJ_CLEANUP

Referenced by DriverEntry().

◆ UDFInitializeIrpContextFromLite()

VOID UDFInitializeIrpContextFromLite ( OUT PtrUDFIrpContext IrpContext,
IN PtrUDFIrpContextLite  IrpContextLite 
)

Definition at line 2419 of file misc.cpp.

2423{
2424 (*IrpContext) = UDFAllocateIrpContext(NULL, IrpContextLite->RealDevice);
2425 // Zero and then initialize the structure.
2426
2427 // Major/Minor Function codes
2428 (*IrpContext)->MajorFunction = IRP_MJ_CLOSE;
2429 (*IrpContext)->Fcb = IrpContextLite->Fcb;
2430 (*IrpContext)->TreeLength = IrpContextLite->TreeLength;
2431 (*IrpContext)->IrpContextFlags |= (IrpContextLite->IrpContextFlags & ~UDF_IRP_CONTEXT_NOT_FROM_ZONE);
2432
2433 // Set the wait parameter
2434 UDFSetFlag( (*IrpContext)->IrpContextFlags, UDF_IRP_CONTEXT_CAN_BLOCK );
2435
2436 return;
2437} // end UDFInitializeIrpContextFromLite()

Referenced by UDFDoDelayedClose().

◆ UDFInitializeIrpContextLite()

NTSTATUS UDFInitializeIrpContextLite ( OUT PtrUDFIrpContextLite IrpContextLite,
IN PtrUDFIrpContext  IrpContext,
IN PtrUDFFCB  Fcb 
)

Definition at line 2457 of file misc.cpp.

2462{
2464 if(!LocalIrpContextLite)
2466 // Zero and then initialize the structure.
2467 RtlZeroMemory( LocalIrpContextLite, sizeof( UDFIrpContextLite ));
2468
2470 LocalIrpContextLite->NodeIdentifier.NodeSize = sizeof(UDFIrpContextLite);
2471
2472 LocalIrpContextLite->Fcb = Fcb;
2473 LocalIrpContextLite->TreeLength = IrpContext->TreeLength;
2474 // Copy RealDevice for workque algorithms.
2475 LocalIrpContextLite->RealDevice = IrpContext->TargetDeviceObject;
2476 LocalIrpContextLite->IrpContextFlags = IrpContext->IrpContextFlags;
2477 *IrpContextLite = LocalIrpContextLite;
2478
2479 return STATUS_SUCCESS;
2480} // end UDFInitializeIrpContextLite()
#define UDF_NODE_TYPE_IRP_CONTEXT_LITE
Definition: struct.h:66
struct _UDFIrpContextLite * PtrUDFIrpContextLite
struct _UDFIrpContextLite UDFIrpContextLite
PDEVICE_OBJECT RealDevice
Definition: struct.h:414
UDFIdentifier NodeIdentifier
Definition: struct.h:406
uint32 IrpContextFlags
Definition: struct.h:416
ULONG TreeLength
Definition: struct.h:415

Referenced by UDFQueueDelayedClose().

◆ UDFInitializeVCB()

NTSTATUS UDFInitializeVCB ( PDEVICE_OBJECT  PtrVolumeDeviceObject,
PDEVICE_OBJECT  PtrTargetDeviceObject,
PVPB  PtrVPB 
)

◆ UDFInitializeZones()

NTSTATUS UDFInitializeZones ( VOID  )

Definition at line 41 of file misc.cpp.

42{
44 uint32 SizeOfZone = UDFGlobalData.DefaultZoneSizeInNumStructs;
45 uint32 SizeOfObjectNameZone = 0;
46 uint32 SizeOfCCBZone = 0;
47// uint32 SizeOfFCBZone = 0;
48 uint32 SizeOfIrpContextZone = 0;
49// uint32 SizeOfFileInfoZone = 0;
50
51 _SEH2_TRY {
52
53 // initialize the spinlock protecting the zones
54 KeInitializeSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock));
55
56 // determine memory requirements
57 switch (MmQuerySystemSize()) {
58 case MmMediumSystem:
59 SizeOfObjectNameZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
60 SizeOfCCBZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
61 SizeOfIrpContextZone = (4 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
62 UDFGlobalData.MaxDelayedCloseCount = 24;
63 UDFGlobalData.MinDelayedCloseCount = 6;
64 UDFGlobalData.MaxDirDelayedCloseCount = 8;
65 UDFGlobalData.MinDirDelayedCloseCount = 2;
70 break;
71 case MmLargeSystem:
72 SizeOfObjectNameZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
73 SizeOfCCBZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
74 SizeOfIrpContextZone = (8 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
75 UDFGlobalData.MaxDelayedCloseCount = 72;
76 UDFGlobalData.MinDelayedCloseCount = 18;
77 UDFGlobalData.MaxDirDelayedCloseCount = 24;
78 UDFGlobalData.MinDirDelayedCloseCount = 6;
83 break;
84 case MmSmallSystem:
85 default:
86 SizeOfObjectNameZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFObjectName))) + sizeof(ZONE_SEGMENT_HEADER);
87 SizeOfCCBZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFCCB))) + sizeof(ZONE_SEGMENT_HEADER);
88 SizeOfIrpContextZone = (2 * SizeOfZone * UDFQuadAlign(sizeof(UDFIrpContext))) + sizeof(ZONE_SEGMENT_HEADER);
89 UDFGlobalData.MaxDelayedCloseCount = 8;
90 UDFGlobalData.MinDelayedCloseCount = 2;
91 UDFGlobalData.MaxDirDelayedCloseCount = 6;
92 UDFGlobalData.MinDirDelayedCloseCount = 1;
97 }
98
99 // typical NT methodology (at least until *someone* exposed the "difference" between a server and workstation ;-)
100 if (MmIsThisAnNtAsSystem()) {
101 SizeOfObjectNameZone *= UDF_NTAS_MULTIPLE;
102 SizeOfCCBZone *= UDF_NTAS_MULTIPLE;
103 SizeOfIrpContextZone *= UDF_NTAS_MULTIPLE;
104 }
105
106 // allocate memory for each of the zones and initialize the zones ...
107 if (!(UDFGlobalData.ObjectNameZone = DbgAllocatePool(NonPagedPool, SizeOfObjectNameZone))) {
109 try_return(RC);
110 }
111
112 if (!(UDFGlobalData.CCBZone = DbgAllocatePool(NonPagedPool, SizeOfCCBZone))) {
114 try_return(RC);
115 }
116
117 if (!(UDFGlobalData.IrpContextZone = DbgAllocatePool(NonPagedPool, SizeOfIrpContextZone))) {
119 try_return(RC);
120 }
121
122 // initialize each of the zone headers ...
123 if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.ObjectNameZoneHeader),
125 UDFGlobalData.ObjectNameZone, SizeOfObjectNameZone))) {
126 // failed the initialization, leave ...
127 try_return(RC);
128 }
129
130 if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.CCBZoneHeader),
131 UDFQuadAlign(sizeof(UDFCCB)),
132 UDFGlobalData.CCBZone,
133 SizeOfCCBZone))) {
134 // failed the initialization, leave ...
135 try_return(RC);
136 }
137
138 if (!NT_SUCCESS(RC = ExInitializeZone(&(UDFGlobalData.IrpContextZoneHeader),
140 UDFGlobalData.IrpContextZone,
141 SizeOfIrpContextZone))) {
142 // failed the initialization, leave ...
143 try_return(RC);
144 }
145
146try_exit: NOTHING;
147
148 } _SEH2_FINALLY {
149 if (!NT_SUCCESS(RC)) {
150 // invoke the destroy routine now ...
152 } else {
153 // mark the fact that we have allocated zones ...
155 }
156 } _SEH2_END;
157
158 return(RC);
159}
#define DbgAllocatePool
Definition: env_spec_w32.h:332
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
MM_SYSTEMSIZE NTAPI MmQuerySystemSize(VOID)
Definition: mmsup.c:257
BOOLEAN NTAPI MmIsThisAnNtAsSystem(VOID)
Definition: mmsup.c:246
#define UDF_NTAS_MULTIPLE
Definition: struct.h:437
ULONG WCacheFramesToKeepFree
Definition: udf_common.h:624
ULONG WCacheBlocksPerFrameSh
Definition: udf_common.h:623
ULONG WCacheMaxFrames
Definition: udf_common.h:621
ULONG WCacheMaxBlocks
Definition: udf_common.h:622
ZONE_SEGMENT_HEADER
Definition: extypes.h:331
@ MmLargeSystem
Definition: mmtypes.h:147
@ MmMediumSystem
Definition: mmtypes.h:146
@ MmSmallSystem
Definition: mmtypes.h:145
NTSTATUS NTAPI ExInitializeZone(PZONE_HEADER Zone, ULONG BlockSize, PVOID InitialSegment, ULONG InitialSegmentSize)
Definition: zone.c:105

Referenced by DriverEntry().

◆ UDFInvalidateVolumes()

NTSTATUS UDFInvalidateVolumes ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 2441 of file fscntrl.cpp.

2445{
2446 NTSTATUS RC;
2450
2451 UDFPrint(("UDFInvalidateVolumes\n"));
2452
2453 KIRQL SavedIrql;
2454
2455 LUID TcbPrivilege = {SE_TCB_PRIVILEGE, 0};
2456
2457 HANDLE Handle;
2458
2459 PVPB NewVpb;
2460 PVCB Vcb;
2461
2463
2464 PFILE_OBJECT FileToMarkBad;
2465 PDEVICE_OBJECT DeviceToMarkBad;
2466
2467 Irp->IoStatus.Information = 0;
2468
2469 // Check for the correct security access.
2470 // The caller must have the SeTcbPrivilege.
2473 IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES &&
2474 !SeSinglePrivilegeCheck( TcbPrivilege, UserMode )) {
2475 UDFPrintErr(("UDFInvalidateVolumes: STATUS_PRIVILEGE_NOT_HELD\n"));
2476 Irp->IoStatus.Status = STATUS_PRIVILEGE_NOT_HELD;
2478 }
2479 // Try to get a pointer to the device object from the handle passed in.
2480 if (IrpSp->Parameters.FileSystemControl.InputBufferLength != sizeof( HANDLE )) {
2481 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INVALID_PARAMETER\n"));
2482 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2484 }
2485
2486 Handle = *((PHANDLE) Irp->AssociatedIrp.SystemBuffer);
2487
2489 0,
2491 KernelMode,
2492 (PVOID*)&FileToMarkBad,
2493 NULL );
2494
2495 if (!NT_SUCCESS(RC)) {
2496 UDFPrintErr(("UDFInvalidateVolumes: can't get handle, RC=%x\n", RC));
2497 Irp->IoStatus.Status = RC;
2498 return RC;
2499 }
2500
2501 // We only needed the pointer, not a reference.
2502 ObDereferenceObject( FileToMarkBad );
2503
2504 // Grab the DeviceObject from the FileObject.
2505 DeviceToMarkBad = FileToMarkBad->DeviceObject;
2506
2507 // Create a new Vpb for this device so that any new opens will mount
2508 // a new volume.
2509 NewVpb = (PVPB)DbgAllocatePoolWithTag( NonPagedPool, sizeof( VPB ), 'bpvU' );
2510 if(!NewVpb) {
2511 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INSUFFICIENT_RESOURCES\n"));
2512 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2514 }
2515 RtlZeroMemory( NewVpb, sizeof( VPB ) );
2516
2517 NewVpb->Type = IO_TYPE_VPB;
2518 NewVpb->Size = sizeof( VPB );
2519 NewVpb->RealDevice = DeviceToMarkBad;
2520 NewVpb->Flags = DeviceToMarkBad->Vpb->Flags & VPB_REMOVE_PENDING;
2521
2522 // Acquire GlobalDataResource
2523 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
2524
2525 // Nothing can go wrong now.
2526 IoAcquireVpbSpinLock( &SavedIrql );
2527 if (DeviceToMarkBad->Vpb->Flags & VPB_MOUNTED) {
2528 DeviceToMarkBad->Vpb = NewVpb;
2529 NewVpb = NULL;
2530 }
2531 ASSERT( DeviceToMarkBad->Vpb->DeviceObject == NULL );
2532 IoReleaseVpbSpinLock( SavedIrql );
2533
2534 if (NewVpb) {
2535 DbgFreePool( NewVpb );
2536 }
2537
2538 // Walk through all of the Vcb's attached to the global data.
2539 Link = UDFGlobalData.VCBQueue.Flink;
2540
2541 //ASSERT(FALSE);
2542
2543 while (Link != &(UDFGlobalData.VCBQueue)) {
2544 // Get 'next' Vcb
2545 Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
2546 // Move to the next link now since the current Vcb may be deleted.
2547 Link = Link->Flink;
2548
2549 // Acquire Vcb resource
2550 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
2551
2552 if (Vcb->Vpb->RealDevice == DeviceToMarkBad) {
2553
2554 if(!Buf) {
2556 if(!Buf) {
2557 UDFPrintErr(("UDFInvalidateVolumes: STATUS_INSUFFICIENT_RESOURCES (2)\n"));
2558 UDFReleaseResource(&(Vcb->VCBResource));
2559 MyFreePool__(NewVpb);
2560 Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
2562 }
2563 }
2564
2565#ifdef UDF_DELAYED_CLOSE
2566 UDFPrint((" UDFInvalidateVolumes: set UDF_VCB_FLAGS_NO_DELAYED_CLOSE\n"));
2568 UDFReleaseResource(&(Vcb->VCBResource));
2569#endif //UDF_DELAYED_CLOSE
2570
2571 if(Vcb->RootDirFCB && Vcb->RootDirFCB->FileInfo) {
2572 UDFPrint((" UDFInvalidateVolumes: UDFCloseAllSystemDelayedInDir\n"));
2573 RC = UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
2574 ASSERT(OS_SUCCESS(RC));
2575 }
2576#ifdef UDF_DELAYED_CLOSE
2577 UDFPrint((" UDFInvalidateVolumes: UDFCloseAllDelayed\n"));
2579 //ASSERT(OS_SUCCESS(RC));
2580#endif //UDF_DELAYED_CLOSE
2581
2582 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE);
2583
2585 UDFReleaseResource(&(Vcb->VCBResource));
2586
2588 UDFPrint(("UDFInvalidateVolumes: Vcb %x dismounted\n", Vcb));
2589 break;
2590 } else {
2591 UDFPrint(("UDFInvalidateVolumes: skip Vcb %x\n", Vcb));
2592 UDFReleaseResource(&(Vcb->VCBResource));
2593 }
2594
2595 }
2596 // Once we have processed all the mounted logical volumes, we can release
2597 // all acquired global resources and leave (in peace :-)
2598 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
2599
2600 Irp->IoStatus.Status = STATUS_SUCCESS;
2601
2602 if(Buf) {
2603 UDFPrint(("UDFInvalidateVolumes: free buffer\n"));
2604 MyFreePool__(Buf);
2605 }
2606
2607 // drop volume completly
2608 UDFPrint(("UDFInvalidateVolumes: drop volume completly\n"));
2609 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
2610 UDFScanForDismountedVcb(IrpContext);
2611 UDFReleaseResource( &(UDFGlobalData.GlobalDataResource) );
2612
2613 UDFPrint(("UDFInvalidateVolumes: done\n"));
2614 return STATUS_SUCCESS;
2615
2616} // end UDFInvalidateVolumes()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
VOID UDFScanForDismountedVcb(IN PtrUDFIrpContext IrpContext)
Definition: fscntrl.cpp:1510
ULONG Handle
Definition: gdb_input.c:15
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
#define SE_TCB_PRIVILEGE
Definition: security.c:661
#define FSCTL_INVALIDATE_VOLUMES
Definition: nt_native.h:847
#define VPB_REMOVE_PENDING
Definition: ntifs_ex.h:428
USHORT Flags
Definition: iotypes.h:192
#define VPB_MOUNTED
Definition: iotypes.h:1807

Referenced by UDFCommonDeviceControl(), and UDFUserFsCtrlRequest().

◆ UDFIsFastIoPossible()

FAST_IO_POSSIBLE NTAPI UDFIsFastIoPossible ( IN PtrUDFFCB  Fcb)

Definition at line 118 of file fastio.cpp.

121{
122 if( !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) /*||
123 !FsRtlOplockIsFastIoPossible(&(Fcb->Oplock))*/ ) {
124 UDFPrint((" FastIoIsNotPossible\n"));
125 return FastIoIsNotPossible;
126 }
127/*
128 // back pressure for very smart and fast system cache ;)
129 if(Fcb->Vcb->VerifyCtx.ItemCount >= UDF_MAX_VERIFY_CACHE) {
130 AdPrint((" Verify queue overflow -> UDFIsFastIoPossible() = FastIoIsNotPossible\n"));
131 return FastIoIsNotPossible;
132 }
133*/
134 if(FsRtlAreThereCurrentFileLocks(&(Fcb->NTRequiredFCB->FileLock)) ) {
135 UDFPrint((" FastIoIsQuestionable\n"));
137 }
138 UDFPrint((" FastIoIsPossible\n"));
139 return FastIoIsPossible;
140} // end UDFIsFastIoPossible()
#define FsRtlAreThereCurrentFileLocks(FL)
Definition: fsrtlfuncs.h:1584
@ FastIoIsQuestionable
Definition: fsrtltypes.h:242
@ FastIoIsNotPossible
Definition: fsrtltypes.h:240

Referenced by UDFCommonCleanup(), UDFCommonCreate(), UDFCommonRead(), UDFCommonWrite(), UDFFastLock(), UDFFastUnlockAll(), UDFFastUnlockAllByKey(), UDFFastUnlockSingle(), UDFSetAllocationInformation(), and UDFSetEOF().

◆ UDFIsIrpTopLevel()

BOOLEAN __fastcall UDFIsIrpTopLevel ( PIRP  Irp)

Definition at line 228 of file misc.cpp.

230{
231 if(!IoGetTopLevelIrp()) {
232 // OK, so we can set ourselves to become the "top level" component
234 return TRUE;
235 }
236 return FALSE;
237}

Referenced by UDFCleanup(), UDFClose(), UDFCreate(), UDFDeviceControl(), UDFDirControl(), UDFFileInfo(), UDFFlush(), UDFFSControl(), UDFLockControl(), UDFPnp(), UDFQuerySetEA(), UDFQueryVolInfo(), UDFRead(), UDFSetVolInfo(), UDFShutdown(), and UDFWrite().

◆ UDFIsPathnameValid()

NTSTATUS UDFIsPathnameValid ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 1660 of file fscntrl.cpp.

1664{
1666 NTSTATUS RC;
1667 PPATHNAME_BUFFER PathnameBuffer;
1668 UNICODE_STRING PathName;
1669 UNICODE_STRING CurName;
1670 PWCHAR TmpBuffer;
1671
1672 UDFPrint(("UDFIsPathnameValid\n"));
1673
1674 // Extract the pathname
1675 PathnameBuffer = (PPATHNAME_BUFFER)Irp->AssociatedIrp.SystemBuffer;
1676 PathName.Buffer = PathnameBuffer->Name;
1677 PathName.Length = (USHORT)PathnameBuffer->PathNameLength;
1678
1679 _SEH2_TRY {
1680 // Check for an invalid buffer
1681 if (FIELD_OFFSET(PATHNAME_BUFFER, Name[0]) + PathnameBuffer->PathNameLength >
1682 IrpSp->Parameters.FileSystemControl.InputBufferLength) {
1684 }
1685 while (TRUE) {
1686 // get next path part...
1687 TmpBuffer = PathName.Buffer;
1688 PathName.Buffer = UDFDissectName(PathName.Buffer,&(CurName.Length) );
1689 PathName.Length -= (USHORT)((ULONG_PTR)(PathName.Buffer) - (ULONG_PTR)TmpBuffer);
1690 CurName.Buffer = PathName.Buffer - CurName.Length;
1691 CurName.Length *= sizeof(WCHAR);
1692 CurName.MaximumLength -= CurName.Length;
1693
1694 if (CurName.Length) {
1695 // check path fragment size
1696 if (CurName.Length > UDF_NAME_LEN*sizeof(WCHAR)) {
1698 }
1699 if (!UDFIsNameValid(&CurName, NULL, NULL)) {
1701 }
1702 } else {
1704 }
1705 }
1706try_exit: NOTHING;
1707 } _SEH2_FINALLY {
1708 Irp->IoStatus.Information = 0;
1709 Irp->IoStatus.Status = RC;
1710 } _SEH2_END;
1711
1712 return RC;
1713} // end UDFIsPathnameValid()
BOOLEAN __fastcall UDFIsNameValid(IN PUNICODE_STRING SearchPattern, OUT BOOLEAN *StreamOpen, OUT ULONG *SNameIndex)
Definition: namesup.cpp:92
PWCHAR __fastcall UDFDissectName(IN PWCHAR Buffer, OUT PUSHORT Length)
Definition: namesup.cpp:19
ULONG PathNameLength
Definition: iotypes.h:6229
WCHAR Name[1]
Definition: iotypes.h:6230
struct _PATHNAME_BUFFER * PPATHNAME_BUFFER

Referenced by UDFUserFsCtrlRequest().

◆ UDFIsResourceAcquired()

ULONG UDFIsResourceAcquired ( IN PERESOURCE  Resource)

Definition at line 2518 of file misc.cpp.

2521{
2522 ULONG ReAcqRes =
2525 return ReAcqRes;
2526} // end UDFIsResourceAcquired()

Referenced by UDFCommonRead(), and UDFCommonWrite().

◆ UDFIsVolumeDirty()

NTSTATUS UDFIsVolumeDirty ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 2367 of file fscntrl.cpp.

2371{
2375
2376 PVCB Vcb;
2377 PtrUDFFCB Fcb;
2378 PtrUDFCCB Ccb;
2379
2380 UDFPrint(("UDFIsVolumeDirty\n"));
2381
2382 Irp->IoStatus.Information = 0;
2383
2384 if (Irp->AssociatedIrp.SystemBuffer != NULL) {
2385 VolumeState = (PULONG)(Irp->AssociatedIrp.SystemBuffer);
2386 } else if (Irp->MdlAddress != NULL) {
2388 } else {
2389 UDFPrintErr((" STATUS_INVALID_USER_BUFFER\n"));
2390 Irp->IoStatus.Status = STATUS_INVALID_USER_BUFFER;
2392 }
2393
2394 if (IrpSp->Parameters.FileSystemControl.OutputBufferLength < sizeof(ULONG)) {
2395 UDFPrintErr((" STATUS_BUFFER_TOO_SMALL\n"));
2396 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
2398 }
2399
2400 (*VolumeState) = 0;
2401
2402 // Decode the file object, the only type of opens we accept are
2403 // user volume opens.
2404 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
2405 if(!Ccb) {
2406 UDFPrintErr((" !Ccb\n"));
2407 Irp->IoStatus.Information = 0;
2408 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2410 }
2411 Fcb = Ccb->Fcb;
2412 Vcb = Fcb->Vcb;
2413
2414 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
2415 UDFPrintErr((" !Volume\n"));
2416 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
2418 }
2419
2420 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
2421 UDFPrintErr((" !Mounted\n"));
2422 Irp->IoStatus.Status = STATUS_VOLUME_DISMOUNTED;
2424 }
2425
2426 if(Vcb->origIntegrityType == INTEGRITY_TYPE_OPEN) {
2427 UDFPrint((" Dirty\n"));
2428 (*VolumeState) |= VOLUME_IS_DIRTY;
2429 Irp->IoStatus.Information = sizeof(ULONG);
2430 } else {
2431 UDFPrint((" Clean\n"));
2432 }
2433 Irp->IoStatus.Status = STATUS_SUCCESS;
2434
2435 return STATUS_SUCCESS;
2436
2437} // end UDFIsVolumeDirty()
IN PVCB IN FAT_VOLUME_STATE VolumeState
Definition: fatprocs.h:1998
#define VOLUME_IS_DIRTY
Definition: ntifs_ex.h:330
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:747
#define MmGetSystemAddressForMdl(Mdl)

Referenced by UDFCommonDeviceControl(), and UDFUserFsCtrlRequest().

◆ UDFIsVolumeMounted()

NTSTATUS UDFIsVolumeMounted ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp 
)

Definition at line 1552 of file fscntrl.cpp.

1556{
1558
1559 PtrUDFFCB Fcb;
1560 PtrUDFCCB Ccb;
1561
1562 UDFPrint(("UDFIsVolumeMounted\n"));
1563
1564 Ccb = (PtrUDFCCB)IrpSp->FileObject->FsContext2;
1565 if(!Ccb) {
1566 UDFPrintErr((" !Ccb\n"));
1567 Irp->IoStatus.Information = 0;
1568 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1570 }
1571 Fcb = Ccb->Fcb;
1572
1573 if(Fcb &&
1574 !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
1575 !(Fcb->Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) ) {
1576
1577 // Disable PopUps, we want to return any error.
1578 IrpContext->IrpContextFlags |= UDF_IRP_CONTEXT_FLAG_DISABLE_POPUPS;
1579
1580 // Verify the Vcb. This will raise in the error condition.
1581 UDFVerifyVcb( IrpContext, Fcb->Vcb );
1582 }
1583
1584 Irp->IoStatus.Information = 0;
1585 Irp->IoStatus.Status = STATUS_SUCCESS;
1586
1587 return STATUS_SUCCESS;
1588} // end UDFIsVolumeMounted()

Referenced by UDFUserFsCtrlRequest().

◆ UDFLockCallersBuffer()

NTSTATUS UDFLockCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
BOOLEAN  IsReadOperation,
uint32  Length 
)

Definition at line 936 of file read.cpp.

942{
944 PMDL PtrMdl = NULL;
945
946 UDFPrint(("UDFLockCallersBuffer: \n"));
947
948 ASSERT(Irp);
949
950 _SEH2_TRY {
951 // Is a MDL already present in the IRP
952 if (!(Irp->MdlAddress)) {
953 // Allocate a MDL
954/*
955 if(!IsReadOperation) {
956 MmPrint((" Allocate TransitionBuffer\n"));
957 PtrIrpContext->TransitionBuffer = (PCHAR)DbgAllocatePool(NonPagedPool, Length);
958 if(!PtrIrpContext->TransitionBuffer) {
959 RC = STATUS_INSUFFICIENT_RESOURCES;
960 try_return(RC);
961 }
962 _SEH2_TRY {
963 RtlCopyMemory(PtrIrpContext->TransitionBuffer, Irp->UserBuffer, Length);
964 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
965 RC = STATUS_INVALID_USER_BUFFER;
966 } _SEH2_END;
967 } else*/ {
968
969 MmPrint((" IoAllocateMdl()\n"));
970// if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, NULL))) {
971
972 // This will place allocated Mdl to Irp
973 if (!(PtrMdl = IoAllocateMdl(Irp->UserBuffer, Length, FALSE, FALSE, Irp))) {
975 try_return(RC);
976 }
977 MmPrint((" Alloc MDL=%x\n", PtrMdl));
978#ifdef UDF_DBG
979 BuildMdlCounter++;
980#endif //UDF_DBG
981 }
982 // Probe and lock the pages described by the MDL
983 // We could encounter an exception doing so, swallow the exception
984 // NOTE: The exception could be due to an unexpected (from our
985 // perspective), invalidation of the virtual addresses that comprise
986 // the passed in buffer
987#ifndef POST_LOCK_PAGES
988 _SEH2_TRY {
989 MmPrint((" MmProbeAndLockPages()\n"));
990 MmProbeAndLockPages(PtrMdl, Irp->RequestorMode, (IsReadOperation ? IoWriteAccess:IoReadAccess));
992 MmPrint((" MmProbeAndLockPages() failed\n"));
993 Irp->MdlAddress = NULL;
995 } _SEH2_END;
996#endif //POST_LOCK_PAGES
997
998 if(NT_SUCCESS(RC)) {
1000 PtrIrpContext->PtrMdl = PtrMdl;
1001 }
1002 } else {
1003 MmPrint((" UDFLockCallersBuffer: do nothing, MDL=%x\n", Irp->MdlAddress));
1004 UDFTouch(Irp->MdlAddress);
1005 }
1006
1007try_exit: NOTHING;
1008
1009 } _SEH2_FINALLY {
1010 if (!NT_SUCCESS(RC) && PtrMdl) {
1011 MmPrint((" Free MDL=%x\n", PtrMdl));
1012 IoFreeMdl(PtrMdl);
1013 }
1014 } _SEH2_END;
1015
1016 return(RC);
1017} // end UDFLockCallersBuffer()
#define IoFreeMdl
Definition: fxmdl.h:89
#define IoAllocateMdl
Definition: fxmdl.h:88

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFQueryDirectory().

◆ UDFLockControl()

NTSTATUS NTAPI UDFLockControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 38 of file lockctrl.cpp.

41{
43 PtrUDFIrpContext PtrIrpContext = NULL;
44 BOOLEAN AreWeTopLevel = FALSE;
45
46 UDFPrint(("UDFLockControl\n"));
47// BrutePoint();
48
51 ASSERT(Irp);
52
53 // set the top level context
54 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
55 // Call the common Lock Control routine, with blocking allowed if
56 // synchronous
57 _SEH2_TRY {
58
59 // get an IRP context structure and issue the request
60 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
61 if(PtrIrpContext) {
62 RC = UDFCommonLockControl(PtrIrpContext, Irp);
63 } else {
65 Irp->IoStatus.Status = RC;
66 Irp->IoStatus.Information = 0;
67 // complete the IRP
69 }
70
72
73 RC = UDFExceptionHandler(PtrIrpContext, Irp);
74
76 } _SEH2_END;
77
78 if (AreWeTopLevel) {
80 }
81
83
84 return(RC);
85} // end UDFLockControl()
NTSTATUS NTAPI UDFCommonLockControl(IN PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: lockctrl.cpp:105

Referenced by UDFInitializeFunctionPointers().

◆ UDFLockVolume()

NTSTATUS UDFLockVolume ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp,
IN ULONG  PID = -1 
)

Definition at line 1724 of file fscntrl.cpp.

1729{
1730 NTSTATUS RC;
1731
1732 KIRQL SavedIrql;
1734
1735 PVCB Vcb;
1736 PtrUDFFCB Fcb;
1737 PtrUDFCCB Ccb;
1738 BOOLEAN VcbAcquired = FALSE;
1739
1740 UDFPrint(("UDFLockVolume: PID %x\n", PID));
1741
1742 // Decode the file object, the only type of opens we accept are
1743 // user volume opens.
1744 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1745 if(!Ccb) {
1746 UDFPrintErr((" !Ccb\n"));
1747 Irp->IoStatus.Information = 0;
1748 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1750 }
1751 Fcb = Ccb->Fcb;
1752 Vcb = Fcb->Vcb;
1753
1754 // Check for volume open
1755 if (Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1756 Irp->IoStatus.Information = 0;
1757 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1759 }
1760
1762
1763 _SEH2_TRY {
1764
1765 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK))
1766 UDFCloseAllSystemDelayedInDir(Vcb, Vcb->RootDirFCB->FileInfo);
1767#ifdef UDF_DELAYED_CLOSE
1769#endif //UDF_DELAYED_CLOSE
1770
1771 // Acquire exclusive access to the Vcb.
1772 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1773 VcbAcquired = TRUE;
1774
1775 // Verify the Vcb.
1776 UDFVerifyVcb( IrpContext, Vcb );
1777
1778 // If the volume is already locked then complete with success if this file
1779 // object has the volume locked, fail otherwise.
1780/* if (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED) {
1781
1782 if (Vcb->VolumeLockFileObject == IrpSp->FileObject) {
1783 RC = STATUS_SUCCESS;
1784 } else {
1785 RC = STATUS_ACCESS_DENIED;
1786 }
1787 // If the open count for the volume is greater than 1 then this request
1788 // will fail.
1789 } else if (Vcb->VCBOpenCount > UDF_RESIDUAL_REFERENCE+1) {
1790 RC = STATUS_ACCESS_DENIED;
1791 // We will try to get rid of all of the user references. If there is only one
1792 // remaining after the purge then we can allow the volume to be locked.
1793 } else {
1794 // flush system cache
1795 UDFReleaseResource( &(Vcb->VCBResource) );
1796 VcbAcquired = FALSE;
1797 }*/
1798
1799 } _SEH2_FINALLY {
1800
1801 // Release the Vcb.
1802 if(VcbAcquired) {
1803 UDFReleaseResource( &(Vcb->VCBResource) );
1804 VcbAcquired = FALSE;
1805 }
1806 } _SEH2_END;
1807
1808 UDFAcquireResourceExclusive(&(Vcb->VCBResource), TRUE );
1809 VcbAcquired = TRUE;
1811 UDFReleaseResource( &(Vcb->VCBResource) );
1812 VcbAcquired = FALSE;
1813 // Check if the Vcb is already locked, or if the open file count
1814 // is greater than 1 (which implies that someone else also is
1815 // currently using the volume, or a file on the volume).
1816 IoAcquireVpbSpinLock( &SavedIrql );
1817
1818 if (!(Vcb->Vpb->Flags & VPB_LOCKED) &&
1819 (Vcb->VolumeLockPID == (ULONG)-1) &&
1820 (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE+1) &&
1821 (Vcb->Vpb->ReferenceCount == 2)) {
1822
1823 // Mark volume as locked
1824 if(PID == (ULONG)-1) {
1825 Vcb->Vpb->Flags |= VPB_LOCKED;
1826 }
1827 Vcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_LOCKED;
1828 Vcb->VolumeLockFileObject = IrpSp->FileObject;
1829 Vcb->VolumeLockPID = PID;
1830
1831 RC = STATUS_SUCCESS;
1832
1833 } else {
1834
1836 }
1837
1838 IoReleaseVpbSpinLock( SavedIrql );
1839
1840 if(!NT_SUCCESS(RC)) {
1842 }
1843
1844 // Complete the request if there haven't been any exceptions.
1845 Irp->IoStatus.Information = 0;
1846 Irp->IoStatus.Status = RC;
1847 return RC;
1848} // end UDFLockVolume()
#define FSRTL_VOLUME_LOCK
Definition: ntifs_ex.h:441
#define FSRTL_VOLUME_LOCK_FAILED
Definition: ntifs_ex.h:442
#define VPB_LOCKED
Definition: iotypes.h:1808

Referenced by UDFCommonDeviceControl(), and UDFUserFsCtrlRequest().

◆ UDFLogEvent()

VOID UDFLogEvent ( NTSTATUS  UDFEventLogId,
NTSTATUS  RC 
)

Definition at line 575 of file misc.cpp.

578{
579 _SEH2_TRY {
580
581 // Implement a call to IoAllocateErrorLogEntry() followed by a call
582 // to IoWriteErrorLogEntry(). You should note that the call to IoWriteErrorLogEntry()
583 // will free memory for the entry once the write completes (which in actuality
584 // is an asynchronous operation).
585
587 // nothing really we can do here, just do not wish to crash ...
588 NOTHING;
589 } _SEH2_END;
590
591 return;
592} // end UDFLogEvent()

Referenced by UDFCleanup(), UDFClose(), UDFCommonDispatch(), UDFCreate(), UDFDeviceControl(), UDFDirControl(), UDFFastIoQueryBasicInfo(), UDFFastIoQueryStdInfo(), UDFFileInfo(), UDFFlush(), UDFFSControl(), UDFLockControl(), UDFPnp(), UDFQueryVolInfo(), UDFRead(), UDFSetVolInfo(), UDFShutdown(), UDFStackOverflowRead(), and UDFWrite().

◆ UDFMarkStreamsForDeletion()

NTSTATUS UDFMarkStreamsForDeletion ( IN PVCB  Vcb,
IN PtrUDFFCB  Fcb,
IN BOOLEAN  ForDel 
)

Definition at line 1137 of file fileinfo.cpp.

1142{
1144 PUDF_FILE_INFO SDirInfo = NULL;
1146 ULONG lc;
1147 BOOLEAN SDirAcq = FALSE;
1148 BOOLEAN StrAcq = FALSE;
1149 uint_di d,i;
1150
1151 _SEH2_TRY {
1152
1153 // In some cases we needn't marking Streams for deleteion
1154 // (Not opened or Don't exist)
1155 if(UDFIsAStream(Fcb->FileInfo) ||
1156 UDFIsAStreamDir(Fcb->FileInfo) ||
1157 !UDFHasAStreamDir(Fcb->FileInfo) ||
1158 !Fcb->FileInfo->Dloc->SDirInfo ||
1159 UDFIsSDirDeleted(Fcb->FileInfo->Dloc->SDirInfo) ||
1160 (UDFGetFileLinkCount(Fcb->FileInfo) > 1) )
1161 try_return (RC /*=STATUS_SUCCESS*/);
1162
1163 // We shall mark Streams for deletion if there is no
1164 // Links to the file. Otherwise we'll delete only the file.
1165 // If we are asked to unmark Streams, we'll precess the whole Tree
1166 RC = UDFOpenStreamDir__(Vcb, Fcb->FileInfo, &SDirInfo);
1167 if(!NT_SUCCESS(RC))
1168 try_return(RC);
1169
1170 if(SDirInfo->Fcb &&
1171 SDirInfo->Fcb->NTRequiredFCB) {
1172 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
1173 UDFAcquireResourceExclusive(&(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1174 SDirAcq = TRUE;
1175 }
1176
1177 if(!ForDel || ((lc = UDFGetFileLinkCount(Fcb->FileInfo)) < 2)) {
1178
1179 UDF_DIR_SCAN_CONTEXT ScanContext;
1180 PDIR_INDEX_ITEM DirNdx;
1181
1182 // It is not worth checking whether the Stream can be deleted if
1183 // Undelete requested
1184 if(ForDel &&
1185 // scan DirIndex
1186 UDFDirIndexInitScan(SDirInfo, &ScanContext, 2)) {
1187
1188 // Check if we can delete Streams
1189 while((DirNdx = UDFDirIndexScan(&ScanContext, &FileInfo))) {
1190 if(!FileInfo)
1191 continue;
1192 if(FileInfo->Fcb) {
1193 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount++;
1194 MmPrint((" MmFlushImageSection() for Stream\n"));
1195 if(!MmFlushImageSection(&(FileInfo->Fcb->NTRequiredFCB->SectionObject), MmFlushForDelete)) {
1196 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount--;
1198 }
1199 FileInfo->Fcb->NTRequiredFCB->AcqFlushCount--;
1200 }
1201 }
1202 }
1203 // (Un)Mark Streams for deletion
1204
1205 // Perform sequencial Open for Streams & mark 'em
1206 // for deletion. We should not get FileInfo pointers directly
1207 // from DirNdx[i] to prevent great troubles with linked
1208 // files. We should mark for deletion FI with proper ParentFile
1209 // pointer.
1210 d = UDFDirIndexGetLastIndex(SDirInfo->Dloc->DirIndex);
1211 for(i=2; i<d; i++) {
1212 RC = UDFOpenFile__(Vcb,
1213 FALSE,TRUE,NULL,
1214 SDirInfo,&FileInfo,&i);
1215 ASSERT(NT_SUCCESS(RC) || (RC == STATUS_FILE_DELETED));
1216 if(NT_SUCCESS(RC)) {
1217 if(FileInfo->Fcb) {
1218 if(FileInfo->Fcb->NTRequiredFCB) {
1219 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1220 UDFAcquireResourceExclusive(&(FileInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
1221 StrAcq = TRUE;
1222 }
1223#ifndef UDF_ALLOW_LINKS_TO_STREAMS
1224 if(UDFGetFileLinkCount(FileInfo) >= 2) {
1225 // Currently, UDF_INFO package doesn't
1226 // support this case, so we'll inform developer
1227 // about this to prevent on-disk space leaks...
1228 BrutePoint();
1230 }
1231#endif //UDF_ALLOW_LINKS_TO_STREAMS
1232 if(ForDel) {
1233 AdPrint((" SET stream DeleteOnClose\n"));
1234#ifdef UDF_DBG
1235 ASSERT(!(FileInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1236 if(FileInfo->ParentFile &&
1237 FileInfo->ParentFile->Fcb) {
1238 ASSERT(!(FileInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1239 }
1240#endif // UDF_DBG
1241 FileInfo->Fcb->FCBFlags |= (UDF_FCB_DELETE_ON_CLOSE |
1243 } else {
1244 AdPrint((" CLEAR stream DeleteOnClose\n"));
1245 FileInfo->Fcb->FCBFlags &= ~(UDF_FCB_DELETE_ON_CLOSE |
1247 }
1248 }
1250 } else
1251 if(RC == STATUS_FILE_DELETED) {
1252 // That's OK if STATUS_FILE_DELETED returned...
1253 RC = STATUS_SUCCESS;
1254 }
1255 if(FileInfo) {
1257 ASSERT(!StrAcq && !(FileInfo->Fcb));
1259 }
1260 if(StrAcq) {
1261 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1262 UDFReleaseResource(&(FileInfo->Fcb->NTRequiredFCB->MainResource));
1263 StrAcq = FALSE;
1264 }
1265 }
1266 FileInfo = NULL;
1267 }
1268 // Mark SDir for deletion
1269 if(SDirInfo->Fcb) {
1270 if(ForDel) {
1271#ifdef UDF_DBG
1272 ASSERT(!(SDirInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1273 if(SDirInfo->ParentFile &&
1274 SDirInfo->ParentFile->Fcb) {
1275 ASSERT(!(SDirInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1276 }
1277#endif // UDF_DBG
1278 AdPrint((" SET stream dir DeleteOnClose\n"));
1279 SDirInfo->Fcb->FCBFlags |= (UDF_FCB_DELETE_ON_CLOSE |
1281 } else {
1282 AdPrint((" CLEAR stream dir DeleteOnClose\n"));
1283 SDirInfo->Fcb->FCBFlags &= ~(UDF_FCB_DELETE_ON_CLOSE |
1285 }
1286 }
1287 } else
1288 if(lc >= 2) {
1289 // if caller wants us to perform DelTree for Streams, but
1290 // someone keeps Stream opened and there is a Link to this
1291 // file, we can't delete it immediately (on Cleanup) & should
1292 // not delete the whole Tree. Instead, we'll set DELETE_PARENT
1293 // flag in SDir to kill this file later, when all the Handles
1294 // to Streams, opened via this file, would be closed
1295#ifdef UDF_DBG
1296 ASSERT(!(SDirInfo->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1297 if(SDirInfo->ParentFile &&
1298 SDirInfo->ParentFile->Fcb) {
1299 ASSERT(!(SDirInfo->ParentFile->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
1300 }
1301#endif // UDF_DBG
1302 if(SDirInfo->Fcb)
1303 SDirInfo->Fcb->FCBFlags |= UDF_FCB_DELETE_PARENT;
1304 }
1305
1306try_exit: NOTHING;
1307
1308 } _SEH2_FINALLY {
1309 if(FileInfo) {
1312 ASSERT(!StrAcq && !(FileInfo->Fcb));
1314 }
1315 if(StrAcq) {
1316 UDF_CHECK_PAGING_IO_RESOURCE(FileInfo->Fcb->NTRequiredFCB);
1317 UDFReleaseResource(&(FileInfo->Fcb->NTRequiredFCB->MainResource));
1318 }
1319 SDirInfo = NULL;
1320 }
1321 if(SDirInfo) {
1322 UDFCloseFile__(Vcb, SDirInfo);
1323 if(SDirAcq) {
1324 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
1325 UDFReleaseResource(&(SDirInfo->Fcb->NTRequiredFCB->MainResource));
1326 }
1327 if(UDFCleanUpFile__(Vcb, SDirInfo)) {
1328 MyFreePool__(SDirInfo);
1329 }
1330 SDirInfo = NULL;
1331 }
1332 } _SEH2_END;
1333 return RC;
1334} // end UDFMarkStreamsForDeletion()
PDIR_INDEX_ITEM UDFDirIndexScan(PUDF_DIR_SCAN_CONTEXT Context, PUDF_FILE_INFO *_FileInfo)
Definition: dirtree.cpp:378
BOOLEAN UDFDirIndexInitScan(IN PUDF_FILE_INFO DirInfo, OUT PUDF_DIR_SCAN_CONTEXT Context, IN uint_di Index)
Definition: dirtree.cpp:347
#define d
Definition: ke_i.h:81
OSSTATUS UDFOpenStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4965
#define UDFHasAStreamDir(FI)
Definition: udf_info.h:1000
#define UDFDirIndexGetLastIndex(di)
Definition: udf_info.h:1122
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172

Referenced by UDFCommonCleanup(), and UDFSetDispositionInformation().

◆ UDFMdlComplete()

VOID UDFMdlComplete ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
BOOLEAN  ReadCompletion 
)

Definition at line 1117 of file read.cpp.

1122{
1125
1126 UDFPrint(("UDFMdlComplete: \n"));
1127
1130
1131 UDFTouch(Irp->MdlAddress);
1132 // Not much to do here.
1133 if (ReadCompletion) {
1134 MmPrint((" CcMdlReadComplete() MDL=%x\n", Irp->MdlAddress));
1135 CcMdlReadComplete(FileObject, Irp->MdlAddress);
1136 } else {
1137 // The Cache Manager needs the byte offset in the I/O stack location.
1138 MmPrint((" CcMdlWriteComplete() MDL=%x\n", Irp->MdlAddress));
1139 CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);
1140 }
1141
1142 // Clear the MDL address field in the IRP so the IoCompleteRequest()
1143 // does not __try to play around with the MDL.
1144 Irp->MdlAddress = NULL;
1145
1146 // Free up the Irp Context.
1147 UDFReleaseIrpContext(PtrIrpContext);
1148
1149 // Complete the IRP.
1150 Irp->IoStatus.Status = RC;
1151 Irp->IoStatus.Information = 0;
1153
1154 return;
1155}
VOID NTAPI CcMdlReadComplete(IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
Definition: mdlsup.c:75
VOID NTAPI CcMdlWriteComplete(IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
Definition: mdlsup.c:102

Referenced by UDFCommonRead(), and UDFCommonWrite().

◆ UDFMountVolume()

NTSTATUS NTAPI UDFMountVolume ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

◆ UDFNotifyChangeDirectory()

NTSTATUS NTAPI UDFNotifyChangeDirectory ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
PFILE_OBJECT  FileObject,
PtrUDFFCB  Fcb,
PtrUDFCCB  Ccb 
)

Definition at line 683 of file dircntrl.cpp.

691{
694 BOOLEAN PostRequest = FALSE;
696 BOOLEAN CanWait = FALSE;
700 _SEH2_VOLATILE BOOLEAN AcquiredFCB = FALSE;
702
703 UDFPrint(("UDFNotifyChangeDirectory\n"));
704
705 _SEH2_TRY {
706
707 // Validate the sent-in FCB
708 if ( (Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) ||
709 !(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
710
713 }
714
715 NtReqFcb = Fcb->NTRequiredFCB;
716 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
717 Vcb = Fcb->Vcb;
718
719 // Acquire the FCB resource shared
721 if (!UDFAcquireResourceShared(&(NtReqFcb->MainResource), CanWait)) {
722 PostRequest = TRUE;
724 }
725 AcquiredFCB = TRUE;
726
727 // If the file is marked as DELETE_PENDING then complete this
728 // request immediately.
729 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
730 ASSERT(!(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY));
732 }
733
734 // Obtain some parameters sent by the caller
735 CompletionFilter = pStackLocation ->Parameters.NotifyDirectory.CompletionFilter;
737
738 // If we wish to capture the subject context, we can do so as
739 // follows:
740 // {
741 // PSECURITY_SUBJECT_CONTEXT SubjectContext;
742 // SubjectContext = MyAllocatePool__(PagedPool,
743 // sizeof(SECURITY_SUBJECT_CONTEXT));
744 // SeCaptureSubjectContext(SubjectContext);
745 // }
746
747 FsRtlNotifyFullChangeDirectory(Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP), (PVOID)Ccb,
748 (Fcb->FileInfo->ParentFile) ? (PSTRING)&(Fcb->FCBName->ObjectName) : (PSTRING)&(UDFGlobalData.UnicodeStrRoot),
750 NULL, // UDFTraverseAccessCheck(...) ?
751 NULL); // SubjectContext ?
752
753 RC = STATUS_PENDING;
754
755 try_exit: NOTHING;
756
757 } _SEH2_FINALLY {
758
759 if (PostRequest) {
760 // Perform appropriate related post processing here
761 if (AcquiredFCB) {
763 UDFReleaseResource(&(NtReqFcb->MainResource));
764 AcquiredFCB = FALSE;
765 }
766 RC = UDFPostRequest(PtrIrpContext, Irp);
767 } else if (CompleteRequest) {
768
770 Irp->IoStatus.Status = RC;
771 Irp->IoStatus.Information = 0;
772 // Free up the Irp Context
773 UDFReleaseIrpContext(PtrIrpContext);
774 // complete the IRP
776 }
777
778 } else {
779 // Simply free up the IrpContext since the IRP has been queued
781 UDFReleaseIrpContext(PtrIrpContext);
782 }
783
784 // Release the FCB resources if acquired.
785 if (AcquiredFCB) {
787 UDFReleaseResource(&(NtReqFcb->MainResource));
788 AcquiredFCB = FALSE;
789 }
790
791 } _SEH2_END;
792
793 return(RC);
794} // end UDFNotifyChangeDirectory()
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG CompletionFilter
Definition: fltkernel.h:2243
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN WatchTree
Definition: fltkernel.h:2241
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:322
#define SL_WATCH_TREE
Definition: iotypes.h:1839

Referenced by UDFCommonDirControl().

◆ UDFOpenFile()

NTSTATUS UDFOpenFile ( IN PVCB  Vcb,
IN PFILE_OBJECT  PtrNewFileObject,
IN PtrUDFFCB  PtrNewFcb 
)

◆ UDFPerformVerify()

NTSTATUS UDFPerformVerify ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp,
IN PDEVICE_OBJECT  DeviceToVerify 
)

Definition at line 472 of file verfysup.cpp.

477{
478
479 PVCB Vcb;
482
483 UDFPrint(("UDFPerformVerify:\n"));
484 if(!IrpContext) return STATUS_INVALID_PARAMETER;
485 if(!Irp) return STATUS_INVALID_PARAMETER;
486
487 // Check if this Irp has a status of Verify required and if it does
488 // then call the I/O system to do a verify.
489 //
490 // Skip the IoVerifyVolume if this is a mount or verify request
491 // itself. Trying a recursive mount will cause a deadlock with
492 // the DeviceObject->DeviceLock.
493 if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) &&
494 ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) ||
495 (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) {
496
497 return UDFPostRequest(IrpContext, Irp);
498 }
499
500 // Extract a pointer to the Vcb from the VolumeDeviceObject.
501 // Note that since we have specifically excluded mount,
502 // requests, we know that IrpSp->DeviceObject is indeed a
503 // volume device object.
504
506
508
509 UDFPrint(("UDFPerformVerify: check\n"));
510 // Check if the volume still thinks it needs to be verified,
511 // if it doesn't then we can skip doing a verify because someone
512 // else beat us to it.
513 _SEH2_TRY {
514
515 if (DeviceToVerify->Flags & DO_VERIFY_VOLUME) {
516
517 // If the IopMount in IoVerifyVolume did something, and
518 // this is an absolute open, force a reparse.
520
521 // Bug?
522/* if (UDFIsRawDevice(RC)) {
523 RC = STATUS_WRONG_VOLUME;
524 }*/
525
526 // If the verify operation completed it will return
527 // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly.
528 if (RC == STATUS_SUCCESS) {
529 IrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_EXCEPTION;
530 }
531 // If UDFVerifyVolume encountered an error during
532 // processing, it will return that error. If we got
533 // STATUS_WRONG_VOLUME from the verify, and our volume
534 // is now mounted, commute the status to STATUS_SUCCESS.
535 if ((RC == STATUS_WRONG_VOLUME) &&
536 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
537 RC = STATUS_SUCCESS;
538 }
539
540 // Do a quick unprotected check here. The routine will do
541 // a safe check. After here we can release the resource.
542 // Note that if the volume really went away, we will be taking
543 // the Reparse path.
544
545 // If the device might need to go away then call our dismount routine.
546 if ( (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) ||
547 (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) &&
548 (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE) )
549 {
550 UDFPrint(("UDFPerformVerify: UDFCheckForDismount\n"));
551 UDFAcquireResourceExclusive(&(UDFGlobalData.GlobalDataResource), TRUE);
552 UDFCheckForDismount( IrpContext, Vcb, FALSE );
553 UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
554 }
555
556 // If this is a create and the verify succeeded then complete the
557 // request with a REPARSE status.
558 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) &&
559 (IrpSp->FileObject->RelatedFileObject == NULL) &&
560 ((RC == STATUS_SUCCESS) || (RC == STATUS_WRONG_VOLUME)) ) {
561
562 UDFPrint(("UDFPerformVerify: IO_REMOUNT\n"));
563
564 Irp->IoStatus.Information = IO_REMOUNT;
565
566 Irp->IoStatus.Status = STATUS_REPARSE;
568
569 UDFReleaseIrpContext(IrpContext);
570
571 RC = STATUS_REPARSE;
572 Irp = NULL;
573 IrpContext = NULL;
574
575 // If there is still an error to process then call the Io system
576 // for a popup.
577 } else if ((Irp != NULL) && !NT_SUCCESS( RC )) {
578
579 UDFPrint(("UDFPerformVerify: check IoIsErrorUserInduced\n"));
580 // Fill in the device object if required.
581 if (IoIsErrorUserInduced( RC ) ) {
583 }
584 UDFPrint(("UDFPerformVerify: UDFNormalizeAndRaiseStatus\n"));
585 UDFNormalizeAndRaiseStatus( IrpContext, RC );
586 }
587 }
588
589 // If there is still an Irp, send it off to an Ex Worker thread.
590 if (IrpContext != NULL) {
591
592 RC = UDFPostRequest( IrpContext, Irp );
593 }
594
596 // We had some trouble trying to perform the verify or raised
597 // an error ourselves. So we'll abort the I/O request with
598 // the error status that we get back from the execption code.
599 RC = UDFExceptionHandler( IrpContext, Irp);
600 } _SEH2_END;
601
602 UDFPrint(("UDFPerformVerify: RC = %x\n", RC));
603
604 return RC;
605
606} // end UDFPerformVerify()
_Inout_ PIRP _In_ PDEVICE_OBJECT DeviceToVerify
Definition: cdprocs.h:1409
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
NTSTATUS NTAPI IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN AllowRawMount)
Definition: volume.c:877
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define UDFNormalizeAndRaiseStatus(IC, S)
Definition: udffs.h:319
BOOLEAN UDFCheckForDismount(IN PtrUDFIrpContext IrpContext, IN PVCB Vcb, IN BOOLEAN _VcbAcquired)
Definition: verfysup.cpp:629
#define IO_REMOUNT
Definition: iotypes.h:544

Referenced by UDFExceptionHandler().

◆ UDFPnp()

NTSTATUS UDFPnp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 81 of file pnp.cpp.

85{
86 NTSTATUS RC;
87 PtrUDFIrpContext PtrIrpContext = NULL;
88 BOOLEAN AreWeTopLevel;
89
90 UDFPrint(("UDFPnp\n"));
92
95 ASSERT(Irp);
96
97 // set the top level context
98 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
99
100 _SEH2_TRY {
101 // We expect there to never be a fileobject, in which case we will always
102 // wait. Since at the moment we don't have any concept of pending Pnp
103 // operations, this is a bit nitpicky.
104
105 // get an IRP context structure and issue the request
106 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
107 if(PtrIrpContext) {
108 RC = UDFCommonPnp(PtrIrpContext, Irp);
109 } else {
111 Irp->IoStatus.Status = RC;
112 Irp->IoStatus.Information = 0;
113 // complete the IRP
115 }
116
118
119 RC = UDFExceptionHandler(PtrIrpContext, Irp);
121 } _SEH2_END;
122
123 if (AreWeTopLevel) {
125 }
126
128
129 return RC;
130}
NTSTATUS UDFCommonPnp(PtrUDFIrpContext PtrIrpContext, IN PIRP Irp)
Definition: pnp.cpp:145

◆ UDFPostRequest()

NTSTATUS UDFPostRequest ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

◆ UDFPostStackOverflowRead()

NTSTATUS UDFPostStackOverflowRead ( IN PtrUDFIrpContext  PtrIrpContext,
IN PIRP  Irp,
IN PtrUDFFCB  Fcb 
)

Definition at line 118 of file read.cpp.

123{
126
127 UDFPrint(("Getting too close to stack limit pass request to Fsp\n"));
128
129 // Allocate an event and get shared on the resource we will
130 // be later using the common read.
132 if(!Event)
135
136 if ((Irp->Flags & IRP_PAGING_IO) && (Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource)) {
137 Resource = Fcb->NTRequiredFCB->CommonFCBHeader.PagingIoResource;
138 } else {
139 Resource = Fcb->NTRequiredFCB->CommonFCBHeader.Resource;
140 }
141
143
144 _SEH2_TRY {
145 // If this read is the result of a verify, we have to
146 // tell the overflow read routne to temporarily
147 // hijack the Vcb->VerifyThread field so that reads
148 // can go through.
150 // And wait for the worker thread to complete the item
152
153 } _SEH2_FINALLY {
154
157 } _SEH2_END;
158
159 return STATUS_PENDING;
160
161} // end UDFPostStackOverflowRead()
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define PKEVENT
Definition: env_spec_w32.h:70
#define DbgWaitForSingleObject(o, to)
Definition: env_spec_w32.h:479
@ NotificationEvent
VOID NTAPI UDFStackOverflowRead(IN PVOID Context, IN PKEVENT Event)
Definition: read.cpp:185
VOID NTAPI FsRtlPostStackOverflow(IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
Definition: stackovf.c:232
ERESOURCE PagingIoResource
Definition: ntfs.h:527

Referenced by UDFCommonRead().

◆ UDFPurgeCacheEx_()

VOID UDFPurgeCacheEx_ ( PtrUDFNTRequiredFCB  NtReqFcb,
LONGLONG  Offset,
LONGLONG  Length,
BOOLEAN  CanWait,
PVCB  Vcb,
PFILE_OBJECT  FileObject 
)

Definition at line 1070 of file write.cpp.

1080{
1081 ULONG Off_l;
1082#ifdef USE_CcCopyWrite_TO_ZERO
1083 ULONG PgLen;
1084#endif //USE_CcCopyWrite_TO_ZERO
1085
1086 // We'll just purge cache section here,
1087 // without call to CcZeroData()
1088 // 'cause udf_info.cpp will care about it
1089
1090#define PURGE_BLOCK_SZ 0x10000000
1091
1092 // NOTE: if FS engine doesn't suport
1093 // sparse/unrecorded areas, CcZeroData must be called
1094 // In this case we'll see some recursive WRITE requests
1095
1096 _SEH2_TRY {
1097 MmPrint((" UDFPurgeCacheEx_(): Offs: %I64x, ", Offset));
1098 MmPrint((" Len: %lx\n", Length));
1099 SECTION_OBJECT_POINTERS* SectionObject = &(NtReqFcb->SectionObject);
1100 if(Length) {
1101 LONGLONG Offset0, OffsetX, VDL;
1102
1103 Offset0 = Offset;
1104 if((Off_l = ((ULONG)Offset0 & (PAGE_SIZE-1)))) {
1105 // Offset, Offset0
1106 // v
1107 // ...|dddddddddddd00000|....
1108 // |<- Off_l ->|
1109#ifndef USE_CcCopyWrite_TO_ZERO
1110 *((PULONG)&Offset0) &= ~(PAGE_SIZE-1);
1111 MmPrint((" CcFlushCache(s) Offs %I64x, Len %x\n", Offset0, Off_l));
1112 CcFlushCache( SectionObject, (PLARGE_INTEGER)&Offset0, Off_l, NULL );
1113#else //USE_CcCopyWrite_TO_ZERO
1114 // ...|ddddd000000000000|....
1115 // |<- PgLen ->|
1116 PgLen = PAGE_SIZE - Off_l; /*(*((PULONG)&Offset) & (PAGE_SIZE-1))*/
1117 //
1118 if(PgLen > Length)
1119 PgLen = (ULONG)Length;
1120
1121 MmPrint((" ZeroCache (CcWrite) Offs %I64x, Len %x\n", Offset, PgLen));
1122#ifdef DBG
1123 if(FileObject && Vcb) {
1124
1125 ASSERT(CanWait);
1126#endif //DBG
1127 if (PgLen) {
1128 if (SectionObject->SharedCacheMap) {
1129 CcCopyWrite(FileObject, (PLARGE_INTEGER)&Offset, PgLen, TRUE || CanWait, Vcb->ZBuffer);
1130 }
1131 Offset += PgLen;
1132 Length -= PgLen;
1133 }
1134#ifdef DBG
1135 } else {
1136 MmPrint((" Can't use CcWrite to zero cache\n"));
1137 }
1138#endif //DBG
1139#endif //USE_CcCopyWrite_TO_ZERO
1140 }
1141 VDL = NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart;
1142 OffsetX = Offset+Length;
1143 if((Off_l = ((ULONG)OffsetX & (PAGE_SIZE-1)))) {
1144
1145 if(OffsetX < VDL) {
1146#ifndef USE_CcCopyWrite_TO_ZERO
1147 Off_l = ( (ULONG)(VDL-OffsetX) > PAGE_SIZE ) ?
1148 (PAGE_SIZE - Off_l) :
1149 ((ULONG)(VDL-OffsetX));
1150 *((PULONG)&OffsetX) &= ~(PAGE_SIZE-1);
1151 MmPrint((" CcFlushCache(e) Offs %I64x, Len %x\n", OffsetX, Off_l));
1152 CcFlushCache( SectionObject, (PLARGE_INTEGER)&OffsetX, Off_l, NULL );
1153#else //USE_CcCopyWrite_TO_ZERO
1154 if(VDL - OffsetX > PAGE_SIZE) {
1155 PgLen = (ULONG)OffsetX & ~(PAGE_SIZE-1);
1156 } else {
1157 PgLen = (ULONG)(VDL - OffsetX) & ~(PAGE_SIZE-1);
1158 }
1159 // ...|000000000000ddddd|....
1160 // |<- PgLen ->|
1161 MmPrint((" ZeroCache (CcWrite - 2) Offs %I64x, Len %x\n", OffsetX, PgLen));
1162#ifdef DBG
1163 if(FileObject && Vcb) {
1164 ASSERT(CanWait);
1165#endif //DBG
1166 if (SectionObject->SharedCacheMap) {
1167 CcCopyWrite(FileObject, (PLARGE_INTEGER)&OffsetX, PgLen, TRUE || CanWait, Vcb->ZBuffer);
1168 }
1169 Length -= PgLen;
1170#ifdef DBG
1171 } else {
1172 MmPrint((" Can't use CcWrite to zero cache (2)\n"));
1173 }
1174#endif //DBG
1175#endif //USE_CcCopyWrite_TO_ZERO
1176 }
1177 }
1178#ifndef USE_CcCopyWrite_TO_ZERO
1179 do
1180#else //USE_CcCopyWrite_TO_ZERO
1181 while(Length)
1182#endif //USE_CcCopyWrite_TO_ZERO
1183 {
1184 MmPrint((" CcPurgeCacheSection()\n"));
1185 if(PURGE_BLOCK_SZ > Length) {
1187 (ULONG)Length, FALSE);
1188 /*
1189 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart += Length;
1190 ASSERT(NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart <=
1191 NtReqFcb->CommonFCBHeader.FileSize.QuadPart);
1192 MmPrint((" CcFlushCache()\n"));
1193 CcFlushCache( SectionObject, (PLARGE_INTEGER)&Offset, (ULONG)Length, NULL );
1194 */
1195#ifndef ALLOW_SPARSE
1196 // UDFZeroFile__(
1197#endif //ALLOW_SPARSE
1198 break;
1199 } else {
1202 /*
1203 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart += PURGE_BLOCK_SZ;
1204 ASSERT(NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart <=
1205 NtReqFcb->CommonFCBHeader.FileSize.QuadPart);
1206 MmPrint((" CcFlushCache()\n"));
1207 CcFlushCache( SectionObject, (PLARGE_INTEGER)&Offset, (ULONG)Length, NULL );
1208 */
1209#ifndef ALLOW_SPARSE
1210 // UDFZeroFile__(
1211#endif //ALLOW_SPARSE
1214 }
1215 }
1216#ifndef USE_CcCopyWrite_TO_ZERO
1217 while(Length);
1218#endif //USE_CcCopyWrite_TO_ZERO
1219 if(VDL < Offset)
1220 NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart = Offset;
1221 }
1223 BrutePoint();
1224 } _SEH2_END;
1225} // end UDFPurgeCacheEx_()
_Must_inspect_result_ _Outptr_ PVOID * SectionObject
Definition: fsrtlfuncs.h:860
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define PURGE_BLOCK_SZ

◆ UDFQueryDirectory()

NTSTATUS NTAPI UDFQueryDirectory ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PIO_STACK_LOCATION  IrpSp,
PFILE_OBJECT  FileObject,
PtrUDFFCB  Fcb,
PtrUDFCCB  Ccb 
)

Definition at line 216 of file dircntrl.cpp.

224{
226 BOOLEAN PostRequest = FALSE;
228 BOOLEAN CanWait = FALSE;
230 _SEH2_VOLATILE BOOLEAN AcquiredFCB = FALSE;
231 unsigned long BufferLength = 0;
232 UNICODE_STRING SearchPattern;
233 PUNICODE_STRING PtrSearchPattern;
237 BOOLEAN FirstTimeQuery = FALSE;
238 LONG NextMatch;
239 LONG PrevMatch = -1;
240 ULONG CurrentOffset;
241 ULONG BaseLength;
242 ULONG FileNameBytes;
243 ULONG Information = 0;
244 ULONG LastOffset = 0;
245 BOOLEAN AtLeastOneFound = FALSE;
247 PUDF_FILE_INFO DirFileInfo = NULL;
248 PDIR_INDEX_HDR hDirIndex = NULL;
249 PFILE_BOTH_DIR_INFORMATION DirInformation = NULL; // Returned from udf_info module
250 PFILE_BOTH_DIR_INFORMATION BothDirInformation = NULL; // Pointer in callers buffer
251 PFILE_NAMES_INFORMATION NamesInfo;
252 ULONG BytesRemainingInBuffer;
253 UCHAR FNM_Flags = 0;
254 PHASH_ENTRY cur_hashes = NULL;
255 PDIR_INDEX_ITEM DirNdx;
256 // do some pre-init...
257 SearchPattern.Buffer = NULL;
258
259 UDFPrint(("UDFQueryDirectory: @=%#x\n", &PtrIrpContext));
260
261#define CanBe8dot3 (FNM_Flags & UDF_FNM_FLAG_CAN_BE_8D3)
262#define IgnoreCase (FNM_Flags & UDF_FNM_FLAG_IGNORE_CASE)
263#define ContainsWC (FNM_Flags & UDF_FNM_FLAG_CONTAINS_WC)
264
266 {
267
268 // Validate the sent-in FCB
269 if ((Fcb->NodeIdentifier.NodeType == UDF_NODE_TYPE_VCB) || !(Fcb->FCBFlags & UDF_FCB_DIRECTORY)) {
270 // We will only allow notify requests on directories.
272 }
273
274 // Obtain the callers parameters
275 NtReqFcb = Fcb->NTRequiredFCB;
276 CanWait = (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_CAN_BLOCK) ? TRUE : FALSE;
277 Vcb = Fcb->Vcb;
278 //Vcb->VCBFlags |= UDF_VCB_SKIP_EJECT_CHECK;
279 FNM_Flags |= (Ccb->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? 0 : UDF_FNM_FLAG_IGNORE_CASE;
280 DirFileInfo = Fcb->FileInfo;
281 BufferLength = pStackLocation->Parameters.QueryDirectory.Length;
282
283 // If the caller does not want to block, it would be easier to
284 // simply post the request now.
285 if (!CanWait) {
286 PostRequest = TRUE;
288 }
289
290 // Continue obtaining the callers parameters...
291 if(IgnoreCase && pStackLocation->Parameters.QueryDirectory.FileName) {
292 PtrSearchPattern = &SearchPattern;
293 if(!NT_SUCCESS(RC = RtlUpcaseUnicodeString(PtrSearchPattern, (PUNICODE_STRING)(pStackLocation->Parameters.QueryDirectory.FileName), TRUE)))
294 try_return(RC);
295 } else {
296 PtrSearchPattern = (PUNICODE_STRING)(pStackLocation->Parameters.QueryDirectory.FileName);
297 }
298 FileInformationClass = pStackLocation->Parameters.QueryDirectory.FileInformationClass;
299
300 // Calculate baselength (without name) for each InfoClass
301 switch (FileInformationClass) {
302
305 break;
308 break;
310 BaseLength = FIELD_OFFSET( FILE_NAMES_INFORMATION, FileName[0] );
311 break;
314 break;
315 default:
317 }
318
319 // Some additional arguments that affect the FSD behavior
321
323 UDFAcquireResourceShared(&(NtReqFcb->MainResource), TRUE);
324 AcquiredFCB = TRUE;
325
326 // We must determine the buffer pointer to be used. Since this
327 // routine could either be invoked directly in the context of the
328 // calling thread, or in the context of a worker thread, here is
329 // a general way of determining what we should use.
330 if(Irp->MdlAddress) {
332 if(!Buffer)
334 } else {
335 Buffer = (PUCHAR) Irp->UserBuffer;
336 if(!Buffer)
338 }
339
340 // The method of determining where to look from and what to look for is
341 // unfortunately extremely confusing. However, here is a methodology
342 // we broadly adopt:
343 // (a) We have to maintain a search buffer per CCB structure.
344 // (b) This search buffer is initialized the very first time
345 // a query directory operation is performed using the file object.
346 // (For the UDF FSD, the search buffer is stored in the
347 // DirectorySearchPattern field)
348 // However, the caller still has the option of "overriding" this stored
349 // search pattern by supplying a new one in a query directory operation.
350 if(PtrSearchPattern &&
351 PtrSearchPattern->Buffer &&
352 !(PtrSearchPattern->Buffer[PtrSearchPattern->Length/sizeof(WCHAR) - 1])) {
353 PtrSearchPattern->Length -= sizeof(WCHAR);
354 }
355
357 // Good idea from M$: we should continue search from NEXT item
358 // when FileIndex specified...
359 // Strange idea from M$: we should do it with EMPTY pattern...
360 PtrSearchPattern = NULL;
361 Ccb->CCBFlags |= UDF_CCB_MATCH_ALL;
362 } else if(PtrSearchPattern &&
363 PtrSearchPattern->Buffer &&
364 !UDFIsMatchAllMask(PtrSearchPattern, NULL) ) {
365
366 Ccb->CCBFlags &= ~(UDF_CCB_MATCH_ALL |
369 // Once we have validated the search pattern, we must
370 // check whether we need to store this search pattern in
371 // the CCB.
372 if(Ccb->DirectorySearchPattern) {
373 MyFreePool__(Ccb->DirectorySearchPattern->Buffer);
374 MyFreePool__(Ccb->DirectorySearchPattern);
375 Ccb->DirectorySearchPattern = NULL;
376 }
377 // This must be the very first query request.
378 FirstTimeQuery = TRUE;
379
380 // Now, allocate enough memory to contain the caller
381 // supplied search pattern and fill in the DirectorySearchPattern
382 // field in the CCB
383 Ccb->DirectorySearchPattern = (PUNICODE_STRING)MyAllocatePool__(NonPagedPool,sizeof(UNICODE_STRING));
384 if(!(Ccb->DirectorySearchPattern)) {
386 }
387 Ccb->DirectorySearchPattern->Length = PtrSearchPattern->Length;
388 Ccb->DirectorySearchPattern->MaximumLength = PtrSearchPattern->MaximumLength;
389 Ccb->DirectorySearchPattern->Buffer = (PWCHAR)MyAllocatePool__(NonPagedPool,PtrSearchPattern->MaximumLength);
390 if(!(Ccb->DirectorySearchPattern->Buffer)) {
392 }
393 RtlCopyMemory(Ccb->DirectorySearchPattern->Buffer,PtrSearchPattern->Buffer,
394 PtrSearchPattern->MaximumLength);
395 if(FsRtlDoesNameContainWildCards(PtrSearchPattern)) {
396 Ccb->CCBFlags |= UDF_CCB_WILDCARD_PRESENT;
397 } else {
398 UDFBuildHashEntry(Vcb, PtrSearchPattern, cur_hashes = &(Ccb->hashes), HASH_POSIX | HASH_ULFN);
399 }
400 if(UDFCanNameBeA8dot3(PtrSearchPattern))
401 Ccb->CCBFlags |= UDF_CCB_CAN_BE_8_DOT_3;
402
403 } else if(!Ccb->DirectorySearchPattern &&
404 !(Ccb->CCBFlags & UDF_CCB_MATCH_ALL) ) {
405
406 // If the filename is not specified or is a single '*' then we will
407 // match all names.
408 FirstTimeQuery = TRUE;
409 PtrSearchPattern = NULL;
410 Ccb->CCBFlags |= UDF_CCB_MATCH_ALL;
411
412 } else {
413 // The caller has not supplied any search pattern that we are
414 // forced to use. However, the caller had previously supplied
415 // a pattern (or we must have invented one) and we will use it.
416 // This is definitely not the first query operation on this
417 // directory using this particular file object.
418 if(Ccb->CCBFlags & UDF_CCB_MATCH_ALL) {
419 PtrSearchPattern = NULL;
420/* if(Ccb->CurrentIndex)
421 Ccb->CurrentIndex++;*/
422 } else {
423 PtrSearchPattern = Ccb->DirectorySearchPattern;
424 if(!(Ccb->CCBFlags & UDF_CCB_WILDCARD_PRESENT)) {
425 cur_hashes = &(Ccb->hashes);
426 }
427 }
428 }
429
431 // Caller has told us wherefrom to begin.
432 // We may need to round this to an appropriate directory entry
433 // entry alignment value.
434 NextMatch = pStackLocation->Parameters.QueryDirectory.FileIndex + 1;
435 } else if(IrpSp->Flags & SL_RESTART_SCAN) {
436 NextMatch = 0;
437 } else {
438 // Get the starting offset from the CCB.
439 // Remember to update this value on our way out from this function.
440 // But, do not update the CCB CurrentByteOffset field if our reach
441 // the end of the directory (or get an error reading the directory)
442 // while performing the search.
443 NextMatch = Ccb->CurrentIndex + 1; // Last good index
444 }
445
446 FNM_Flags |= (Ccb->CCBFlags & UDF_CCB_WILDCARD_PRESENT) ? UDF_FNM_FLAG_CONTAINS_WC : 0;
447 // this is used only when mask is supplied
448 FNM_Flags |= (Ccb->CCBFlags & UDF_CCB_CAN_BE_8_DOT_3) ? UDF_FNM_FLAG_CAN_BE_8D3 : 0;
449
450 // This is an additional verifying
451 if(!UDFIsADirectory(DirFileInfo)) {
453 }
454
455 hDirIndex = DirFileInfo->Dloc->DirIndex;
456 if(!hDirIndex) {
458 }
459
460 RC = STATUS_SUCCESS;
461 // Allocate buffer enough to save both DirInformation and FileName
464 if(!DirInformation) {
466 }
467 CurrentOffset=0;
468 BytesRemainingInBuffer = pStackLocation->Parameters.QueryDirectory.Length;
469 RtlZeroMemory(Buffer,BytesRemainingInBuffer);
470
471 if((!FirstTimeQuery) && !UDFDirIndex(hDirIndex, (uint_di)NextMatch) ) {
473 }
474
475 // One final note though:
476 // If we do not find a directory entry OR while searching we reach the
477 // end of the directory, then the return code should be set as follows:
478
479 // (a) If any files have been returned (i.e. ReturnSingleEntry was FALSE
480 // and we did find at least one match), then return STATUS_SUCCESS
481 // (b) If no entry is being returned then:
482 // (i) If this is the first query i.e. FirstTimeQuery is TRUE
483 // then return STATUS_NO_SUCH_FILE
484 // (ii) Otherwise, return STATUS_NO_MORE_FILES
485
486 while(TRUE) {
487 // If the user had requested only a single match and we have
488 // returned that, then we stop at this point.
489 if(ReturnSingleEntry && AtLeastOneFound) {
490 try_return(RC);
491 }
492 // We call UDFFindNextMatch to look down the next matching dirent.
493 RC = UDFFindNextMatch(Vcb, hDirIndex,&NextMatch,PtrSearchPattern, FNM_Flags, cur_hashes, &DirNdx);
494 // If we didn't receive next match, then we are at the end of the
495 // directory. If we have returned any files, we exit with
496 // success, otherwise we return STATUS_NO_MORE_FILES.
497 if(!NT_SUCCESS(RC)) {
498 RC = AtLeastOneFound ? STATUS_SUCCESS :
499 (FirstTimeQuery ? STATUS_NO_SUCH_FILE : STATUS_NO_MORE_FILES);
500 try_return(RC);
501 }
502 // We found at least one matching file entry
503 AtLeastOneFound = TRUE;
504 if(!NT_SUCCESS(RC = UDFFileDirInfoToNT(Vcb, DirNdx, DirInformation))) {
505 // this happends when we can't allocate tmp buffers
506 try_return(RC);
507 }
508 DirInformation->FileIndex = NextMatch;
509 FileNameBytes = DirInformation->FileNameLength;
510
511 if ((BaseLength + FileNameBytes) > BytesRemainingInBuffer) {
512 // We haven't successfully transfered current data &
513 // later NextMatch will be incremented. Thus we should
514 // prevent loosing information in such a way:
515 if(NextMatch) NextMatch --;
516 // If this won't fit and we have returned a previous entry then just
517 // return STATUS_SUCCESS. Otherwise
518 // use a status code of STATUS_BUFFER_OVERFLOW.
519 if(CurrentOffset) {
521 }
522 // strange policy...
524 FileNameBytes = BaseLength + FileNameBytes - BytesRemainingInBuffer;
526 }
527 // Now we have an entry to return to our caller.
528 // We'll case on the type of information requested and fill up
529 // the user buffer if everything fits.
530 switch (FileInformationClass) {
531
535
536 BothDirInformation = (PFILE_BOTH_DIR_INFORMATION)(Buffer + CurrentOffset);
537 RtlCopyMemory(BothDirInformation,DirInformation,BaseLength);
538 BothDirInformation->FileIndex = NextMatch;
539 BothDirInformation->FileNameLength = FileNameBytes;
540 break;
541
543
544 NamesInfo = (PFILE_NAMES_INFORMATION)(Buffer + CurrentOffset);
545 NamesInfo->FileIndex = NextMatch;
546 NamesInfo->FileNameLength = FileNameBytes;
547 break;
548
549 default:
550 break;
551 }
552 if (FileNameBytes) {
553 // This is a Unicode name, we can copy the bytes directly.
554 RtlCopyMemory( (PVOID)(Buffer + CurrentOffset + BaseLength),
555 DirInformation->FileName, FileNameBytes );
556 }
557
558 Information = CurrentOffset + BaseLength + FileNameBytes;
559
560 // ((..._INFORMATION)(PointerToPreviousEntryInBuffer))->NextEntryOffset = CurrentOffset - LastOffset;
561 *((PULONG)(Buffer+LastOffset)) = CurrentOffset - LastOffset;
562 // Set up our variables for the next dirent.
563 FirstTimeQuery = FALSE;
564
565 LastOffset = CurrentOffset;
566 PrevMatch = NextMatch;
567 NextMatch++;
568 CurrentOffset = UDFQuadAlign(Information);
569 BytesRemainingInBuffer = BufferLength - CurrentOffset;
570 }
571
572try_exit: NOTHING;
573
574
575 } _SEH2_FINALLY {
576
577 if (PostRequest) {
578
579 if (AcquiredFCB) {
581 UDFReleaseResource(&(NtReqFcb->MainResource));
582 }
583 // Map the users buffer and then post the request.
584 RC = UDFLockCallersBuffer(PtrIrpContext, Irp, TRUE, BufferLength);
585 ASSERT(NT_SUCCESS(RC));
586
587 RC = UDFPostRequest(PtrIrpContext, Irp);
588
589 } else {
590#ifdef UDF_DBG
591 if(!NT_SUCCESS(RC)) {
592 UDFPrint((" Not found\n"));
593 }
594#endif // UDF_DBG
595 // Remember to update the CurrentByteOffset field in the CCB if required.
596 if(Ccb) Ccb->CurrentIndex = PrevMatch;
597
598 if (AcquiredFCB) {
600 UDFReleaseResource(&(NtReqFcb->MainResource));
601 }
603 // complete the IRP
604 Irp->IoStatus.Status = RC;
605 Irp->IoStatus.Information = Information;
607 // Free up the Irp Context
608 UDFReleaseIrpContext(PtrIrpContext);
609 }
610 }
611
612 if(SearchPattern.Buffer) RtlFreeUnicodeString(&SearchPattern);
613 if(DirInformation) MyFreePool__(DirInformation);
614 } _SEH2_END;
615
616 return(RC);
617} // end UDFQueryDirectory()
#define UDF_FNM_FLAG_CONTAINS_WC
Definition: dircntrl.cpp:28
#define UDF_FNM_FLAG_CAN_BE_8D3
Definition: dircntrl.cpp:26
#define IgnoreCase
Definition: cdprocs.h:461
NTSTATUS UDFFindNextMatch(IN PVCB Vcb, IN PDIR_INDEX_HDR hDirIndex, IN PLONG CurrentNumber, IN PUNICODE_STRING PtrSearchPattern, IN UCHAR FNM_Flags, IN PHASH_ENTRY hashes, OUT PDIR_INDEX_ITEM *_DirNdx)
Definition: dircntrl.cpp:623
#define UDF_FNM_FLAG_IGNORE_CASE
Definition: dircntrl.cpp:27
uint8 UDFBuildHashEntry(IN PVCB Vcb, IN PUNICODE_STRING Name, OUT PHASH_ENTRY hashes, IN uint8 Mask)
Definition: dirtree.cpp:429
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2295
@ FileDirectoryInformation
Definition: from_kernel.h:62
@ FileNamesInformation
Definition: from_kernel.h:73
@ FileFullDirectoryInformation
Definition: from_kernel.h:63
@ FileBothDirectoryInformation
Definition: from_kernel.h:64
struct _FILE_NAMES_INFORMATION * PFILE_NAMES_INFORMATION
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
BOOLEAN __fastcall UDFIsMatchAllMask(IN PUNICODE_STRING Name, OUT BOOLEAN *DosOpen)
Definition: namesup.cpp:214
BOOLEAN __fastcall UDFCanNameBeA8dot3(IN PUNICODE_STRING Name)
Definition: namesup.cpp:266
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
#define UDF_CCB_CAN_BE_8_DOT_3
Definition: struct.h:169
#define UDF_CCB_WILDCARD_PRESENT
Definition: struct.h:168
#define UDF_CCB_MATCH_ALL
Definition: struct.h:167
Definition: udf_rel.h:128
#define HASH_ULFN
Definition: udf_info.h:76
#define HASH_POSIX
Definition: udf_info.h:75
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1837
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1836
#define SL_RESTART_SCAN
Definition: iotypes.h:1835

Referenced by UDFCommonDirControl().

◆ UDFQuerySetEA()

NTSTATUS NTAPI UDFQuerySetEA ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 2484 of file misc.cpp.

2488{
2490// PtrUDFIrpContext PtrIrpContext = NULL;
2491 BOOLEAN AreWeTopLevel = FALSE;
2492
2493 UDFPrint(("UDFQuerySetEA: \n"));
2494
2497 ASSERT(Irp);
2498
2499 // set the top level context
2500 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
2501
2503 Irp->IoStatus.Status = RC;
2504 Irp->IoStatus.Information = 0;
2505 // complete the IRP
2507
2508 if(AreWeTopLevel) {
2510 }
2511
2513
2514 return(RC);
2515} // end UDFQuerySetEA()
#define STATUS_EAS_NOT_SUPPORTED
Definition: ntstatus.h:315

Referenced by UDFInitializeFunctionPointers().

◆ UDFQueryVolInfo()

NTSTATUS NTAPI UDFQueryVolInfo ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 86 of file volinfo.cpp.

90{
92 PtrUDFIrpContext PtrIrpContext = NULL;
93 BOOLEAN AreWeTopLevel = FALSE;
94
95 UDFPrint(("UDFQueryVolInfo: \n"));
96
99 ASSERT(Irp);
100
101 // set the top level context
102 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
103 ASSERT(!UDFIsFSDevObj(DeviceObject));
104
105 _SEH2_TRY {
106
107 // get an IRP context structure and issue the request
108 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
109 if(PtrIrpContext) {
110 RC = UDFCommonQueryVolInfo(PtrIrpContext, Irp);
111 } else {
113 Irp->IoStatus.Status = RC;
114 Irp->IoStatus.Information = 0;
115 // complete the IRP
117 }
118
120
121 RC = UDFExceptionHandler(PtrIrpContext, Irp);
122
124 } _SEH2_END;
125
126 if (AreWeTopLevel) {
128 }
129
131
132 return(RC);
133} // end UDFQueryVolInfo()
NTSTATUS UDFCommonQueryVolInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: volinfo.cpp:149

Referenced by UDFInitializeFunctionPointers().

◆ UDFQueueDelayedClose()

NTSTATUS UDFQueueDelayedClose ( PtrUDFIrpContext  IrpContext,
PtrUDFFCB  Fcb 
)

Definition at line 1106 of file close.cpp.

1110{
1111 PtrUDFIrpContextLite IrpContextLite;
1112 BOOLEAN StartWorker = FALSE;
1113 _SEH2_VOLATILE BOOLEAN AcquiredVcb = FALSE;
1114 NTSTATUS RC;
1115
1116 AdPrint((" UDFQueueDelayedClose\n"));
1117
1118 _SEH2_TRY {
1119 // Acquire DelayedCloseResource
1120 UDFAcquireResourceExclusive(&(UDFGlobalData.DelayedCloseResource), TRUE);
1121
1122 UDFAcquireResourceShared(&(Fcb->Vcb->VCBResource), TRUE);
1123 AcquiredVcb = TRUE;
1124
1125 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
1127 }
1128
1129 if(Fcb->IrpContextLite ||
1130 Fcb->FCBFlags & UDF_FCB_POSTED_RENAME) {
1131// BrutePoint();
1133 }
1134
1135 if(!NT_SUCCESS(RC = UDFInitializeIrpContextLite(&IrpContextLite,IrpContext,Fcb))) {
1136 try_return(RC);
1137 }
1138
1139 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1140 InsertTailList( &UDFGlobalData.DirDelayedCloseQueue,
1141 &IrpContextLite->DelayedCloseLinks );
1142 UDFGlobalData.DirDelayedCloseCount++;
1143 } else {
1144 InsertTailList( &UDFGlobalData.DelayedCloseQueue,
1145 &IrpContextLite->DelayedCloseLinks );
1146 UDFGlobalData.DelayedCloseCount++;
1147 }
1148 Fcb->IrpContextLite = IrpContextLite;
1149
1150 // If we are above our threshold then start the delayed
1151 // close operation.
1152 if(UDFGlobalData.DelayedCloseCount > UDFGlobalData.MaxDelayedCloseCount) {
1153
1154 UDFGlobalData.ReduceDelayedClose = TRUE;
1155
1156 if(!UDFGlobalData.FspCloseActive) {
1157
1158 UDFGlobalData.FspCloseActive = TRUE;
1159 StartWorker = TRUE;
1160 }
1161 }
1162 // If we are above our threshold then start the delayed
1163 // close operation.
1164 if(UDFGlobalData.DirDelayedCloseCount > UDFGlobalData.MaxDirDelayedCloseCount) {
1165
1166 UDFGlobalData.ReduceDirDelayedClose = TRUE;
1167
1168 if(!UDFGlobalData.FspCloseActive) {
1169
1170 UDFGlobalData.FspCloseActive = TRUE;
1171 StartWorker = TRUE;
1172 }
1173 }
1174 // Start the FspClose thread if we need to.
1175 if(StartWorker) {
1177 }
1178 RC = STATUS_SUCCESS;
1179
1180try_exit: NOTHING;
1181
1182 } _SEH2_FINALLY {
1183
1184 if(!NT_SUCCESS(RC)) {
1185 Fcb->FCBFlags &= ~UDF_FCB_DELAY_CLOSE;
1186 }
1187 if(AcquiredVcb) {
1188 UDFReleaseResource(&(Fcb->Vcb->VCBResource));
1189 }
1190 // Release DelayedCloseResource
1191 UDFReleaseResource(&(UDFGlobalData.DelayedCloseResource));
1192 } _SEH2_END;
1193 return RC;
1194} // end UDFQueueDelayedClose()
NTSTATUS UDFInitializeIrpContextLite(OUT PtrUDFIrpContextLite *IrpContextLite, IN PtrUDFIrpContext IrpContext, IN PtrUDFFCB Fcb)
Definition: misc.cpp:2457
#define UDF_FCB_POSTED_RENAME
Definition: struct.h:317
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
@ CriticalWorkQueue
Definition: extypes.h:189

Referenced by UDFCommonClose().

◆ UDFRead()

OSSTATUS NTAPI UDFRead ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 53 of file read.cpp.

56{
58 PtrUDFIrpContext PtrIrpContext = NULL;
59 BOOLEAN AreWeTopLevel = FALSE;
60
61 TmPrint(("UDFRead: \n"));
62
65 ASSERT(Irp);
66
67 // set the top level context
68 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
69 ASSERT(!UDFIsFSDevObj(DeviceObject));
70
71 _SEH2_TRY {
72
73 // get an IRP context structure and issue the request
74 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
75 if(PtrIrpContext) {
76 RC = UDFCommonRead(PtrIrpContext, Irp);
77 } else {
79 Irp->IoStatus.Status = RC;
80 Irp->IoStatus.Information = 0;
81 // complete the IRP
83 }
84
86
87 RC = UDFExceptionHandler(PtrIrpContext, Irp);
88
90 } _SEH2_END;
91
92 if (AreWeTopLevel) {
94 }
95
97
98 return(RC);
99} // end UDFRead()
NTSTATUS UDFCommonRead(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: read.cpp:229

Referenced by UDFInitializeFunctionPointers().

◆ UDFReadRegKeys()

VOID UDFReadRegKeys ( PVCB  Vcb,
BOOLEAN  Update,
BOOLEAN  UseCfg 
)

Definition at line 1780 of file misc.cpp.

1785{
1786 ULONG mult = 1;
1787 ptrUDFGetParameter UDFGetParameter = UseCfg ? UDFGetCfgParameter : UDFGetRegParameter;
1788
1789 Vcb->DefaultRegName = UDFMediaClassName[(ULONG)UDFGetMediaClass(Vcb)].ClassName;
1790
1791 // Should we use Extended FE by default ?
1792 Vcb->UseExtendedFE = (UCHAR)UDFGetParameter(Vcb, REG_USEEXTENDEDFE_NAME,
1793 Update ? Vcb->UseExtendedFE : FALSE);
1794 if(Vcb->UseExtendedFE != TRUE) Vcb->UseExtendedFE = FALSE;
1795 // What type of AllocDescs should we use
1796 Vcb->DefaultAllocMode = (USHORT)UDFGetParameter(Vcb, REG_DEFALLOCMODE_NAME,
1797 Update ? Vcb->DefaultAllocMode : ICB_FLAG_AD_SHORT);
1798 if(Vcb->DefaultAllocMode > ICB_FLAG_AD_LONG) Vcb->DefaultAllocMode = ICB_FLAG_AD_SHORT;
1799 // Default UID & GID to be set on newly created files
1800 Vcb->DefaultUID = UDFGetParameter(Vcb, UDF_DEFAULT_UID_NAME, Update ? Vcb->DefaultUID : -1);
1801 Vcb->DefaultGID = UDFGetParameter(Vcb, UDF_DEFAULT_GID_NAME, Update ? Vcb->DefaultGID : -1);
1802 // FE allocation charge for plain Dirs
1803 Vcb->FECharge = UDFGetParameter(Vcb, UDF_FE_CHARGE_NAME, Update ? Vcb->FECharge : 0);
1804 if(!Vcb->FECharge)
1805 Vcb->FECharge = UDF_DEFAULT_FE_CHARGE;
1806 // FE allocation charge for Stream Dirs (SDir)
1807 Vcb->FEChargeSDir = UDFGetParameter(Vcb, UDF_FE_CHARGE_SDIR_NAME,
1808 Update ? Vcb->FEChargeSDir : 0);
1809 if(!Vcb->FEChargeSDir)
1810 Vcb->FEChargeSDir = UDF_DEFAULT_FE_CHARGE_SDIR;
1811 // How many Deleted entries should contain Directory to make us
1812 // start packing it.
1813 Vcb->PackDirThreshold = UDFGetParameter(Vcb, UDF_DIR_PACK_THRESHOLD_NAME,
1814 Update ? Vcb->PackDirThreshold : 0);
1815 if(Vcb->PackDirThreshold == 0xffffffff)
1816 Vcb->PackDirThreshold = UDF_DEFAULT_DIR_PACK_THRESHOLD;
1817 // The binary exponent for the number of Pages to be read-ahead'ed
1818 // This information would be sent to System Cache Manager
1819 if(!Update) {
1820 Vcb->SystemCacheGran = (1 << UDFGetParameter(Vcb, UDF_READAHEAD_GRAN_NAME, 0)) * PAGE_SIZE;
1821 if(!Vcb->SystemCacheGran)
1822 Vcb->SystemCacheGran = UDF_DEFAULT_READAHEAD_GRAN;
1823 }
1824 // Timeouts for FreeSpaceBitMap & TheWholeDirTree flushes
1825 Vcb->BM_FlushPriod = UDFGetParameter(Vcb, UDF_BM_FLUSH_PERIOD_NAME,
1826 Update ? Vcb->BM_FlushPriod : 0);
1827 if(!Vcb->BM_FlushPriod) {
1828 Vcb->BM_FlushPriod = UDF_DEFAULT_BM_FLUSH_TIMEOUT;
1829 } else
1830 if(Vcb->BM_FlushPriod == (ULONG)-1) {
1831 Vcb->BM_FlushPriod = 0;
1832 }
1833 Vcb->Tree_FlushPriod = UDFGetParameter(Vcb, UDF_TREE_FLUSH_PERIOD_NAME,
1834 Update ? Vcb->Tree_FlushPriod : 0);
1835 if(!Vcb->Tree_FlushPriod) {
1836 Vcb->Tree_FlushPriod = UDF_DEFAULT_TREE_FLUSH_TIMEOUT;
1837 } else
1838 if(Vcb->Tree_FlushPriod == (ULONG)-1) {
1839 Vcb->Tree_FlushPriod = 0;
1840 }
1841 Vcb->SkipCountLimit = UDFGetParameter(Vcb, UDF_NO_UPDATE_PERIOD_NAME,
1842 Update ? Vcb->SkipCountLimit : 0);
1843 if(!Vcb->SkipCountLimit)
1844 Vcb->SkipCountLimit = -1;
1845
1846 Vcb->SkipEjectCountLimit = UDFGetParameter(Vcb, UDF_NO_EJECT_PERIOD_NAME,
1847 Update ? Vcb->SkipEjectCountLimit : 3);
1848
1849 if(!Update) {
1850 // How many threads are allowed to sodomize Disc simultaneously on each CPU
1851 Vcb->ThreadsPerCpu = UDFGetParameter(Vcb, UDF_FSP_THREAD_PER_CPU_NAME,
1852 Update ? Vcb->ThreadsPerCpu : 2);
1853 if(Vcb->ThreadsPerCpu < 2)
1854 Vcb->ThreadsPerCpu = UDF_DEFAULT_FSP_THREAD_PER_CPU;
1855 }
1856 // The mimimum FileSize increment when we'll decide not to allocate
1857 // on-disk space.
1858 Vcb->SparseThreshold = UDFGetParameter(Vcb, UDF_SPARSE_THRESHOLD_NAME,
1859 Update ? Vcb->SparseThreshold : 0);
1860 if(!Vcb->SparseThreshold)
1861 Vcb->SparseThreshold = UDF_DEFAULT_SPARSE_THRESHOLD;
1862 // This option is used to VERIFY all the data written. It decreases performance
1863 Vcb->VerifyOnWrite = UDFGetParameter(Vcb, UDF_VERIFY_ON_WRITE_NAME,
1864 Update ? Vcb->VerifyOnWrite : FALSE) ? TRUE : FALSE;
1865
1866#ifndef UDF_READ_ONLY_BUILD
1867 // Should we update AttrFileTime on Attr changes
1869 // Should we update ModifyFileTime on Writes changes
1870 // It also affects ARCHIVE bit setting on write operations
1872 // Should we update AccessFileTime on Exec & so on.
1874 // Should we update Archive bit
1876 // Should we update Dir's Times & Attrs on Modify
1878 // Should we update Dir's Times & Attrs on Access
1880 // Should we allow user to write into Read-Only Directory
1882 // Should we allow user to change Access Time for unchanged Directory
1884#endif //UDF_READ_ONLY_BUILD
1885 // Should we record Allocation Descriptors in W2k-compatible form
1887 // Should we read LONG_ADs with invalid PartitionReferenceNumber (generated by Nero Instant Burner)
1889 // Should we make a copy of VolumeLabel in LVD
1890 // usually only PVD is updated
1892 // Should we handle or ignore HW_RO flag
1894 // Should we handle or ignore SOFT_RO flag
1896
1897 // Check if we should generate UDF-style or OS-style DOS-names
1899#ifndef UDF_READ_ONLY_BUILD
1900 // should we force FO_WRITE_THROUGH on removable media
1902 (Vcb->TargetDeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) ? TRUE : FALSE
1903 );
1904#endif //UDF_READ_ONLY_BUILD
1905 // Should we ignore FO_SEQUENTIAL_ONLY
1907// Force Read-only mounts
1908#ifndef UDF_READ_ONLY_BUILD
1910#else //UDF_READ_ONLY_BUILD
1911 Vcb->CompatFlags |= UDF_VCB_IC_FORCE_HW_RO;
1912#endif //UDF_READ_ONLY_BUILD
1913 // Check if we should send FLUSH request for File/Dir down to
1914 // underlaying driver
1915 if(UDFGetParameter(Vcb, UDF_FLUSH_MEDIA,Update ? Vcb->FlushMedia : FALSE)) {
1916 Vcb->FlushMedia = TRUE;
1917 } else {
1918 Vcb->FlushMedia = FALSE;
1919 }
1920 // compare data from packet with data to be writen there
1921 // before physical writing
1922 if(!UDFGetParameter(Vcb, UDF_COMPARE_BEFORE_WRITE, Update ? Vcb->DoNotCompareBeforeWrite : FALSE)) {
1923 Vcb->DoNotCompareBeforeWrite = TRUE;
1924 } else {
1925 Vcb->DoNotCompareBeforeWrite = FALSE;
1926 }
1927 if(!Update) {
1928 if(UDFGetParameter(Vcb, UDF_CHAINED_IO, TRUE)) {
1929 Vcb->CacheChainedIo = TRUE;
1930 }
1931
1932 if(UDFGetParameter(Vcb, UDF_FORCE_MOUNT_ALL, FALSE)) {
1933 Vcb->VCBFlags |= UDF_VCB_FLAGS_RAW_DISK;
1934 }
1935 // Should we show Blank.Cd file on damaged/unformatted,
1936 // but UDF-compatible disks
1937 Vcb->ShowBlankCd = (UCHAR)UDFGetParameter(Vcb, UDF_SHOW_BLANK_CD, FALSE);
1938 if(Vcb->ShowBlankCd) {
1939 Vcb->CompatFlags |= UDF_VCB_IC_SHOW_BLANK_CD;
1940 if(Vcb->ShowBlankCd > 2) {
1941 Vcb->ShowBlankCd = 2;
1942 }
1943 }
1944 // Should we wait util CD device return from
1945 // Becoming Ready state
1946 if(UDFGetParameter(Vcb, UDF_WAIT_CD_SPINUP, TRUE)) {
1947 Vcb->CompatFlags |= UDF_VCB_IC_WAIT_CD_SPINUP;
1948 }
1949 // Should we remenber bad VDS locations during mount
1950 // Caching will improve mount performance on bad disks, but
1951 // will degrade mauntability of unreliable discs
1952 if(UDFGetParameter(Vcb, UDF_CACHE_BAD_VDS, TRUE)) {
1953 Vcb->CompatFlags |= UDF_VCB_IC_CACHE_BAD_VDS;
1954 }
1955
1956 // Set partitially damaged volume mount mode
1957 Vcb->PartitialDamagedVolumeAction = (UCHAR)UDFGetParameter(Vcb, UDF_PART_DAMAGED_BEHAVIOR, UDF_PART_DAMAGED_RW);
1958 if(Vcb->PartitialDamagedVolumeAction > 2) {
1959 Vcb->PartitialDamagedVolumeAction = UDF_PART_DAMAGED_RW;
1960 }
1961
1962 // Set partitially damaged volume mount mode
1963 Vcb->NoFreeRelocationSpaceVolumeAction = (UCHAR)UDFGetParameter(Vcb, UDF_NO_SPARE_BEHAVIOR, UDF_PART_DAMAGED_RW);
1964 if(Vcb->NoFreeRelocationSpaceVolumeAction > 1) {
1965 Vcb->NoFreeRelocationSpaceVolumeAction = UDF_PART_DAMAGED_RW;
1966 }
1967
1968 // Set dirty volume mount mode
1969 if(UDFGetParameter(Vcb, UDF_DIRTY_VOLUME_BEHAVIOR, UDF_PART_DAMAGED_RO)) {
1970 Vcb->CompatFlags |= UDF_VCB_IC_DIRTY_RO;
1971 }
1972
1973 mult = UDFGetParameter(Vcb, UDF_CACHE_SIZE_MULTIPLIER, 1);
1974 if(!mult) mult = 1;
1975 Vcb->WCacheMaxBlocks *= mult;
1976 Vcb->WCacheMaxFrames *= mult;
1977
1978 if(UDFGetParameter(Vcb, UDF_USE_EJECT_BUTTON, TRUE)) {
1979 Vcb->UseEvent = TRUE;
1980 }
1981 }
1982 return;
1983} // end UDFReadRegKeys()
@ Update
Definition: registry.c:565
VOID UDFUpdateCompatOption(PVCB Vcb, BOOLEAN Update, BOOLEAN UseCfg, PCWSTR Name, ULONG Flag, BOOLEAN Default)
Definition: misc.cpp:1761
ULONG UDFGetCfgParameter(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:2000
ULONG(* ptrUDFGetParameter)(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:1754
UDFFSD_MEDIA_TYPE UDFGetMediaClass(PVCB Vcb)
Definition: misc.cpp:1694
ULONG UDFGetRegParameter(IN PVCB Vcb, IN PCWSTR Name, IN ULONG DefValue)
Definition: misc.cpp:1986
#define ICB_FLAG_AD_LONG
Definition: ecma_167.h:494
#define ICB_FLAG_AD_SHORT
Definition: ecma_167.h:493
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define UDF_VCB_IC_HW_RO
Definition: udf_common.h:502
#define UDF_VCB_IC_FORCE_HW_RO
Definition: udf_common.h:505
#define UDF_VCB_IC_IGNORE_SEQUENTIAL_IO
Definition: udf_common.h:506
#define UDF_VCB_IC_OS_NATIVE_DOS_NAME
Definition: udf_common.h:503
#define UDF_VCB_IC_WAIT_CD_SPINUP
Definition: udf_common.h:519
#define UDF_VCB_IC_W2K_COMPAT_ALLOC_DESCS
Definition: udf_common.h:501
#define UDF_VCB_IC_INSTANT_COMPAT_ALLOC_DESCS
Definition: udf_common.h:513
#define UDF_VCB_IC_UPDATE_DIR_READ
Definition: udf_common.h:498
#define UDF_VCB_IC_CACHE_BAD_VDS
Definition: udf_common.h:518
#define UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME
Definition: udf_common.h:500
struct UDF_MEDIA_CLASS_NAMES UDFMediaClassName[]
Definition: udfinit.cpp:29
#define UDF_VCB_IC_SHOW_BLANK_CD
Definition: udf_common.h:520
#define UDF_VCB_IC_SOFT_RO
Definition: udf_common.h:514
#define UDF_VCB_IC_W2K_COMPAT_VLABEL
Definition: udf_common.h:517
#define UDF_VCB_IC_FORCE_WRITE_THROUGH
Definition: udf_common.h:504
#define UDF_SHOW_BLANK_CD
Definition: udf_reg.h:224
#define UDF_INSTANT_COMPAT_ALLOC_DESCS
Definition: udf_reg.h:179
#define UDF_PART_DAMAGED_BEHAVIOR
Definition: udf_reg.h:215
#define UDF_W2K_COMPAT_ALLOC_DESCS
Definition: udf_reg.h:173
#define UDF_FORCE_WRITE_THROUGH_NAME
Definition: udf_reg.h:206
#define UDF_UPDATE_DIR_TIMES_ATTR_W
Definition: udf_reg.h:161
#define UDF_UPDATE_TIMES_ATTR
Definition: udf_reg.h:149
#define UDF_CHAINED_IO
Definition: udf_reg.h:200
#define UDF_FE_CHARGE_NAME
Definition: udf_reg.h:113
#define UDF_FSP_THREAD_PER_CPU_NAME
Definition: udf_reg.h:131
#define REG_USEEXTENDEDFE_NAME
Definition: udf_reg.h:98
#define UDF_NO_SPARE_BEHAVIOR
Definition: udf_reg.h:218
#define UDF_ALLOW_UPDATE_TIMES_ACCS_UCHG_DIR
Definition: udf_reg.h:170
#define UDF_FE_CHARGE_SDIR_NAME
Definition: udf_reg.h:116
#define UDF_ALLOW_WRITE_IN_RO_DIR
Definition: udf_reg.h:167
#define REG_DEFALLOCMODE_NAME
Definition: udf_reg.h:101
#define UDF_HANDLE_SOFT_RO
Definition: udf_reg.h:185
#define UDF_OS_NATIVE_DOS_NAME
Definition: udf_reg.h:203
#define UDF_NO_EJECT_PERIOD_NAME
Definition: udf_reg.h:128
#define UDF_BM_FLUSH_PERIOD_NAME
Definition: udf_reg.h:119
#define UDF_CACHE_SIZE_MULTIPLIER
Definition: udf_reg.h:197
#define UDF_DIR_PACK_THRESHOLD_NAME
Definition: udf_reg.h:110
#define UDF_DEFAULT_UID_NAME
Definition: udf_reg.h:104
#define UDF_READAHEAD_GRAN_NAME
Definition: udf_reg.h:134
#define UDF_TREE_FLUSH_PERIOD_NAME
Definition: udf_reg.h:122
#define UDF_UPDATE_ATTR_ARCH
Definition: udf_reg.h:158
#define UDF_UPDATE_TIMES_MOD
Definition: udf_reg.h:152
#define UDF_NO_UPDATE_PERIOD_NAME
Definition: udf_reg.h:125
#define UDF_WAIT_CD_SPINUP
Definition: udf_reg.h:227
#define UDF_FORCE_HW_RO
Definition: udf_reg.h:209
#define UDF_SPARSE_THRESHOLD_NAME
Definition: udf_reg.h:143
#define UDF_VERIFY_ON_WRITE_NAME
Definition: udf_reg.h:146
#define UDF_FORCE_MOUNT_ALL
Definition: udf_reg.h:191
#define UDF_COMPARE_BEFORE_WRITE
Definition: udf_reg.h:194
#define UDF_DIRTY_VOLUME_BEHAVIOR
Definition: udf_reg.h:221
#define UDF_W2K_COMPAT_VLABEL
Definition: udf_reg.h:176
#define UDF_HANDLE_HW_RO
Definition: udf_reg.h:182
#define UDF_IGNORE_SEQUENTIAL_IO
Definition: udf_reg.h:212
#define UDF_DEFAULT_GID_NAME
Definition: udf_reg.h:107
#define UDF_USE_EJECT_BUTTON
Definition: udf_reg.h:236
#define UDF_CACHE_BAD_VDS
Definition: udf_reg.h:233
#define UDF_UPDATE_TIMES_ACCS
Definition: udf_reg.h:155
#define UDF_FLUSH_MEDIA
Definition: udf_reg.h:188
#define UDF_UPDATE_DIR_TIMES_ATTR_R
Definition: udf_reg.h:164
#define UDF_DEFAULT_FE_CHARGE_SDIR
Definition: udf_rel.h:501
#define UDF_DEFAULT_FE_CHARGE
Definition: udf_rel.h:500
#define UDF_DEFAULT_TREE_FLUSH_TIMEOUT
Definition: udffs.h:96
#define UDF_DEFAULT_BM_FLUSH_TIMEOUT
Definition: udffs.h:95
#define UDF_DEFAULT_READAHEAD_GRAN
Definition: udffs.h:55
#define UDF_DEFAULT_SPARSE_THRESHOLD
Definition: udffs.h:56
#define UDF_DEFAULT_FSP_THREAD_PER_CPU
Definition: udffs.h:98
#define UDF_DEFAULT_DIR_PACK_THRESHOLD
Definition: udffs.h:50
#define UDF_PART_DAMAGED_RW
Definition: udfpubl.h:120
#define UDF_PART_DAMAGED_RO
Definition: udfpubl.h:121

Referenced by UDFCommonDeviceControl(), UDFCompleteMount(), and UDFMountVolume().

◆ UDFReadSecurity()

NTSTATUS UDFReadSecurity ( IN PVCB  Vcb,
IN PtrUDFFCB  Fcb,
IN PSECURITY_DESCRIPTOR SecurityDesc 
)

Definition at line 420 of file secursup.cpp.

425{
426#ifdef UDF_ENABLE_SECURITY
428 PUDF_FILE_INFO SDirInfo = NULL;
429 PUDF_FILE_INFO AclInfo = NULL;
430 NTSTATUS RC;
431 ULONG NumberBytesRead;
432 PERESOURCE Res1 = NULL;
433
434 UDFPrint(("UDFReadSecurity\n"));
435
436 _SEH2_TRY {
437
438 FileInfo = Fcb->FileInfo;
440 if(!FileInfo) {
441 UDFPrint((" Volume Security\n"));
443 }
444 if(Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) {
445 UDFPrint((" No Security on blank volume\n"));
447 }
448
449 // Open Stream Directory
450 RC = UDFOpenStreamDir__(Vcb, FileInfo, &SDirInfo);
451
452 if(RC == STATUS_NOT_FOUND)
454 if(!NT_SUCCESS(RC)) {
455 if(UDFCleanUpFile__(Vcb, SDirInfo)) {
456 if(SDirInfo) MyFreePool__(SDirInfo);
457 }
458 SDirInfo = NULL;
459 try_return(RC);
460 }
461 // Acquire SDir exclusively if Fcb present
462 if(SDirInfo->Fcb) {
463 BrutePoint();
464 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
465 UDFAcquireResourceExclusive(Res1 = &(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
466 }
467
468 // Open Acl Stream
469 RC = UDFOpenFile__(Vcb,
471 SDirInfo,&AclInfo,NULL);
474 if(!NT_SUCCESS(RC)) {
475 if(UDFCleanUpFile__(Vcb, AclInfo)) {
476 if(AclInfo) MyFreePool__(AclInfo);
477 }
478 AclInfo = NULL;
479 try_return(RC);
480 }
481
482 NumberBytesRead = (ULONG)UDFGetFileSize(AclInfo);
483 (*SecurityDesc) = DbgAllocatePool(NonPagedPool, NumberBytesRead);
484 if(!(*SecurityDesc))
486 RC = UDFReadFile__(Vcb, AclInfo, 0, NumberBytesRead,
487 FALSE, (PCHAR)(*SecurityDesc), &NumberBytesRead);
488 if(!NT_SUCCESS(RC))
489 try_return(RC);
490
491 RC = RtlValidSecurityDescriptor(*SecurityDesc);
492
493try_exit: NOTHING;
494
495 } _SEH2_FINALLY {
496
497 if(AclInfo) {
498 UDFCloseFile__(Vcb, AclInfo);
499 if(UDFCleanUpFile__(Vcb, AclInfo))
500 MyFreePool__(AclInfo);
501 }
502
503 if(SDirInfo) {
504 UDFCloseFile__(Vcb, SDirInfo);
505 if(UDFCleanUpFile__(Vcb, SDirInfo))
506 MyFreePool__(SDirInfo);
507 }
508
509 if(!NT_SUCCESS(RC) && (*SecurityDesc)) {
510 DbgFreePool(*SecurityDesc);
511 (*SecurityDesc) = NULL;
512 }
513 if(Res1)
514 UDFReleaseResource(Res1);
515 }
516
517 return RC;
518#else
520#endif //UDF_ENABLE_SECURITY
521
522} // end UDFReadSecurity()
NTSYSAPI BOOLEAN NTAPI RtlValidSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: sd.c:1054
UNICODE_STRING AclName
Definition: udf_common.h:618

Referenced by UDFAssignAcl().

◆ UDFRegCheckParameterValue()

ULONG UDFRegCheckParameterValue ( IN PUNICODE_STRING  RegistryPath,
IN PCWSTR  Name,
IN PUNICODE_STRING  PtrVolumePath,
IN PCWSTR  DefaultPath,
IN ULONG  DefValue = 0 
)

Definition at line 2225 of file misc.cpp.

2232{
2234
2235 ULONG val = DefValue;
2236
2237 UNICODE_STRING paramStr;
2238 UNICODE_STRING defaultParamStr;
2239 UNICODE_STRING paramPathUnknownStr;
2240
2241 UNICODE_STRING paramSuffix;
2242 UNICODE_STRING paramPath;
2243 UNICODE_STRING paramPathUnknown;
2244 UNICODE_STRING paramDevPath;
2245 UNICODE_STRING defaultParamPath;
2246
2247 _SEH2_TRY {
2248
2249 paramPath.Buffer = NULL;
2250 paramDevPath.Buffer = NULL;
2251 paramPathUnknown.Buffer = NULL;
2252 defaultParamPath.Buffer = NULL;
2253
2254 // First append \Parameters to the passed in registry path
2255 // Note, RtlInitUnicodeString doesn't allocate memory
2256 RtlInitUnicodeString(&paramStr, L"\\Parameters");
2257 RtlInitUnicodeString(&paramPath, NULL);
2258
2259 RtlInitUnicodeString(&paramPathUnknownStr, REG_DEFAULT_UNKNOWN);
2260 RtlInitUnicodeString(&paramPathUnknown, NULL);
2261
2262 paramPathUnknown.MaximumLength = RegistryPath->Length + paramPathUnknownStr.Length + paramStr.Length + sizeof(WCHAR);
2263 paramPath.MaximumLength = RegistryPath->Length + paramStr.Length + sizeof(WCHAR);
2264
2265 paramPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramPath.MaximumLength);
2266 if(!paramPath.Buffer) {
2267 UDFPrint(("UDFCheckRegValue: couldn't allocate paramPath\n"));
2268 try_return(val = DefValue);
2269 }
2270 paramPathUnknown.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramPathUnknown.MaximumLength);
2271 if(!paramPathUnknown.Buffer) {
2272 UDFPrint(("UDFCheckRegValue: couldn't allocate paramPathUnknown\n"));
2273 try_return(val = DefValue);
2274 }
2275
2276 RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
2277 status = RtlAppendUnicodeToString(&paramPath, RegistryPath->Buffer);
2278 if(!NT_SUCCESS(status)) {
2279 try_return(val = DefValue);
2280 }
2281 status = RtlAppendUnicodeToString(&paramPath, paramStr.Buffer);
2282 if(!NT_SUCCESS(status)) {
2283 try_return(val = DefValue);
2284 }
2285 UDFPrint(("UDFCheckRegValue: (1) |%S|\n", paramPath.Buffer));
2286
2287 RtlZeroMemory(paramPathUnknown.Buffer, paramPathUnknown.MaximumLength);
2288 status = RtlAppendUnicodeToString(&paramPathUnknown, RegistryPath->Buffer);
2289 if(!NT_SUCCESS(status)) {
2290 try_return(val = DefValue);
2291 }
2292 status = RtlAppendUnicodeToString(&paramPathUnknown, paramStr.Buffer);
2293 if(!NT_SUCCESS(status)) {
2294 try_return(val = DefValue);
2295 }
2296 status = RtlAppendUnicodeToString(&paramPathUnknown, paramPathUnknownStr.Buffer);
2297 if(!NT_SUCCESS(status)) {
2298 try_return(val = DefValue);
2299 }
2300 UDFPrint(("UDFCheckRegValue: (2) |%S|\n", paramPathUnknown.Buffer));
2301
2302 // First append \Parameters\Default_XXX to the passed in registry path
2303 if(DefaultPath) {
2304 RtlInitUnicodeString(&defaultParamStr, DefaultPath);
2305 RtlInitUnicodeString(&defaultParamPath, NULL);
2306 defaultParamPath.MaximumLength = paramPath.Length + defaultParamStr.Length + sizeof(WCHAR);
2307 defaultParamPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, defaultParamPath.MaximumLength);
2308 if(!defaultParamPath.Buffer) {
2309 UDFPrint(("UDFCheckRegValue: couldn't allocate defaultParamPath\n"));
2310 try_return(val = DefValue);
2311 }
2312
2313 RtlZeroMemory(defaultParamPath.Buffer, defaultParamPath.MaximumLength);
2314 status = RtlAppendUnicodeToString(&defaultParamPath, paramPath.Buffer);
2315 if(!NT_SUCCESS(status)) {
2316 try_return(val = DefValue);
2317 }
2318 status = RtlAppendUnicodeToString(&defaultParamPath, defaultParamStr.Buffer);
2319 if(!NT_SUCCESS(status)) {
2320 try_return(val = DefValue);
2321 }
2322 UDFPrint(("UDFCheckRegValue: (3) |%S|\n", defaultParamPath.Buffer));
2323 }
2324
2325 if(PtrVolumePath) {
2326 paramSuffix = *PtrVolumePath;
2327 } else {
2328 RtlInitUnicodeString(&paramSuffix, NULL);
2329 }
2330
2331 RtlInitUnicodeString(&paramDevPath, NULL);
2332 // now build the device specific path
2333 paramDevPath.MaximumLength = paramPath.Length + paramSuffix.Length + sizeof(WCHAR);
2334 paramDevPath.Buffer = (PWCH)MyAllocatePool__(PagedPool, paramDevPath.MaximumLength);
2335 if(!paramDevPath.Buffer) {
2336 try_return(val = DefValue);
2337 }
2338
2339 RtlZeroMemory(paramDevPath.Buffer, paramDevPath.MaximumLength);
2340 status = RtlAppendUnicodeToString(&paramDevPath, paramPath.Buffer);
2341 if(!NT_SUCCESS(status)) {
2342 try_return(val = DefValue);
2343 }
2344 if(paramSuffix.Buffer) {
2345 status = RtlAppendUnicodeToString(&paramDevPath, paramSuffix.Buffer);
2346 if(!NT_SUCCESS(status)) {
2347 try_return(val = DefValue);
2348 }
2349 }
2350
2351 UDFPrint(( " Parameter = %ws\n", Name));
2352
2353 {
2354 HKEY hk = NULL;
2355 status = RegTGetKeyHandle(NULL, RegistryPath->Buffer, &hk);
2356 if(NT_SUCCESS(status)) {
2358 }
2359 }
2360
2361
2362 // *** Read GLOBAL_DEFAULTS from
2363 // "\DwUdf\Parameters_Unknown\"
2364
2365 status = RegTGetDwordValue(NULL, paramPath.Buffer, Name, &val);
2366
2367 // *** Read DEV_CLASS_SPEC_DEFAULTS (if any) from
2368 // "\DwUdf\Parameters_%DevClass%\"
2369
2370 if(DefaultPath) {
2371 status = RegTGetDwordValue(NULL, defaultParamPath.Buffer, Name, &val);
2372 }
2373
2374 // *** Read DEV_SPEC_PARAMS from (if device supports GetDevName)
2375 // "\DwUdf\Parameters\%DevName%\"
2376
2377 status = RegTGetDwordValue(NULL, paramDevPath.Buffer, Name, &val);
2378
2379try_exit: NOTHING;
2380
2381 } _SEH2_FINALLY {
2382
2383 if(DefaultPath && defaultParamPath.Buffer) {
2384 MyFreePool__(defaultParamPath.Buffer);
2385 }
2386 if(paramPath.Buffer) {
2387 MyFreePool__(paramPath.Buffer);
2388 }
2389 if(paramDevPath.Buffer) {
2390 MyFreePool__(paramDevPath.Buffer);
2391 }
2392 if(paramPathUnknown.Buffer) {
2393 MyFreePool__(paramPathUnknown.Buffer);
2394 }
2395 } _SEH2_END;
2396
2397 UDFPrint(( "UDFCheckRegValue: %ws for drive %s is %x\n\n", Name, PtrVolumePath, val));
2398 return val;
2399} // end UDFRegCheckParameterValue()
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define PagedPool
Definition: env_spec_w32.h:308
GLuint GLfloat * val
Definition: glext.h:7180
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
WCHAR * PWCH
Definition: ntbasedef.h:410
BOOLEAN RegTGetDwordValue(IN HKEY hRootKey, IN PCWSTR RegistryPath, IN PCWSTR Name, IN PULONG pUlong)
Definition: regtools.cpp:99
VOID RegTCloseKeyHandle(IN HKEY hKey)
Definition: regtools.cpp:86
NTSTATUS RegTGetKeyHandle(IN HKEY hRootKey, IN PWCHAR KeyName, OUT HKEY *hKey)
Definition: regtools.cpp:59
#define REG_DEFAULT_UNKNOWN
Definition: udf_reg.h:75
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215

Referenced by UDFGetRegParameter().

◆ UDFReleaseCCB()

VOID __fastcall UDFReleaseCCB ( PtrUDFCCB  Ccb)

Definition at line 768 of file misc.cpp.

771{
772 KIRQL CurrentIrql;
773
774 ASSERT(Ccb);
775
776 UDFPrint(("UDFReleaseCCB: %x\n", Ccb));
777 // give back memory either to the zone or to the VMM
778 if(!(Ccb->CCBFlags & UDF_CCB_NOT_FROM_ZONE)) {
779 // back to the zone
780 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
781 ExFreeToZone(&(UDFGlobalData.CCBZoneHeader), Ccb);
782 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
783 } else {
785 }
786
787 return;
788} // end UDFReleaseCCB()
static __inline PVOID ExFreeToZone(IN PZONE_HEADER Zone, IN PVOID Block)
Definition: exfuncs.h:297

Referenced by UDFCleanUpCCB().

◆ UDFReleaseFCB()

__inline VOID UDFReleaseFCB ( PtrUDFFCB  Fcb)

Definition at line 620 of file protos.h.

623{
624 ASSERT(Fcb);
625
627
628 return;
629}

Referenced by UDFCleanUpFCB().

◆ UDFReleaseFileIdCache()

VOID UDFReleaseFileIdCache ( IN PVCB  Vcb)

Definition at line 2456 of file fileinfo.cpp.

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()

Referenced by UDFCleanupVCB().

◆ UDFReleaseIrpContext()

VOID UDFReleaseIrpContext ( PtrUDFIrpContext  PtrIrpContext)

Definition at line 1086 of file misc.cpp.

1088{
1089 if(!PtrIrpContext) return;
1090// ASSERT(PtrIrpContext);
1091
1092#ifdef UDF_DBG
1093 IrpContextCounter--;
1094#endif //UDF_DBG
1095
1096 // give back memory either to the zone or to the VMM
1097 if (!(PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_NOT_FROM_ZONE)) {
1098 // back to the zone
1099 KIRQL CurrentIrql;
1100
1101 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
1102 ExFreeToZone(&(UDFGlobalData.IrpContextZoneHeader), PtrIrpContext);
1103 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
1104 } else {
1105 MyFreePool__(PtrIrpContext);
1106 }
1107
1108 return;
1109} // end UDFReleaseIrpContext()

Referenced by UDFCommonCleanup(), UDFCommonClose(), UDFCommonCreate(), UDFCommonDeviceControl(), UDFCommonDirControl(), UDFCommonDispatch(), UDFCommonFileInfo(), UDFCommonFlush(), UDFCommonFSControl(), UDFCommonLockControl(), UDFCommonPnp(), UDFCommonQueryVolInfo(), UDFCommonRead(), UDFCommonSetVolInfo(), UDFCommonShutdown(), UDFCommonWrite(), UDFDevIoctlCompletion(), UDFExceptionHandler(), UDFMdlComplete(), UDFNotifyChangeDirectory(), UDFPerformVerify(), UDFPnpQueryRemove(), UDFPnpRemove(), UDFPnpSurpriseRemove(), and UDFQueryDirectory().

◆ UDFReleaseObjectName()

VOID __fastcall UDFReleaseObjectName ( PtrUDFObjectName  PtrObjectName)

Definition at line 670 of file misc.cpp.

672{
673 KIRQL CurrentIrql;
674
675 ASSERT(PtrObjectName);
676
677 // give back memory either to the zone or to the VMM
678 if (!(PtrObjectName->ObjectNameFlags & UDF_OBJ_NAME_NOT_FROM_ZONE)) {
679 // back to the zone
680 KeAcquireSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), &CurrentIrql);
681 ExFreeToZone(&(UDFGlobalData.ObjectNameZoneHeader), PtrObjectName);
682 KeReleaseSpinLock(&(UDFGlobalData.ZoneAllocationSpinLock), CurrentIrql);
683 } else {
684 MyFreePool__(PtrObjectName);
685 }
686
687 return;
688} // end UDFReleaseObjectName()

Referenced by UDFBlankMount(), UDFCleanUpFCB(), UDFCompleteMount(), UDFFirstOpenFile(), and UDFRename().

◆ UDFReleaseVCB()

VOID UDFReleaseVCB ( PVCB  Vcb)

Definition at line 2137 of file misc.cpp.

2140{
2141 LARGE_INTEGER delay;
2142 UDFPrint(("UDFReleaseVCB\n"));
2143
2144 delay.QuadPart = -500000; // 0.05 sec
2145 while(Vcb->PostedRequestCount) {
2146 UDFPrint(("UDFReleaseVCB: PostedRequestCount = %d\n", Vcb->PostedRequestCount));
2147 // spin until all queues IRPs are processed
2149 delay.QuadPart -= 500000; // grow delay 0.05 sec
2150 }
2151
2152 _SEH2_TRY {
2153 UDFPrint(("UDF: Flushing buffers\n"));
2155 WCacheFlushAll__(&(Vcb->FastCache),Vcb);
2156 WCacheRelease__(&(Vcb->FastCache));
2157
2159 BrutePoint();
2160 } _SEH2_END;
2161
2162#ifdef UDF_DBG
2163 _SEH2_TRY {
2164 if (!ExIsResourceAcquiredShared(&UDFGlobalData.GlobalDataResource)) {
2165 UDFPrint(("UDF: attempt to access to not protected data\n"));
2166 UDFPrint(("UDF: UDFGlobalData\n"));
2167 BrutePoint();
2168 }
2170 BrutePoint();
2171 } _SEH2_END;
2172#endif
2173
2174 _SEH2_TRY {
2175 RemoveEntryList(&(Vcb->NextVCB));
2177 BrutePoint();
2178 } _SEH2_END;
2179
2180/* _SEH2_TRY {
2181 if(Vcb->VCBFlags & UDF_VCB_FLAGS_STOP_WAITER_EVENT)
2182 KeWaitForSingleObject(&(Vcb->WaiterStopped), Executive, KernelMode, FALSE, NULL);
2183 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_STOP_WAITER_EVENT;
2184 } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
2185 BrutePoint();
2186 }*/
2187
2188 _SEH2_TRY {
2189 UDFPrint(("UDF: Delete resources\n"));
2190 UDFDeleteResource(&(Vcb->VCBResource));
2191 UDFDeleteResource(&(Vcb->BitMapResource1));
2192 UDFDeleteResource(&(Vcb->FcbListResource));
2193 UDFDeleteResource(&(Vcb->FileIdResource));
2194 UDFDeleteResource(&(Vcb->DlocResource));
2195 UDFDeleteResource(&(Vcb->DlocResource2));
2196 UDFDeleteResource(&(Vcb->FlushResource));
2197 UDFDeleteResource(&(Vcb->PreallocResource));
2198 UDFDeleteResource(&(Vcb->IoResource));
2200 BrutePoint();
2201 } _SEH2_END;
2202
2203 _SEH2_TRY {
2204 UDFPrint(("UDF: Cleanup VCB\n"));
2205 ASSERT(IsListEmpty(&(Vcb->NextNotifyIRP)));
2206 FsRtlNotifyUninitializeSync(&(Vcb->NotifyIRPMutex));
2209 BrutePoint();
2210 } _SEH2_END;
2211
2212 _SEH2_TRY {
2213 UDFPrint(("UDF: Delete DO\n"));
2214 IoDeleteDevice(Vcb->VCBDeviceObject);
2216 BrutePoint();
2217 } _SEH2_END;
2218
2219} // end UDFReleaseVCB()
VOID UDFCleanupVCB(IN PVCB Vcb)
Definition: fscntrl.cpp:1428
VOID NTAPI FsRtlNotifyUninitializeSync(IN PNOTIFY_SYNC *NotifySync)
Definition: notify.c:1668
VOID WCacheFlushAll__(IN PW_CACHE Cache, IN PVOID Context)
VOID WCacheRelease__(IN PW_CACHE Cache)
#define ExIsResourceAcquiredShared
Definition: exfuncs.h:348

Referenced by UDFCheckForDismount(), and UDFDismountVcb().

◆ UDFRelLazyWrite()

VOID NTAPI UDFRelLazyWrite ( IN PVOID  Context)

Definition at line 472 of file fastio.cpp.

474{
475 // The context is whatever we passed to the Cache Manager when invoking
476 // the CcInitializeCacheMaps() function. In the case of the UDF FSD
477 // implementation, this context is a pointer to the NT_REQ_FCB structure.
479
480 MmPrint((" UDFRelLazyWrite()\n"));
481
482 // Remove the current thread-id from the NT_REQ_FCB
483 // and release the MainResource.
484 ASSERT((NtReqFcb->LazyWriterThreadID) == HandleToUlong(PsGetCurrentThreadId()));
485 NtReqFcb->LazyWriterThreadID = 0;
486
487 // Release the acquired resource.
488 UDFReleaseResource(&(NtReqFcb->PagingIoResource));
489
491 return;
492} // end UDFRelLazyWrite()

Referenced by UDFInitializeFunctionPointers().

◆ UDFRelReadAhead()

VOID NTAPI UDFRelReadAhead ( IN PVOID  Context)

Definition at line 558 of file fastio.cpp.

560{
561 // The context is whatever we passed to the Cache Manager when invoking
562 // the CcInitializeCacheMaps() function. In the case of the UDF FSD
563 // implementation, this context is a pointer to the NT_REQ_FCB structure.
564#define NtReqFcb ((PtrUDFNTRequiredFCB)Context)
565
566 MmPrint((" RelFromReadAhead()\n"));
567
568 // Release the acquired resource.
570 UDFReleaseResource(&(NtReqFcb->MainResource));
571
572 // Of course, the FSD should undo whatever else seems appropriate at this
573 // time.
575
576 return;
577#undef NtReqFcb
578} // end UDFRelReadAhead()

Referenced by UDFInitializeFunctionPointers().

◆ UDFRemoveFileId()

NTSTATUS UDFRemoveFileId ( IN PVCB  Vcb,
IN LONGLONG  Id 
)

Definition at line 2442 of file fileinfo.cpp.

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()

◆ UDFRename()

NTSTATUS UDFRename ( IN PIO_STACK_LOCATION  IrpSp,
IN PtrUDFFCB  Fcb,
IN PtrUDFCCB  Ccb,
IN PFILE_OBJECT  FileObject,
IN PFILE_RENAME_INFORMATION  PtrBuffer 
)

Definition at line 1961 of file fileinfo.cpp.

1968{
1969 // Source Directory
1970 PFILE_OBJECT DirObject1 = FileObject1->RelatedFileObject;
1971 // Target Directory
1972 PFILE_OBJECT DirObject2 = PtrSp->Parameters.SetFile.FileObject;
1973 // Overwite Flag
1974 BOOLEAN Replace = PtrSp->Parameters.SetFile.ReplaceIfExists &&
1975 PtrBuffer->ReplaceIfExists;
1976 NTSTATUS RC;
1977 PVCB Vcb = Fcb1->Vcb;
1978 PtrUDFFCB Fcb2;
1979 BOOLEAN ic;
1980 BOOLEAN AcquiredVcb = TRUE;
1981 BOOLEAN AcquiredVcbEx = FALSE;
1982 BOOLEAN AcquiredDir1 = FALSE;
1983 BOOLEAN AcquiredFcb1 = FALSE;
1984 BOOLEAN SingleDir = TRUE;
1985 BOOLEAN UseClose;
1986
1987 PUDF_FILE_INFO File1;
1988 PUDF_FILE_INFO Dir1;
1989 PUDF_FILE_INFO Dir2;
1990 PUDF_FILE_INFO NextFileInfo, fi;
1991
1993 UNICODE_STRING LocalPath;
1994 PtrUDFCCB CurCcb = NULL;
1996 ULONG i;
1997 ULONG DirRefCount;
1998 ULONG FileInfoRefCount;
1999 ULONG Attr;
2000 PDIR_INDEX_ITEM DirNdx;
2001
2002 AdPrint(("UDFRename %8.8x\n", DirObject2));
2003
2004 LocalPath.Buffer = NULL;
2005
2006 _SEH2_TRY {
2007 // do we try to rename Volume ?
2008#ifdef UDF_ALLOW_RENAME_MOVE
2009 if(!(File1 = Fcb1->FileInfo))
2010#endif //UDF_ALLOW_RENAME_MOVE
2012
2013 // do we try to rename RootDir ?
2014 if(!(Dir1 = File1->ParentFile))
2016
2017 // do we try to rename to RootDir or Volume ?
2018 if(!DirObject2) {
2019 Dir2 = File1->ParentFile;
2020 DirObject2 = DirObject1;
2021 } else
2022 if(DirObject2->FsContext2 &&
2023 (Fcb2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb)) {
2024 Dir2 = ((PtrUDFCCB)(DirObject2->FsContext2))->Fcb->FileInfo;
2025 } else {
2027 }
2028 // invalid destination ?
2029 if(!Dir2) try_return (RC = STATUS_ACCESS_DENIED);
2030
2031 // Stream can't be a Dir or have StreamDir
2032 if(UDFIsAStreamDir(Dir2)) {
2033#ifdef UDF_ENABLE_SECURITY
2034 if(UDFIsADirectory(File1)) {
2036 }
2037 // We should check whether File1 has only Internal
2038 // (or Deleted) streams. In this case SDir should be
2039 // removed (in UDFRenameMoveFile__()). Otherwise
2040 // return STATUS_ACCESS_DENIED
2041 if(UDFHasAStreamDir(File1)) {
2042 UDFPrint(("TODO: We should remove Streams from source file\n"));
2044 }
2045#else //UDF_ENABLE_SECURITY
2046 if(UDFIsADirectory(File1) ||
2047 UDFHasAStreamDir(File1)) {
2049 }
2050#endif //UDF_ENABLE_SECURITY
2051 }
2052
2053 RC = UDFPrepareForRenameMoveLink(Vcb, &AcquiredVcb, &AcquiredVcbEx,
2054 &SingleDir,
2055 &AcquiredDir1, &AcquiredFcb1,
2056 Ccb1, File1,
2057 Dir1, Dir2,
2058 FALSE); // it is Rename operation
2059 if(!NT_SUCCESS(RC))
2060 try_return(RC);
2061
2062 // check if the source file is in use
2063 if(Fcb1->OpenHandleCount > 1)
2065 ASSERT(Fcb1->OpenHandleCount);
2066 ASSERT(!Fcb1->IrpContextLite);
2067 if(Fcb1->IrpContextLite) {
2069 }
2070 // Check if we have parallel/pending Close threads
2071 if(Fcb1->CcbCount && !SingleDir) {
2072 // if this is the 1st attempt, we'll try to
2073 // synchronize with Close requests
2074 // otherwise fail request
2076post_rename:
2077 if(Fcb1->FCBFlags & UDF_FCB_POSTED_RENAME) {
2078 Fcb1->FCBFlags &= ~UDF_FCB_POSTED_RENAME;
2079 try_return (RC);
2080 }
2081 Fcb1->FCBFlags |= UDF_FCB_POSTED_RENAME;
2083 }
2084
2085 if(!DirObject2) {
2086 // Make sure the name is of legal length.
2087 if(PtrBuffer->FileNameLength > UDF_NAME_LEN*sizeof(WCHAR)) {
2089 }
2090 NewName.Length = NewName.MaximumLength = (USHORT)(PtrBuffer->FileNameLength);
2091 NewName.Buffer = (PWCHAR)&(PtrBuffer->FileName);
2092 } else {
2093 // This name is by definition legal.
2094 NewName = *((PUNICODE_STRING)&DirObject2->FileName);
2095 }
2096
2097 ic = (Ccb1->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? FALSE : TRUE;
2098
2099 AdPrint((" %ws ->\n %ws\n",
2100 Fcb1->FCBName->ObjectName.Buffer,
2101 NewName.Buffer));
2102
2103 if(UDFIsDirOpened__(File1)) {
2104 // We can't rename file because of unclean references.
2105 // UDF_INFO package can safely do it, but NT side cannot.
2106 // In this case NT requires STATUS_OBJECT_NAME_COLLISION
2107 // rather than STATUS_ACCESS_DENIED
2108 if(NT_SUCCESS(UDFFindFile__(Vcb, ic, &NewName, Dir2)))
2111 } else {
2112 // Last check before Moving.
2113 // We can't move across Dir referenced (even internally) file
2114 if(!SingleDir) {
2115 RC = UDFDoesOSAllowFileToBeMoved__(File1);
2116 if(!NT_SUCCESS(RC)) {
2117// try_return(RC);
2118 goto post_rename;
2119 }
2120 }
2121
2122 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2123 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2124 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2125
2126 RC = UDFRenameMoveFile__(Vcb, ic, &Replace, &NewName, Dir1, Dir2, File1);
2127 }
2128 if(!NT_SUCCESS(RC))
2129 try_return (RC);
2130
2131 ASSERT(UDFDirIndex(File1->ParentFile->Dloc->DirIndex, File1->Index)->FileInfo == File1);
2132
2133 RC = MyCloneUnicodeString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2135 &(Dir2->Fcb->FCBName->ObjectName) );
2136 if(!NT_SUCCESS(RC)) try_return (RC);
2137// RC = MyAppendUnicodeStringToString(&LocalPath, (Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? &(UDFGlobalData.UnicodeStrRoot) : &(Dir2->Fcb->FCBName->ObjectName));
2138// if(!NT_SUCCESS(RC)) try_return (RC);
2139 if(Dir2->ParentFile) {
2140 RC = MyAppendUnicodeToString(&LocalPath, L"\\");
2141 if(!NT_SUCCESS(RC)) try_return (RC);
2142 }
2143 RC = MyAppendUnicodeStringToStringTag(&LocalPath, &NewName, MEM_USREN_TAG);
2144 if(!NT_SUCCESS(RC)) try_return (RC);
2145
2146 // Set Archive bit
2147 DirNdx = UDFDirIndex(File1->ParentFile->Dloc->DirIndex, File1->Index);
2148 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT) {
2149 Attr = UDFAttributesToNT(DirNdx, File1->Dloc->FileEntry);
2150 if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))
2152 }
2153 // Update Parent Objects (mark 'em as modified)
2154 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_DIR_WRITE) {
2155 if(DirObject1)
2156 DirObject1->Flags |= FO_FILE_MODIFIED;
2157 if(DirObject2) {
2158 DirObject2->Flags |= FO_FILE_MODIFIED;
2159 if(!Replace)
2160 DirObject2->Flags |= FO_FILE_SIZE_CHANGED;
2161 }
2162 }
2163 // report changes
2164 if(SingleDir && !Replace) {
2168/* UDFNotifyFullReportChange( Vcb, File2,
2169 UDFIsADirectory(File2) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2170 FILE_ACTION_RENAMED_NEW_NAME );*/
2171 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2172 (PSTRING)&LocalPath,
2173 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ? 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2174 NULL,NULL,
2177 NULL);
2178 } else {
2182 if(Replace) {
2183/* UDFNotifyFullReportChange( Vcb, File2,
2184 FILE_NOTIFY_CHANGE_ATTRIBUTES |
2185 FILE_NOTIFY_CHANGE_SIZE |
2186 FILE_NOTIFY_CHANGE_LAST_WRITE |
2187 FILE_NOTIFY_CHANGE_LAST_ACCESS |
2188 FILE_NOTIFY_CHANGE_CREATION |
2189 FILE_NOTIFY_CHANGE_EA,
2190 FILE_ACTION_MODIFIED );*/
2191 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2192 (PSTRING)&LocalPath,
2193 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2194 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2195 NULL,NULL,
2203 NULL);
2204 } else {
2205/* UDFNotifyFullReportChange( Vcb, File2,
2206 UDFIsADirectory(File2) ? FILE_NOTIFY_CHANGE_DIR_NAME : FILE_NOTIFY_CHANGE_FILE_NAME,
2207 FILE_ACTION_ADDED );*/
2208 FsRtlNotifyFullReportChange( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
2209 (PSTRING)&LocalPath,
2210 ((Dir2->Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY) ?
2211 0 : Dir2->Fcb->FCBName->ObjectName.Length) + sizeof(WCHAR),
2212 NULL,NULL,
2213 UDFIsADirectory(File1) ?
2217 NULL);
2218 }
2219 }
2220
2221 // this will prevent structutre release before call to
2222 // UDFCleanUpFcbChain()
2223 UDFInterlockedIncrement((PLONG)&(Dir1->Fcb->ReferenceCount));
2224 UDFInterlockedIncrement((PLONG)&(Dir1->Fcb->NTRequiredFCB->CommonRefCount));
2225 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2226
2227 // Look through Ccb list & decrement OpenHandleCounter(s)
2228 // acquire CcbList
2229 if(!SingleDir) {
2230 UDFAcquireResourceExclusive(&(Fcb1->CcbListResource),TRUE);
2231 Link = Fcb1->NextCCB.Flink;
2232 DirRefCount = 0;
2233 FileInfoRefCount = 0;
2234 ASSERT(Link != &(Fcb1->NextCCB));
2235 while (Link != &(Fcb1->NextCCB)) {
2236 NextFileInfo = Dir1;
2237 CurCcb = CONTAINING_RECORD(Link, UDFCCB, NextCCB);
2238 ASSERT(CurCcb->TreeLength);
2239 i = (CurCcb->TreeLength) ? (CurCcb->TreeLength - 1) : 0;
2240 Link = Link->Flink;
2241 UseClose = (CurCcb->CCBFlags & UDF_CCB_CLEANED) ? FALSE : TRUE;
2242
2243 AdPrint((" Ccb:%x:%s:i:%x\n", CurCcb, UseClose ? "Close" : "",i));
2244 // cleanup old parent chain
2245 for(; i && NextFileInfo; i--) {
2246 // remember parent file now
2247 // it will prevent us from data losses
2248 // due to eventual structure release
2249 fi = NextFileInfo->ParentFile;
2250 if(UseClose) {
2251 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount >= NextFileInfo->RefCount);
2252 UDFCloseFile__(Vcb, NextFileInfo);
2253 }
2254 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount > NextFileInfo->RefCount);
2255 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount);
2256 ASSERT_REF(NextFileInfo->Fcb->NTRequiredFCB->CommonRefCount);
2257 UDFInterlockedDecrement((PLONG)&(NextFileInfo->Fcb->ReferenceCount));
2258 UDFInterlockedDecrement((PLONG)&(NextFileInfo->Fcb->NTRequiredFCB->CommonRefCount));
2259 ASSERT_REF(NextFileInfo->Fcb->ReferenceCount >= NextFileInfo->RefCount);
2260 NextFileInfo = fi;
2261 }
2262
2263 if(CurCcb->TreeLength > 1) {
2264 DirRefCount++;
2265 if(UseClose)
2266 FileInfoRefCount++;
2267 CurCcb->TreeLength = 2;
2268#ifdef UDF_DBG
2269 } else {
2270 BrutePoint();
2271#endif // UDF_DBG
2272 }
2273 }
2274 UDFReleaseResource(&(Fcb1->CcbListResource));
2275
2276 ASSERT_REF(DirRefCount >= FileInfoRefCount);
2277 // update counters & pointers
2278 Fcb1->ParentFcb = Dir2->Fcb;
2279 // move references to Dir2
2280 UDFInterlockedExchangeAdd((PLONG)&(Dir2->Fcb->ReferenceCount), DirRefCount);
2281 UDFInterlockedExchangeAdd((PLONG)&(Dir2->Fcb->NTRequiredFCB->CommonRefCount), DirRefCount);
2282 ASSERT_REF(Dir2->Fcb->ReferenceCount > Dir2->RefCount);
2283 UDFReferenceFileEx__(Dir2,FileInfoRefCount);
2284 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2285 }
2286 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2287 ASSERT_REF(Dir2->RefCount);
2288
2289 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2290 // Modify name in Fcb1
2291 if(Fcb1->FCBName) {
2292 if(Fcb1->FCBName->ObjectName.Buffer) {
2293 MyFreePool__(Fcb1->FCBName->ObjectName.Buffer);
2294 }
2295 UDFReleaseObjectName(Fcb1->FCBName);
2296 }
2297 Fcb1->FCBName = UDFAllocateObjectName();
2298 if(!(Fcb1->FCBName)) {
2299insuf_res:
2300 BrutePoint();
2301 // UDFCleanUpFcbChain()...
2302 if(AcquiredFcb1) {
2303 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2304 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2305 AcquiredDir1 = FALSE;
2306 }
2307 if(AcquiredDir1) {
2308 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2309 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2310 AcquiredDir1 = FALSE;
2311 }
2312 UDFCleanUpFcbChain(Vcb, Dir1, 1, TRUE);
2314 }
2315
2316 RC = MyCloneUnicodeString(&(Fcb1->FCBName->ObjectName), &(Fcb2->FCBName->ObjectName));
2317 if(!NT_SUCCESS(RC))
2318 goto insuf_res;
2319/* RC = MyAppendUnicodeStringToString(&(Fcb1->FCBName->ObjectName), &(Fcb2->FCBName->ObjectName));
2320 if(!NT_SUCCESS(RC))
2321 goto insuf_res;*/
2322 // if Dir2 is a RootDir, we shoud not append '\\' because
2323 // uit will be the 2nd '\\' character (RootDir's name is also '\\')
2324 if(Dir2->ParentFile) {
2325 RC = MyAppendUnicodeToString(&(Fcb1->FCBName->ObjectName), L"\\");
2326 if(!NT_SUCCESS(RC))
2327 goto insuf_res;
2328 }
2329 RC = MyAppendUnicodeStringToStringTag(&(Fcb1->FCBName->ObjectName), &NewName, MEM_USREN2_TAG);
2330 if(!NT_SUCCESS(RC))
2331 goto insuf_res;
2332
2333 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2334 ASSERT_REF(Dir1->Fcb->ReferenceCount >= Dir1->RefCount);
2335 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2336
2337 RC = STATUS_SUCCESS;
2338
2339try_exit: NOTHING;
2340
2341 } _SEH2_FINALLY {
2342
2343 if(AcquiredFcb1) {
2344 UDF_CHECK_PAGING_IO_RESOURCE(Fcb1->NTRequiredFCB);
2345 UDFReleaseResource(&(Fcb1->NTRequiredFCB->MainResource));
2346 }
2347 if(AcquiredDir1) {
2348 UDF_CHECK_PAGING_IO_RESOURCE(Dir1->Fcb->NTRequiredFCB);
2349 UDFReleaseResource(&(Dir1->Fcb->NTRequiredFCB->MainResource));
2350 }
2351 // perform protected structure release
2352 if(NT_SUCCESS(RC) &&
2353 (RC != STATUS_PENDING)) {
2354 ASSERT(AcquiredVcb);
2355 UDFCleanUpFcbChain(Vcb, Dir1, 1, TRUE);
2356 ASSERT_REF(Fcb1->ReferenceCount >= File1->RefCount);
2357 ASSERT_REF(Dir2->Fcb->ReferenceCount >= Dir2->RefCount);
2358 }
2359
2360 if(AcquiredVcb) {
2361 if(AcquiredVcbEx)
2362 UDFConvertExclusiveToSharedLite(&(Vcb->VCBResource));
2363 } else {
2364 // caller assumes Vcb to be acquired shared
2365 BrutePoint();
2366 UDFAcquireResourceShared(&(Vcb->VCBResource), TRUE);
2367 }
2368
2369 if(LocalPath.Buffer) {
2370 MyFreePool__(LocalPath.Buffer);
2371 }
2372 } _SEH2_END;
2373
2374 return RC;
2375} // end UDFRename()
#define MEM_USREN2_TAG
Definition: fileinfo.cpp:24
#define MEM_USREN_TAG
Definition: fileinfo.cpp:23
struct _UDF_FILE_INFO * FileInfo
Definition: udf_rel.h:204
PtrUDFObjectName FCBName
Definition: struct.h:286
uint32 RefCount
Definition: udf_rel.h:399
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
#define UDFIsDirOpened__(fi)
Definition: udf_info.h:1071
__inline OSSTATUS UDFFindFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING Name, IN PUDF_FILE_INFO DirInfo)
Definition: udf_info.h:114
#define UDFReferenceFileEx__(fi, i)
Definition: udf_info.h:1052
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define UDFInterlockedExchangeAdd(addr, i)
Definition: udffs.h:257
#define FILE_ACTION_RENAMED_OLD_NAME
#define FILE_ACTION_RENAMED_NEW_NAME

Referenced by UDFCommonFileInfo().

◆ UDFScanForDismountedVcb()

VOID UDFScanForDismountedVcb ( IN PtrUDFIrpContext  IrpContext)

Definition at line 1510 of file fscntrl.cpp.

1513{
1514 PVCB Vcb;
1516
1517
1518 // Walk through all of the Vcb's attached to the global data.
1519 Link = UDFGlobalData.VCBQueue.Flink;
1520
1521 while (Link != &(UDFGlobalData.VCBQueue)) {
1522
1523 Vcb = CONTAINING_RECORD( Link, VCB, NextVCB );
1524
1525 // Move to the next link now since the current Vcb may be deleted.
1526 Link = Link->Flink;
1527
1528 // If dismount is already underway then check if this Vcb can
1529 // go away.
1530 if((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) ||
1531 ((!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) && (Vcb->VCBOpenCount <= UDF_RESIDUAL_REFERENCE))) {
1532
1533 UDFCheckForDismount( IrpContext, Vcb, FALSE );
1534 }
1535 }
1536
1537 return;
1538} // end UDFScanForDismountedVcb()

Referenced by UDFInvalidateVolumes(), and UDFMountVolume().

◆ UDFSetAccessRights()

NTSTATUS UDFSetAccessRights ( PFILE_OBJECT  FileObject,
PACCESS_STATE  AccessState,
PtrUDFFCB  Fcb,
PtrUDFCCB  Ccb,
ACCESS_MASK  DesiredAccess,
USHORT  ShareAccess 
)

Definition at line 1049 of file secursup.cpp.

1057{
1058#ifndef UDF_ENABLE_SECURITY
1059 ASSERT(Ccb);
1060 ASSERT(Fcb->FileInfo);
1061
1063
1064#else //UDF_ENABLE_SECURITY
1065
1066 NTSTATUS RC;
1067 // Set Security on Object
1068 PSECURITY_DESCRIPTOR SecDesc;
1070 BOOLEAN AutoInherit;
1071
1072 ASSERT(Ccb);
1073 ASSERT(Fcb->FileInfo);
1074
1075 SecDesc = UDFLookUpAcl(Fcb->Vcb, FileObject, Fcb);
1076 AutoInherit = UDFIsAStreamDir(Fcb->FileInfo) || UDFIsAStream(Fcb->FileInfo);
1077
1078 if(SecDesc && !AutoInherit) {
1079 // Get caller's User/Primary Group info
1081 RC = SeAssignSecurity(
1082 Fcb->FileInfo->ParentFile->Dloc->CommonFcb->SecurityDesc,
1083// NULL,
1084 AccessState->SecurityDescriptor,
1085 &(Fcb->NTRequiredFCB->SecurityDesc),
1086 UDFIsADirectory(Fcb->FileInfo),
1089 NonPagedPool);
1091 UDFConvertToSelfRelative(&(Fcb->NTRequiredFCB->SecurityDesc));
1092
1093 if(!NT_SUCCESS(RC)) {
1094Clean_Up_SD:
1095 UDFDeassignAcl(Fcb->NTRequiredFCB, AutoInherit);
1096 return RC;
1097 }
1098 }
1099
1101 if(!NT_SUCCESS(RC))
1102 goto Clean_Up_SD;
1103 return RC;
1104
1105#endif //UDF_ENABLE_SECURITY
1106
1107} // end UDFSetAccessRights()
VOID UDFDeassignAcl(IN PtrUDFNTRequiredFCB NtReqFcb, IN BOOLEAN AutoInherited)
Definition: secursup.cpp:772
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417

Referenced by UDFCommonCreate().

◆ UDFSetAllocationInformation()

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 at line 1454 of file fileinfo.cpp.

1463{
1465 BOOLEAN TruncatedFile = FALSE;
1466 BOOLEAN ModifiedAllocSize = FALSE;
1467 BOOLEAN CacheMapInitialized = FALSE;
1468 BOOLEAN AcquiredPagingIo = FALSE;
1469
1470 AdPrint(("UDFSetAllocationInformation\n"));
1471
1472 _SEH2_TRY {
1473 // Increasing the allocation size associated with a file stream
1474 // is relatively easy. All we have to do is execute some FSD
1475 // specific code to check whether we have enough space available
1476 // (and if the FSD supports user/volume quotas, whether the user
1477 // is not exceeding quota), and then increase the file size in the
1478 // corresponding on-disk and in-memory structures.
1479 // Then, all we should do is inform the Cache Manager about the
1480 // increased allocation size.
1481
1482 // First, do whatever error checking is appropriate here (e.g. whether
1483 // the caller is trying the change size for a directory, etc.).
1484 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1486
1487 Fcb->NTRequiredFCB->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
1488
1489 if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
1490 (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
1491 !FlagOn(Irp->Flags, IRP_PAGING_IO)) {
1493 // Now initialize the cache map.
1494 MmPrint((" CcInitializeCacheMap()\n"));
1496 (PCC_FILE_SIZES)&Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize,
1497 FALSE,
1498 &(UDFGlobalData.CacheMgrCallBacks),
1499 Fcb->NTRequiredFCB );
1500
1501 CacheMapInitialized = TRUE;
1502 }
1503
1504 // Are we increasing the allocation size?
1505 if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart <
1506 PtrBuffer->AllocationSize.QuadPart) {
1507
1508 // Yes. Do the FSD specific stuff i.e. increase reserved
1509 // space on disk.
1510 if(((LONGLONG)UDFGetFreeSpace(Vcb) << Vcb->LBlockSizeBits) < PtrBuffer->AllocationSize.QuadPart) {
1512 }
1513// RC = STATUS_SUCCESS;
1514 ModifiedAllocSize = TRUE;
1515
1516 } else if(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize.QuadPart >
1517 PtrBuffer->AllocationSize.QuadPart) {
1518 // This is the painful part. See if the VMM will allow us to proceed.
1519 // The VMM will deny the request if:
1520 // (a) any image section exists OR
1521 // (b) a data section exists and the size of the user mapped view
1522 // is greater than the new size
1523 // Otherwise, the VMM should allow the request to proceed.
1524 MmPrint((" MmCanFileBeTruncated()\n"));
1525 if(!MmCanFileBeTruncated(&(Fcb->NTRequiredFCB->SectionObject), &(PtrBuffer->AllocationSize))) {
1526 // VMM said no way!
1528 }
1529
1530 // Perform our directory entry modifications. Release any on-disk
1531 // space we may need to in the process.
1532 ModifiedAllocSize = TRUE;
1533 TruncatedFile = TRUE;
1534 }
1535
1536 ASSERT(NT_SUCCESS(RC));
1537 // This is a good place to check if we have performed a truncate
1538 // operation. If we have perform a truncate (whether we extended
1539 // or reduced file size or even leave it intact), we should update
1540 // file time stamps.
1541 FileObject->Flags |= FO_FILE_MODIFIED;
1542
1543 // Last, but not the lease, we must inform the Cache Manager of file size changes.
1544 if(ModifiedAllocSize) {
1545
1546 // If we decreased the allocation size to less than the
1547 // current file size, modify the file size value.
1548 // Similarly, if we decreased the value to less than the
1549 // current valid data length, modify that value as well.
1550
1551 AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&(Fcb->NTRequiredFCB->PagingIoResource));
1552 // Update the FCB Header with the new allocation size.
1553 if(TruncatedFile) {
1554 if(Fcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength.QuadPart >
1555 PtrBuffer->AllocationSize.QuadPart) {
1556 // Decrease the valid data length value.
1557 Fcb->NTRequiredFCB->CommonFCBHeader.ValidDataLength =
1558 PtrBuffer->AllocationSize;
1559 }
1560 if(Fcb->NTRequiredFCB->CommonFCBHeader.FileSize.QuadPart >
1561 PtrBuffer->AllocationSize.QuadPart) {
1562 // Decrease the file size value.
1563 Fcb->NTRequiredFCB->CommonFCBHeader.FileSize =
1564 PtrBuffer->AllocationSize;
1565 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->AllocationSize.QuadPart);
1566// UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, NULL);
1567 }
1568 } else {
1569 Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize = PtrBuffer->AllocationSize;
1570// UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo,
1571// &(PtrBuffer->AllocationSize.QuadPart));
1572 }
1573 if(AcquiredPagingIo) {
1574 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1575 AcquiredPagingIo = FALSE;
1576 }
1577 // If the FCB has not had caching initiated, it is still valid
1578 // for us to invoke the NT Cache Manager. It is possible in such
1579 // situations for the call to be no'oped (unless some user has
1580 // mapped in the file)
1581
1582 // NOTE: The invocation to CcSetFileSizes() will quite possibly
1583 // result in a recursive call back into the file system.
1584 // This is because the NT Cache Manager will typically
1585 // perform a flush before telling the VMM to purge pages
1586 // especially when caching has not been initiated on the
1587 // file stream, but the user has mapped the file into
1588 // the process' virtual address space.
1589 MmPrint((" CcSetFileSizes()\n"));
1590 Fcb->NTRequiredFCB->AcqFlushCount++;
1591 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize));
1592 Fcb->NTRequiredFCB->AcqFlushCount--;
1593 Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1594
1595 // Inform any pending IRPs (notify change directory).
1596 if(UDFIsAStream(Fcb->FileInfo)) {
1597 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1600 } else {
1601 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1604 }
1605 }
1606
1607try_exit: NOTHING;
1608
1609 } _SEH2_FINALLY {
1610 if(AcquiredPagingIo) {
1611 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1612 AcquiredPagingIo = FALSE;
1613 }
1614 if (CacheMapInitialized) {
1615
1616 MmPrint((" CcUninitializeCacheMap()\n"));
1618 }
1619 } _SEH2_END;
1620 return(RC);
1621} // end UDFSetAllocationInformation()
int64 __fastcall UDFGetFreeSpace(IN PVCB Vcb)
Definition: alloc.cpp:1105
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:711
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4255
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155

Referenced by UDFCommonFileInfo().

◆ UDFSetBasicInformation()

NTSTATUS UDFSetBasicInformation ( IN PtrUDFFCB  Fcb,
IN PtrUDFCCB  Ccb,
IN PFILE_OBJECT  FileObject,
IN PFILE_BASIC_INFORMATION  PtrBuffer 
)

Definition at line 1013 of file fileinfo.cpp.

1018{
1020 ULONG NotifyFilter = 0;
1021
1022 AdPrint(("UDFSetBasicInformation\n"));
1023
1024 _SEH2_TRY {
1025
1026 // Obtain a pointer to the directory entry associated with
1027 // the FCB being modifed. The directory entry is obviously
1028 // part of the data associated with the parent directory that
1029 // contains this particular file stream.
1030 if(PtrBuffer->FileAttributes) {
1031 UDFUpdateAttrTime(Fcb->Vcb, Fcb->FileInfo);
1032 } else
1033 if( UDFIsADirectory(Fcb->FileInfo) &&
1034 !(Fcb->Vcb->CompatFlags & UDF_VCB_IC_UPDATE_UCHG_DIR_ACCESS_TIME) &&
1035 ((Fcb->FileInfo->Dloc->DataLoc.Modified ||
1036 Fcb->FileInfo->Dloc->AllocLoc.Modified ||
1037 (Fcb->FileInfo->Dloc->FE_Flags & UDF_FE_FLAG_FE_MODIFIED) ||
1038 Fcb->FileInfo->Dloc->FELoc.Modified))
1039 ) {
1040 // ignore Access Time Modification for unchanged Dir
1041 if(!PtrBuffer->CreationTime.QuadPart &&
1042 PtrBuffer->LastAccessTime.QuadPart &&
1043 !PtrBuffer->ChangeTime.QuadPart &&
1044 !PtrBuffer->LastWriteTime.QuadPart)
1045 try_return(RC);
1046 }
1047
1048 UDFSetFileXTime(Fcb->FileInfo,
1049 &(PtrBuffer->CreationTime.QuadPart),
1050 &(PtrBuffer->LastAccessTime.QuadPart),
1051 &(PtrBuffer->ChangeTime.QuadPart),
1052 &(PtrBuffer->LastWriteTime.QuadPart) );
1053
1054 if(PtrBuffer->CreationTime.QuadPart) {
1055 // The interesting thing here is that the user has set certain time
1056 // fields. However, before doing this, the user may have performed
1057 // I/O which in turn would have caused FSD to mark the fact that
1058 // write/access time should be modifed at cleanup.
1059 // We'll mark the fact that such updates are no longer
1060 // required since the user has explicitly specified the values he
1061 // wishes to see associated with the file stream.
1062 Fcb->NTRequiredFCB->CreationTime = PtrBuffer->CreationTime;
1063 Ccb->CCBFlags |= UDF_CCB_CREATE_TIME_SET;
1065 }
1066 if(PtrBuffer->LastAccessTime.QuadPart) {
1067 Fcb->NTRequiredFCB->LastAccessTime = PtrBuffer->LastAccessTime;
1068 Ccb->CCBFlags |= UDF_CCB_ACCESS_TIME_SET;
1070 }
1071 if(PtrBuffer->ChangeTime.QuadPart) {
1072 Fcb->NTRequiredFCB->ChangeTime = PtrBuffer->ChangeTime;
1073 Ccb->CCBFlags |= UDF_CCB_MODIFY_TIME_SET;
1074 }
1075 if(PtrBuffer->LastWriteTime.QuadPart) {
1076 Fcb->NTRequiredFCB->LastWriteTime = PtrBuffer->LastWriteTime;
1077 Ccb->CCBFlags |= UDF_CCB_WRITE_TIME_SET;
1079 }
1080
1081 // Now come the attributes.
1082 if(PtrBuffer->FileAttributes) {
1083 // We have a non-zero attribute value.
1084 // The presence of a particular attribute indicates that the
1085 // user wishes to set the attribute value. The absence indicates
1086 // the user wishes to clear the particular attribute.
1087
1088 // Our routine ignores unsupported flags
1089 PtrBuffer->FileAttributes &= ~(FILE_ATTRIBUTE_NORMAL);
1090
1091 // Similarly, we should pick out other invalid flag values.
1092 if( (PtrBuffer->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
1093 !(Fcb->FCBFlags & UDF_FCB_DIRECTORY))
1095
1096 if(PtrBuffer->FileAttributes & FILE_ATTRIBUTE_TEMPORARY) {
1097 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1099 FileObject->Flags |= FO_TEMPORARY_FILE;
1100 } else {
1101 FileObject->Flags &= ~FO_TEMPORARY_FILE;
1102 }
1103
1104 if(PtrBuffer->FileAttributes & FILE_ATTRIBUTE_READONLY) {
1105 Fcb->FCBFlags |= UDF_FCB_READ_ONLY;
1106 } else {
1107 Fcb->FCBFlags &= ~UDF_FCB_READ_ONLY;
1108 }
1109
1110 UDFAttributesToUDF(UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index),
1111 NULL, PtrBuffer->FileAttributes);
1112
1113 (UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index))
1114 ->FI_Flags |= UDF_FI_FLAG_SYS_ATTR;
1115 // If the FSD supports file compression, we may wish to
1116 // note the user's preferences for compressing/not compressing
1117 // the file at this time.
1118 Ccb->CCBFlags |= UDF_CCB_ATTRIBUTES_SET;
1120 }
1121
1122 if(NotifyFilter) {
1123 UDFNotifyFullReportChange( Fcb->Vcb, Fcb->FileInfo,
1125 UDFSetFileSizeInDirNdx(Fcb->Vcb, Fcb->FileInfo, NULL);
1126 Fcb->FileInfo->Dloc->FE_Flags |= UDF_FE_FLAG_FE_MODIFIED;
1127 }
1128
1129try_exit: NOTHING;
1130 } _SEH2_FINALLY {
1131 ;
1132 } _SEH2_END;
1133 return(RC);
1134} // end UDFSetBasicInformation()
#define UDF_FE_FLAG_FE_MODIFIED
Was modified & should be flushed.
Definition: udf_rel.h:323
#define UDF_FI_FLAG_SYS_ATTR
Given entry of file list contains valid file attributes & times in NT-specific format.
Definition: udf_rel.h:219
_In_opt_ HANDLE _In_opt_ PIO_APC_ROUTINE _In_opt_ PVOID _Out_ PIO_STATUS_BLOCK _In_ ULONG NotifyFilter
Definition: zwfuncs.h:504

Referenced by UDFCommonFileInfo().

◆ UDFSetDispositionInformation()

NTSTATUS UDFSetDispositionInformation ( IN PtrUDFFCB  Fcb,
IN PtrUDFCCB  Ccb,
IN PVCB  Vcb,
IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Delete 
)

Definition at line 1340 of file fileinfo.cpp.

1347{
1349// PUDF_FILE_INFO SDirInfo = NULL;
1350// PUDF_FILE_INFO FileInfo = NULL;
1351 ULONG lc;
1352
1353 AdPrint(("UDFSetDispositionInformation\n"));
1354
1355 _SEH2_TRY {
1356
1357 if(!Delete) {
1358 AdPrint((" CLEAR DeleteOnClose\n"));
1359 // "un-delete" the file.
1360 Fcb->FCBFlags &= ~UDF_FCB_DELETE_ON_CLOSE;
1361 if(FileObject)
1362 FileObject->DeletePending = FALSE;
1363 RC = UDFMarkStreamsForDeletion(Vcb, Fcb, FALSE); // Undelete
1364 try_return(RC);
1365 }
1366 AdPrint((" SET DeleteOnClose\n"));
1367
1368 // The easy part is over. Now, we know that the user wishes to
1369 // delete the corresponding directory entry (of course, if this
1370 // is the only link to the file stream, any on-disk storage space
1371 // associated with the file stream will also be released when the
1372 // (only) link is deleted!)
1373
1374 // Do some checking to see if the file can even be deleted.
1375 if(Fcb->FCBFlags & UDF_FCB_DELETE_ON_CLOSE) {
1376 // All done!
1377 try_return(RC);
1378 }
1379
1380 if(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_READ_ONLY) {
1382 }
1383
1384 if(Fcb->FCBFlags & UDF_FCB_READ_ONLY) {
1386 if(!NT_SUCCESS(RC)) {
1388 }
1389 }
1390
1391 // It would not be prudent to allow deletion of either a root
1392 // directory or a directory that is not empty.
1393 if(Fcb->FCBFlags & UDF_FCB_ROOT_DIRECTORY)
1395
1396 lc = UDFGetFileLinkCount(Fcb->FileInfo);
1397
1398 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY) {
1399 // Perform check to determine whether the directory
1400 // is empty or not.
1401 if(!UDFIsDirEmpty__(Fcb->FileInfo)) {
1403 }
1404
1405 } else {
1406 // An important step is to check if the file stream has been
1407 // mapped by any process. The delete cannot be allowed to proceed
1408 // in this case.
1409 MmPrint((" MmFlushImageSection()\n"));
1410 Fcb->NTRequiredFCB->AcqFlushCount++;
1411 if(!MmFlushImageSection(&(Fcb->NTRequiredFCB->SectionObject),
1412 (lc > 1) ? MmFlushForWrite : MmFlushForDelete)) {
1413 Fcb->NTRequiredFCB->AcqFlushCount--;
1415 }
1416 Fcb->NTRequiredFCB->AcqFlushCount--;
1417 }
1418 // We should also mark Streams for deletion if there are no
1419 // Links to the file. Otherwise we'll delete only the file
1420
1421 if(lc > 1) {
1422 RC = STATUS_SUCCESS;
1423 } else {
1424 RC = UDFMarkStreamsForDeletion(Vcb, Fcb, TRUE); // Delete
1425 if(!NT_SUCCESS(RC))
1426 try_return(RC);
1427 }
1428
1429 // Set a flag to indicate that this directory entry will become history
1430 // at cleanup.
1431 Fcb->FCBFlags |= UDF_FCB_DELETE_ON_CLOSE;
1432 if(FileObject)
1433 FileObject->DeletePending = TRUE;
1434
1435 if((Fcb->FCBFlags & UDF_FCB_DIRECTORY) && Ccb) {
1436 FsRtlNotifyFullChangeDirectory( Vcb->NotifyIRPMutex, &(Vcb->NextNotifyIRP),
1437 (PVOID)Ccb, NULL, FALSE, FALSE,
1438 0, NULL, NULL, NULL );
1439 }
1440
1441try_exit: NOTHING;
1442
1443 } _SEH2_FINALLY {
1444 ;
1445 } _SEH2_END;
1446 return(RC);
1447} // end UDFSetDispositionInformation()
NTSTATUS UDFCheckAccessRights(PFILE_OBJECT FileObject, PACCESS_STATE AccessState, PtrUDFFCB Fcb, PtrUDFCCB Ccb, ACCESS_MASK DesiredAccess, USHORT ShareAccess)
Definition: secursup.cpp:927
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167

Referenced by UDFCommonFileInfo().

◆ UDFSetEOF()

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 at line 1627 of file fileinfo.cpp.

1636{
1638 BOOLEAN TruncatedFile = FALSE;
1639 BOOLEAN ModifiedAllocSize = FALSE;
1640 ULONG Attr;
1641 PDIR_INDEX_ITEM DirNdx;
1643 LONGLONG OldFileSize;
1644// BOOLEAN ZeroBlock;
1645 BOOLEAN CacheMapInitialized = FALSE;
1646 BOOLEAN AcquiredPagingIo = FALSE;
1647
1648 AdPrint(("UDFSetEOF\n"));
1649
1650 _SEH2_TRY {
1651 // Increasing the allocation size associated with a file stream
1652 // is relatively easy. All we have to do is execute some FSD
1653 // specific code to check whether we have enough space available
1654 // (and if the FSD supports user/volume quotas, whether the user
1655 // is not exceeding quota), and then increase the file size in the
1656 // corresponding on-disk and in-memory structures.
1657 // Then, all we should do is inform the Cache Manager about the
1658 // increased allocation size.
1659
1660 // First, do whatever error checking is appropriate here (e.g. whether
1661 // the caller is trying the change size for a directory, etc.).
1662 if(Fcb->FCBFlags & UDF_FCB_DIRECTORY)
1664
1665 NtReqFcb = Fcb->NTRequiredFCB;
1666
1667 if((Fcb->FCBFlags & UDF_FCB_DELETED) ||
1668 (NtReqFcb->NtReqFCBFlags & UDF_NTREQ_FCB_DELETED)) {
1669#ifdef UDF_DBG
1670 if(UDFGetFileLinkCount(Fcb->FileInfo) < 1) {
1671 BrutePoint();
1673 } else
1674#endif // UDF_DBG
1676 }
1677
1678 NtReqFcb->CommonFCBHeader.IsFastIoPossible = UDFIsFastIoPossible(Fcb);
1679
1680 if ((FileObject->SectionObjectPointer->DataSectionObject != NULL) &&
1681 (FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
1682 !(Irp->Flags & IRP_PAGING_IO)) {
1684 // Now initialize the cache map.
1685 MmPrint((" CcInitializeCacheMap()\n"));
1687 (PCC_FILE_SIZES)&Fcb->NTRequiredFCB->CommonFCBHeader.AllocationSize,
1688 FALSE,
1689 &(UDFGlobalData.CacheMgrCallBacks),
1690 Fcb->NTRequiredFCB );
1691
1692 CacheMapInitialized = TRUE;
1693 }
1694
1695 AcquiredPagingIo = UDFAcquireResourceExclusiveWithCheck(&(Fcb->NTRequiredFCB->PagingIoResource));
1696 // Do a special case here for the lazy write of file sizes.
1697 if(PtrSp->Parameters.SetFile.AdvanceOnly) {
1698 // Never have the dirent filesize larger than the fcb filesize
1699 PtrBuffer->EndOfFile.QuadPart =
1700 min(PtrBuffer->EndOfFile.QuadPart,
1701 NtReqFcb->CommonFCBHeader.FileSize.QuadPart);
1702 // Only advance the file size, never reduce it with this call
1703 RC = STATUS_SUCCESS;
1704 if(UDFGetFileSizeFromDirNdx(Vcb, Fcb->FileInfo) >=
1705 PtrBuffer->EndOfFile.QuadPart)
1706 try_return(RC);
1707
1708 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, &(PtrBuffer->EndOfFile.QuadPart));
1709 goto notify_size_changes;
1710 }
1711
1712 // !!! IMPORTANT !!!
1713
1714 // We can get here after all Handles to the file are closed
1715 // To prevent allocation size incoherency we should
1716 // reference FileInfo _before_ call to UDFResizeFile__()
1717 // and use UDFCloseFile__() _after_ that
1718
1719 // Are we increasing the allocation size?
1720 OldFileSize = NtReqFcb->CommonFCBHeader.FileSize.QuadPart;
1721 if(OldFileSize < PtrBuffer->EndOfFile.QuadPart) {
1722
1723 // Yes. Do the FSD specific stuff i.e. increase reserved
1724 // space on disk.
1725/*
1726 if (FileObject->PrivateCacheMap)
1727 ZeroBlock = TRUE;
1728*/
1729
1730 // reference file to pretend that it is opened
1731 UDFReferenceFile__(Fcb->FileInfo);
1732 UDFInterlockedIncrement((PLONG)&(Fcb->ReferenceCount));
1733 UDFInterlockedIncrement((PLONG)&(NtReqFcb->CommonRefCount));
1734 // perform resize operation
1735 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart);
1736 // dereference file
1737 UDFCloseFile__(Vcb, Fcb->FileInfo);
1738 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
1739 UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
1740 // update values in NtReqFcb
1741 NtReqFcb->CommonFCBHeader.FileSize.QuadPart =
1742// NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart =
1743 PtrBuffer->EndOfFile.QuadPart;
1744 ModifiedAllocSize = TRUE;
1745
1746 } else if(NtReqFcb->CommonFCBHeader.FileSize.QuadPart >
1747 PtrBuffer->EndOfFile.QuadPart) {
1748
1749 // This is the painful part. See if the VMM will allow us to proceed.
1750 // The VMM will deny the request if:
1751 // (a) any image section exists OR
1752 // (b) a data section exists and the size of the user mapped view
1753 // is greater than the new size
1754 // Otherwise, the VMM should allow the request to proceed.
1755
1756 MmPrint((" MmCanFileBeTruncated()\n"));
1757 if(!MmCanFileBeTruncated(&(NtReqFcb->SectionObject), &(PtrBuffer->EndOfFile))) {
1758 // VMM said no way!
1760 }
1761
1762 // Perform directory entry modifications. Release any on-disk
1763 // space we may need to in the process.
1764 UDFReferenceFile__(Fcb->FileInfo);
1765 UDFInterlockedIncrement((PLONG)&(Fcb->ReferenceCount));
1766 UDFInterlockedIncrement((PLONG)&(NtReqFcb->CommonRefCount));
1767 // perform resize operation
1768 RC = UDFResizeFile__(Vcb, Fcb->FileInfo, PtrBuffer->EndOfFile.QuadPart);
1769 // dereference file
1770 UDFCloseFile__(Vcb, Fcb->FileInfo);
1771 UDFInterlockedDecrement((PLONG)&(Fcb->ReferenceCount));
1772 UDFInterlockedDecrement((PLONG)&(NtReqFcb->CommonRefCount));
1773
1774 ModifiedAllocSize = TRUE;
1775 TruncatedFile = TRUE;
1776 }
1777
1778 // This is a good place to check if we have performed a truncate
1779 // operation. If we have perform a truncate (whether we extended
1780 // or reduced file size), we should update file time stamps.
1781
1782 // Last, but not the least, we must inform the Cache Manager of file size changes.
1783 if(ModifiedAllocSize && NT_SUCCESS(RC)) {
1784 // If we decreased the allocation size to less than the
1785 // current file size, modify the file size value.
1786 // Similarly, if we decreased the value to less than the
1787 // current valid data length, modify that value as well.
1788 if(TruncatedFile) {
1789 if(NtReqFcb->CommonFCBHeader.ValidDataLength.QuadPart >
1790 PtrBuffer->EndOfFile.QuadPart) {
1791 // Decrease the valid data length value.
1792 NtReqFcb->CommonFCBHeader.ValidDataLength =
1793 PtrBuffer->EndOfFile;
1794 }
1795 if(NtReqFcb->CommonFCBHeader.FileSize.QuadPart >
1796 PtrBuffer->EndOfFile.QuadPart) {
1797 // Decrease the file size value.
1798 NtReqFcb->CommonFCBHeader.FileSize =
1799 PtrBuffer->EndOfFile;
1800 }
1801 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, NULL);
1802 } else {
1803 // Update the FCB Header with the new allocation size.
1804 // NT expects AllocationSize to be decreased on Close only
1805 NtReqFcb->CommonFCBHeader.AllocationSize.QuadPart =
1806 PtrBuffer->EndOfFile.QuadPart;
1807// UDFSysGetAllocSize(Vcb, UDFGetFileSize(Fcb->FileInfo));
1808 UDFSetFileSizeInDirNdx(Vcb, Fcb->FileInfo, &(PtrBuffer->EndOfFile.QuadPart));
1809 }
1810
1811 FileObject->Flags |= FO_FILE_MODIFIED;
1812// UDFGetFileAllocationSize(Vcb, Fcb->FileInfo);
1813
1814 // If the FCB has not had caching initiated, it is still valid
1815 // for us to invoke the NT Cache Manager. It is possible in such
1816 // situations for the call to be no'oped (unless some user has
1817 // mapped in the file)
1818
1819 // Archive bit
1820 if(Vcb->CompatFlags & UDF_VCB_IC_UPDATE_ARCH_BIT) {
1821 DirNdx = UDFDirIndex(UDFGetDirIndexByFileInfo(Fcb->FileInfo), Fcb->FileInfo->Index);
1822 Ccb->CCBFlags &= ~UDF_CCB_ATTRIBUTES_SET;
1823 Attr = UDFAttributesToNT(DirNdx, Fcb->FileInfo->Dloc->FileEntry);
1824 if(!(Attr & FILE_ATTRIBUTE_ARCHIVE))
1825 UDFAttributesToUDF(DirNdx, Fcb->FileInfo->Dloc->FileEntry, Attr | FILE_ATTRIBUTE_ARCHIVE);
1826 }
1827
1828 // NOTE: The invocation to CcSetFileSizes() will quite possibly
1829 // result in a recursive call back into the file system.
1830 // This is because the NT Cache Manager will typically
1831 // perform a flush before telling the VMM to purge pages
1832 // especially when caching has not been initiated on the
1833 // file stream, but the user has mapped the file into
1834 // the process' virtual address space.
1835 MmPrint((" CcSetFileSizes(), thrd:%8.8x\n",PsGetCurrentThread()));
1836 Fcb->NTRequiredFCB->AcqFlushCount++;
1837 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&(NtReqFcb->CommonFCBHeader.AllocationSize));
1838 Fcb->NTRequiredFCB->AcqFlushCount--;
1839/* if(ZeroBlock) {
1840 UDFZeroDataEx(NtReqFcb,
1841 OldFileSize,
1842 PtrBuffer->EndOfFile.QuadPart - OldFileSize,
1843 TRUE // CanWait, Vcb, FileObject);
1844 }*/
1845 Fcb->NTRequiredFCB->NtReqFCBFlags |= UDF_NTREQ_FCB_MODIFIED;
1846
1847notify_size_changes:
1848 if(AcquiredPagingIo) {
1849 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1850 AcquiredPagingIo = FALSE;
1851 }
1852
1853 // Inform any pending IRPs (notify change directory).
1854 if(UDFIsAStream(Fcb->FileInfo)) {
1855 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1858 } else {
1859 UDFNotifyFullReportChange( Vcb, Fcb->FileInfo,
1862 }
1863 }
1864
1865try_exit: NOTHING;
1866
1867 } _SEH2_FINALLY {
1868 if(AcquiredPagingIo) {
1869 UDFReleaseResource(&(Fcb->NTRequiredFCB->PagingIoResource));
1870 AcquiredPagingIo = FALSE;
1871 }
1872 if (CacheMapInitialized) {
1873
1874 MmPrint((" CcUninitializeCacheMap()\n"));
1876 }
1877 } _SEH2_END;
1878 return(RC);
1879} // end UDFSetEOF()
int64 UDFGetFileSizeFromDirNdx(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo)
Definition: udf_info.cpp:1256

Referenced by UDFCommonFileInfo().

◆ UDFSetSecurity()

NTSTATUS UDFSetSecurity ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

◆ UDFSetVolInfo()

NTSTATUS NTAPI UDFSetVolInfo ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 617 of file volinfo.cpp.

621{
623 PtrUDFIrpContext PtrIrpContext = NULL;
624 BOOLEAN AreWeTopLevel = FALSE;
625
626 UDFPrint(("UDFSetVolInfo: \n"));
627
630 ASSERT(Irp);
631
632 // set the top level context
633 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
634 ASSERT(!UDFIsFSDevObj(DeviceObject));
635
636 _SEH2_TRY {
637
638 // get an IRP context structure and issue the request
639 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
640 ASSERT(PtrIrpContext);
641
642 RC = UDFCommonSetVolInfo(PtrIrpContext, Irp);
643
645
646 RC = UDFExceptionHandler(PtrIrpContext, Irp);
647
649 } _SEH2_END;
650
651 if (AreWeTopLevel) {
653 }
654
656
657 return(RC);
658} // end UDFSetVolInfo()
NTSTATUS UDFCommonSetVolInfo(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: volinfo.cpp:666

Referenced by UDFInitializeFunctionPointers().

◆ UDFShutdown()

NTSTATUS NTAPI UDFShutdown ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 47 of file shutdown.cpp.

51{
53 PtrUDFIrpContext PtrIrpContext = NULL;
54 BOOLEAN AreWeTopLevel = FALSE;
55
56 UDFPrint(("UDFShutDown\n"));
57// BrutePoint();
58
61 ASSERT(Irp);
62
63 // set the top level context
64 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
65 //ASSERT(!UDFIsFSDevObj(DeviceObject));
66
67 _SEH2_TRY {
68
69 // get an IRP context structure and issue the request
70 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
71 if(PtrIrpContext) {
72 RC = UDFCommonShutdown(PtrIrpContext, Irp);
73 } else {
75 Irp->IoStatus.Status = RC;
76 Irp->IoStatus.Information = 0;
77 // complete the IRP
79 }
80
82
83 RC = UDFExceptionHandler(PtrIrpContext, Irp);
84
86 } _SEH2_END;
87
88 if (AreWeTopLevel) {
90 }
91
93
94 return(RC);
95} // end UDFShutdown()
NTSTATUS UDFCommonShutdown(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: shutdown.cpp:115

Referenced by UDFInitializeFunctionPointers().

◆ UDFStackOverflowRead()

VOID NTAPI UDFStackOverflowRead ( IN PVOID  Context,
IN PKEVENT  Event 
)

Definition at line 185 of file read.cpp.

189{
191 NTSTATUS RC;
192
193 UDFPrint(("UDFStackOverflowRead: \n"));
194 // Make it now look like we can wait for I/O to complete
196
197 // Do the read operation protected by a try-except clause
198 _SEH2_TRY {
199 UDFCommonRead(PtrIrpContext, PtrIrpContext->Irp);
201 RC = UDFExceptionHandler(PtrIrpContext, PtrIrpContext->Irp);
203 } _SEH2_END;
204
205 // Set the stack overflow item's event to tell the original
206 // thread that we're done.
207 KeSetEvent( Event, 0, FALSE );
208} // end UDFStackOverflowRead()
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476

Referenced by UDFPostStackOverflowRead().

◆ UDFStartEjectWaiter()

NTSTATUS UDFStartEjectWaiter ( IN PVCB  Vcb)

(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) &&

Definition at line 850 of file fscntrl.cpp.

853{
854// NTSTATUS RC;
856 UDFPrint(("UDFStartEjectWaiter:\n"));
857
858 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) {
859 UDFPrint((" UDF_VCB_FLAGS_MEDIA_READ_ONLY\n"));
860 }
861 if(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) {
862 UDFPrint((" UDF_VCB_FLAGS_MEDIA_LOCKED\n"));
863 }
864 UDFPrint((" EjectWaiter=%x\n", Vcb->EjectWaiter));
865 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY) &&
867 !(Vcb->EjectWaiter)) {
868
869 UDFPrint(("UDFStartEjectWaiter: check driver\n"));
870 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_OUR_DEVICE_DRIVER) &&
871 (Vcb->FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)) {
872 // we don't know how to write without our device driver
874 UDFPrint((" not our driver, ignore\n"));
875 return STATUS_SUCCESS;
876 }
877 UDFPrint(("UDFStartEjectWaiter: check removable\n"));
878 if(Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) {
879 // prevent media removal
880 UDFPrint(("UDFStartEjectWaiter: lock media\n"));
883 Vcb,
884 &Buff,sizeof(PREVENT_MEDIA_REMOVAL_USER_IN),
885 NULL,0,
886 FALSE,NULL );
887 Vcb->VCBFlags |= UDF_VCB_FLAGS_MEDIA_LOCKED;
888 }
889 UDFPrint(("UDFStartEjectWaiter: prepare to start\n"));
890 // initialize Eject Request waiter
892 if(!(Vcb->EjectWaiter)) return STATUS_INSUFFICIENT_RESOURCES;
893 KeInitializeEvent(&(Vcb->WaiterStopped), NotificationEvent, FALSE);
894 Vcb->EjectWaiter->Vcb = Vcb;
895 Vcb->EjectWaiter->SoftEjectReq = FALSE;
896 KeInitializeEvent(&(Vcb->EjectWaiter->StopReq), NotificationEvent, FALSE);
897// Vcb->EjectWaiter->StopReq = FALSE;
898 Vcb->EjectWaiter->WaiterStopped = &(Vcb->WaiterStopped);
899 // This can occure after unexpected media loss, when EjectRequestWaiter
900 // terminates automatically
903 ExInitializeWorkItem(&(Vcb->EjectWaiter->EjectReqWorkQueueItem), UDFEjectReqWaiter, Vcb->EjectWaiter);
904 UDFPrint(("UDFStartEjectWaiter: create thread\n"));
905 ExQueueWorkItem(&(Vcb->EjectWaiter->EjectReqWorkQueueItem), DelayedWorkQueue);
906 } else {
907 UDFPrint((" ignore\n"));
908 }
909 return STATUS_SUCCESS;
910} // end UDFStartEjectWaiter()
NTSTATUS NTAPI UDFTSendIOCTL(IN ULONG IoControlCode, IN PVCB Vcb, IN PVOID InputBuffer, IN ULONG InputBufferLength, OUT PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
Definition: env_spec.cpp:462
VOID NTAPI UDFEjectReqWaiter(IN PVOID Context)
struct _UDFEjectWaitContext * PUDFEjectWaitContext
#define UDF_VCB_FLAGS_STOP_WAITER_EVENT
Definition: udf_common.h:479
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by UDFMountVolume(), and UDFVerifyVolume().

◆ UDFStoreFileId()

NTSTATUS UDFStoreFileId ( IN PVCB  Vcb,
IN PtrUDFCCB  Ccb,
IN PUDF_FILE_INFO  fi,
IN LONGLONG  Id 
)

Definition at line 2417 of file fileinfo.cpp.

2423{
2424 LONG i;
2426
2427 if((i = UDFFindFileId(Vcb, Id)) == (-1)) {
2428 if((i = UDFFindFreeFileId(Vcb, Id)) == (-1)) return STATUS_INSUFFICIENT_RESOURCES;
2429 } else {
2430 return STATUS_SUCCESS;
2431 }
2432 Vcb->FileIdCache[i].Id = Id;
2433 Vcb->FileIdCache[i].CaseSens = (Ccb->CCBFlags & UDF_CCB_CASE_SENSETIVE) ? TRUE : FALSE;
2434 RC = MyCloneUnicodeString(&(Vcb->FileIdCache[i].FullName), &(Ccb->Fcb->FCBName->ObjectName));
2435/* if(NT_SUCCESS(RC)) {
2436 RC = MyAppendUnicodeStringToStringTag(&(Vcb->FileIdCache[i].FullName), &(Ccb->Fcb->FCBName->ObjectName), MEM_USFIDC_TAG);
2437 }*/
2438 return RC;
2439} // end UDFStoreFileId()
LONG UDFFindFreeFileId(IN PVCB Vcb, IN LONGLONG Id)
Definition: fileinfo.cpp:2393

Referenced by UDFGetInternalInformation().

◆ UDFUnlockCallersBuffer()

NTSTATUS UDFUnlockCallersBuffer ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp,
PVOID  SystemBuffer 
)

Definition at line 1034 of file read.cpp.

1039{
1041
1042 UDFPrint(("UDFUnlockCallersBuffer: \n"));
1043
1044 ASSERT(Irp);
1045
1046 _SEH2_TRY {
1047 // Is a nonPaged buffer already present in the IRP
1048 if (PtrIrpContext->IrpContextFlags & UDF_IRP_CONTEXT_BUFFER_LOCKED) {
1049
1050 UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1051 if(PtrIrpContext->TransitionBuffer) {
1052 MmPrint((" UDFUnlockCallersBuffer: free TransitionBuffer\n"));
1053 DbgFreePool(PtrIrpContext->TransitionBuffer);
1054 PtrIrpContext->TransitionBuffer = NULL;
1055 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_BUFFER_LOCKED;
1056 try_return(RC);
1057 }
1058 // Free buffer
1059 KeFlushIoBuffers( PtrIrpContext->PtrMdl, TRUE, FALSE );
1060// MmPrint((" IrpCtx->Mdl, MmUnmapLockedPages()\n"));
1061// MmUnmapLockedPages(SystemBuffer, PtrIrpContext->PtrMdl);
1062
1063 // This will be done in IoCompleteIrp !!!
1064
1065 //MmPrint((" MmUnlockPages()\n"));
1066 //MmUnlockPages(PtrIrpContext->PtrMdl);
1067
1068#ifdef UDF_DBG
1069 LockBufferCounter--;
1070#endif //UDF_DBG
1071
1072 // This will be done in IoCompleteIrp !!!
1073
1074 //IoFreeMdl(PtrIrpContext->PtrMdl);
1075
1076#ifdef UDF_DBG
1077 BuildMdlCounter--;
1078#endif //UDF_DBG
1079 UDFTouch(PtrIrpContext->PtrMdl);
1080 PtrIrpContext->PtrMdl = NULL;
1081 PtrIrpContext->IrpContextFlags &= ~UDF_IRP_CONTEXT_BUFFER_LOCKED;
1082 } else
1083 if(Irp->MdlAddress) {
1084// MmPrint((" Irp->Mdl, MmUnmapLockedPages()\n"));
1085// MmUnmapLockedPages(SystemBuffer, Irp->MdlAddress);
1086 UDFPrint((" UDF_IRP_CONTEXT_BUFFER_LOCKED MDL=%x, Irp MDL=%x\n", PtrIrpContext->PtrMdl, Irp->MdlAddress));
1087 UDFTouch(Irp->MdlAddress);
1088 KeFlushIoBuffers( Irp->MdlAddress,
1090 FALSE );
1091 } else
1092 { ; }
1093
1094try_exit: NOTHING;
1095
1096 } _SEH2_FINALLY {
1097 NOTHING;
1098 } _SEH2_END;
1099
1100 return(RC);
1101} // end UDFUnlockCallersBuffer()
#define KeFlushIoBuffers(_Mdl, _ReadOperation, _DmaOperation)
Definition: ke.h:174
_In_ UCHAR MajorFunction
Definition: wdfdevice.h:1697

Referenced by UDFCommonRead(), UDFCommonWrite(), and UDFGetVolumeBitmap().

◆ UDFUnlockVolume()

NTSTATUS UDFUnlockVolume ( IN PtrUDFIrpContext  IrpContext,
IN PIRP  Irp,
IN ULONG  PID = -1 
)

Definition at line 1859 of file fscntrl.cpp.

1864{
1866
1867 KIRQL SavedIrql;
1869
1870 PVCB Vcb;
1871 PtrUDFFCB Fcb;
1872 PtrUDFCCB Ccb;
1873
1874 UDFPrint(("UDFUnlockVolume: PID %x\n", PID));
1875
1876 // Decode the file object, the only type of opens we accept are
1877 // user volume opens.
1878 Ccb = (PtrUDFCCB)(IrpSp->FileObject->FsContext2);
1879 if(!Ccb) {
1880 UDFPrintErr((" !Ccb\n"));
1881 Irp->IoStatus.Information = 0;
1882 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1884 }
1885 Fcb = Ccb->Fcb;
1886 Vcb = Fcb->Vcb;
1887
1888 // Check for volume open
1889 if(Vcb != (PVCB)Fcb || !(Ccb->CCBFlags & UDF_CCB_VOLUME_OPEN)) {
1890 Irp->IoStatus.Information = 0;
1891 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
1893 }
1894
1895 // Acquire exclusive access to the Vcb/Vpb.
1896 IoAcquireVpbSpinLock( &SavedIrql );
1897
1898 _SEH2_TRY {
1899
1900 // We won't check for a valid Vcb for this request. An unlock will always
1901 // succeed on a locked volume.
1902 if(Vcb->Vpb->Flags & VPB_LOCKED ||
1903 Vcb->VolumeLockPID == PID) {
1904 Vcb->Vpb->Flags &= ~VPB_LOCKED;
1905 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_LOCKED;
1906 Vcb->VolumeLockFileObject = NULL;
1907 Vcb->VolumeLockPID = -1;
1909 RC = STATUS_SUCCESS;
1910 } else {
1911 RC = STATUS_NOT_LOCKED;
1912 RC = STATUS_SUCCESS;
1914 }
1915
1916 } _SEH2_FINALLY {
1917 ;
1918 } _SEH2_END;
1919
1920 // Release all of our resources
1921 IoReleaseVpbSpinLock( SavedIrql );
1922
1923 // Complete the request if there haven't been any exceptions.
1924 Irp->IoStatus.Information = 0;
1925 Irp->IoStatus.Status = RC;
1926 return RC;
1927} // end UDFUnlockVolume()

Referenced by UDFCommonDeviceControl(), and UDFUserFsCtrlRequest().

◆ UDFUserFsCtrlRequest()

NTSTATUS NTAPI UDFUserFsCtrlRequest ( PtrUDFIrpContext  PtrIrpContext,
PIRP  Irp 
)

Definition at line 178 of file fscntrl.cpp.

182{
183 NTSTATUS RC;
185
186 // Case on the control code.
187 switch ( IrpSp->Parameters.FileSystemControl.FsControlCode ) {
188
197
198 UDFPrint(("UDFUserFsCtrlRequest: OPLOCKS\n"));
200
201 Irp->IoStatus.Information = 0;
202 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
203 break;
204/*
205 RC = UDFOplockRequest( IrpContext, Irp );
206 break;
207*/
209
210 RC = UDFInvalidateVolumes( IrpContext, Irp );
211 break;
212/*
213 case FSCTL_MOVE_FILE:
214
215 case FSCTL_QUERY_ALLOCATED_RANGES:
216 case FSCTL_SET_ZERO_DATA:
217 case FSCTL_SET_SPARSE:
218
219 case FSCTL_MARK_VOLUME_DIRTY:
220
221 RC = UDFDirtyVolume( IrpContext, Irp );
222 break;
223
224 */
226
227 RC = UDFIsVolumeDirty(IrpContext, Irp);
228 break;
229
231
232 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_ALLOW_EXTENDED_DASD_IO\n"));
233 // DASD i/o is always permitted
234 // So, no-op this call
235 RC = STATUS_SUCCESS;
236
237 Irp->IoStatus.Information = 0;
238 Irp->IoStatus.Status = STATUS_SUCCESS;
239 break;
240
242
243 RC = UDFDismountVolume( IrpContext, Irp );
244 break;
245
247
248 RC = UDFIsVolumeMounted( IrpContext, Irp );
249 break;
250
252
253 RC = UDFGetStatistics( IrpContext, Irp );
254 break;
255
257
258 RC = UDFLockVolume( IrpContext, Irp );
259 break;
260
262
263 RC = UDFUnlockVolume( IrpContext, Irp );
264 break;
265
267
268 RC = UDFIsPathnameValid( IrpContext, Irp );
269 break;
270
272
273 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_GET_VOLUME_BITMAP\n"));
274 RC = UDFGetVolumeBitmap( IrpContext, Irp );
275 break;
276
278
279 UDFPrint(("UDFUserFsCtrlRequest: FSCTL_GET_RETRIEVAL_POINTERS\n"));
280 RC = UDFGetRetrievalPointers( IrpContext, Irp, 0 );
281 break;
282
283
284 // We don't support any of the known or unknown requests.
285 default:
286
287 UDFPrintErr(("UDFUserFsCtrlRequest: STATUS_INVALID_DEVICE_REQUEST for %x\n",
288 IrpSp->Parameters.FileSystemControl.FsControlCode));
290
291 Irp->IoStatus.Information = 0;
292 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
293 break;
294 }
295
297 return RC;
298
299} // end UDFUserFsCtrlRequest()
NTSTATUS UDFIsPathnameValid(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1660
NTSTATUS UDFGetStatistics(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1601
NTSTATUS UDFIsVolumeMounted(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1552
NTSTATUS UDFDismountVolume(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:1942
NTSTATUS UDFGetVolumeBitmap(IN PtrUDFIrpContext IrpContext, IN PIRP Irp)
Definition: fscntrl.cpp:2069
#define FSCTL_OPLOCK_BREAK_NOTIFY
Definition: nt_native.h:831
#define FSCTL_LOCK_VOLUME
Definition: nt_native.h:832
#define FSCTL_OPLOCK_BREAK_ACKNOWLEDGE
Definition: nt_native.h:829
#define FSCTL_REQUEST_OPLOCK_LEVEL_1
Definition: nt_native.h:826
#define FSCTL_REQUEST_FILTER_OPLOCK
Definition: nt_native.h:849
#define FSCTL_IS_PATHNAME_VALID
Definition: nt_native.h:837
#define FSCTL_UNLOCK_VOLUME
Definition: nt_native.h:833
#define FSCTL_REQUEST_BATCH_OPLOCK
Definition: nt_native.h:828
#define FSCTL_FILESYSTEM_GET_STATISTICS
Definition: nt_native.h:850
#define FSCTL_OPBATCH_ACK_CLOSE_PENDING
Definition: nt_native.h:830
#define FSCTL_OPLOCK_BREAK_ACK_NO_2
Definition: nt_native.h:846
#define FSCTL_IS_VOLUME_MOUNTED
Definition: nt_native.h:836
#define FSCTL_REQUEST_OPLOCK_LEVEL_2
Definition: nt_native.h:827
#define FSCTL_DISMOUNT_VOLUME
Definition: nt_native.h:834
#define FSCTL_GET_RETRIEVAL_POINTERS
Definition: winioctl.h:95
#define FSCTL_GET_VOLUME_BITMAP
Definition: winioctl.h:94

Referenced by UDFCommonFSControl().

◆ UDFVerifyVcb()

NTSTATUS UDFVerifyVcb ( IN PtrUDFIrpContext  IrpContext,
IN PVCB  Vcb 
)

Definition at line 37 of file verfysup.cpp.

41{
44 ULONG MediaChangeCount = 0;
45 BOOLEAN Nop = TRUE;
46 BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
47
48 UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
49 // Fail immediately if the volume is in the progress of being dismounted
50 // or has been marked invalid.
51 if (Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED) {
53 }
54
55 // If the media is removable and the verify volume flag in the
56 // device object is not set then we want to ping the device
57 // to see if it needs to be verified
58 if ( (Vcb->VCBFlags & UDF_VCB_FLAGS_REMOVABLE_MEDIA) &&
59 !(Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
60 (!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) || UnsafeIoctl) ) {
61 UDFPrint(("UDFVerifyVCB: UnsafeIoctl=%d, locked=%d\n", UnsafeIoctl, (Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) ? 0 : 1));
62 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
64 Vcb,
65 NULL,0,
66 &MediaChangeCount,sizeof(ULONG),
67 FALSE,&Iosb );
68
69 // Be safe about the count in case the driver didn't fill it in
70 if (Iosb.Information != sizeof(ULONG)) MediaChangeCount = 0;
71 UDFPrint((" MediaChangeCount %d -> %d\n", Vcb->MediaChangeCount, MediaChangeCount));
72
73 // If the volume is now an empty device, or we have receieved a
74 // bare STATUS_VERIFY_REQUIRED (various hardware conditions such
75 // as bus resets, etc., will trigger this in the drivers), or the
76 // media change count has moved since we last inspected the device,
77 // then mark the volume to be verified.
78
79 if ( (RC == STATUS_VERIFY_REQUIRED) ||
80 (UDFIsRawDevice(RC) && (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) ||
81 (NT_SUCCESS(RC) && (Vcb->MediaChangeCount != MediaChangeCount)) ||
82 UnsafeIoctl) {
83
84 UDFPrint((" set DO_VERIFY_VOLUME\n"));
85 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
86
87 // If the volume is not mounted and we got a media change count,
88 // update the Vcb so we do not trigger a verify again at this
89 // count value. If the verify->mount path detects that the media
90 // has actually changed and this Vcb is valid again, this will have
91 // done nothing. We are already synchronized since the caller has
92 // the Vcb.
93 if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED) &&
94 NT_SUCCESS(RC) ) {
95 Vcb->MediaChangeCount = MediaChangeCount;
96 }
97
98 } else if (!NT_SUCCESS(RC)) {
99// Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
100 UDFPrint((" UDFNormalizeAndRaiseStatus(%x)\n", RC));
101 UDFNormalizeAndRaiseStatus(IrpContext,RC);
102 ASSERT(Nop);
103 }
104 }
105
106 UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
107 // The Vcb may be mounted but the underlying real device may need to be verified.
108 // If it does then we'll set the Iosb in the irp to be our real device
109 if (Vcb->Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) {
110
111 UDFPrint((" DO_VERIFY_VOLUME -> IoSetHardErrorOrVerifyDevice()\n"));
112 IoSetHardErrorOrVerifyDevice( IrpContext->Irp,
113 Vcb->Vpb->RealDevice );
114
116 UDFPrint((" UDFRaiseStatus()\n"));
117 UDFRaiseStatus(IrpContext, RC);
118 ASSERT(Nop);
119 }
120
121 UDFPrint(("UDFVerifyVCB: Modified=%d\n", Vcb->Modified));
122 if (!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)) {
123 UDFPrint((" !UDF_VCB_FLAGS_VOLUME_MOUNTED -> IoSetHardErrorOrVerifyDevice()\n"));
124 Vcb->Vpb->RealDevice->Flags |= DO_VERIFY_VOLUME;
125 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice );
127 UDFPrint((" UDFRaiseStatus()\n"));
128 UDFRaiseStatus(IrpContext, RC);
129// UDFRaiseStatus(IrpContext, STATUS_UNRECOGNIZED_VOLUME);
130 ASSERT(Nop);
131 }
132 if ((Vcb->VCBFlags & UDF_VCB_FLAGS_BEING_DISMOUNTED)) {
133 UDFPrint((" UDF_VCB_FLAGS_BEING_DISMOUNTED\n"));
135 UDFRaiseStatus( IrpContext, RC );
136 ASSERT(Nop);
137 }
138 UDFPrint(("UDFVerifyVcb: RC = %x\n", RC));
139
140 return RC;
141} // end UDFVerifyVcb()
return Iosb
Definition: create.c:4402
#define STATUS_FILE_INVALID
Definition: ntstatus.h:388
#define UDFRaiseStatus(IC, S)
Definition: udffs.h:314
#define UDFIsRawDevice(RC)
Definition: udffs.h:324

Referenced by UDFCommonCreate(), UDFCommonDeviceControl(), UDFIsVolumeMounted(), and UDFLockVolume().

◆ UDFVerifyVolume()

NTSTATUS UDFVerifyVolume ( IN PIRP  Irp)

Definition at line 158 of file verfysup.cpp.

161{
163 PVPB Vpb = IrpSp->Parameters.VerifyVolume.Vpb;
164 PVCB Vcb = (PVCB)IrpSp->Parameters.VerifyVolume.DeviceObject->DeviceExtension;
165 PVCB NewVcb = NULL;
167 ULONG MediaChangeCount = 0;
168 NTSTATUS RC;
169 ULONG Mode;
170 BOOLEAN UnsafeIoctl = (Vcb->VCBFlags & UDF_VCB_FLAGS_UNSAFE_IOCTL) ? TRUE : FALSE;
171
172 // Update the real device in the IrpContext from the Vpb. There was no available
173 // file object when the IrpContext was created.
174 // IrpContext->RealDevice = Vpb->RealDevice;
175 UDFPrint(("UDFVerifyVolume:\n"));
176
177 // Acquire shared global access, the termination handler for the
178 // following try statement will free the access.
179
180 UDFAcquireResourceShared(&(UDFGlobalData.GlobalDataResource),TRUE);
181 UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
182
183 _SEH2_TRY {
184
185 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
186 // Check if the real device still needs to be verified. If it doesn't
187 // then obviously someone beat us here and already did the work
188 // so complete the verify irp with success. Otherwise reenable
189 // the real device and get to work.
190 if( !(Vpb->RealDevice->Flags & DO_VERIFY_VOLUME) &&
191 ((Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_LOCKED) && !UnsafeIoctl) ) {
192 UDFPrint(("UDFVerifyVolume: STATUS_SUCCESS (1)\n"));
194 }
195 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_UNSAFE_IOCTL;
196 // Verify that there is a disk here.
198 Vcb->TargetDeviceObject,
199 NULL,0,
200 &MediaChangeCount,sizeof(ULONG),
201 TRUE,&Iosb );
202
203 if(!NT_SUCCESS( RC )) {
204 // If we will allow a raw mount then return WRONG_VOLUME to
205 // allow the volume to be mounted by raw.
207 UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (1)\n"));
209 }
210
211 if(UDFIsRawDevice(RC)) {
212 UDFPrint(("UDFVerifyVolume: STATUS_WRONG_VOLUME (2)\n"));
214 }
215 try_return( RC );
216 }
217
218 if(Iosb.Information != sizeof(ULONG)) {
219 // Be safe about the count in case the driver didn't fill it in
220 MediaChangeCount = 0;
221 }
222
223 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
224 UDFPrint(("UDFVerifyVolume: MediaChangeCount=%x, Vcb->MediaChangeCount=%x, UnsafeIoctl=%x\n",
225 MediaChangeCount, Vcb->MediaChangeCount, UnsafeIoctl));
226 // Verify that the device actually saw a change. If the driver does not
227 // support the MCC, then we must verify the volume in any case.
228 if(MediaChangeCount == 0 ||
229 (Vcb->MediaChangeCount != MediaChangeCount) ||
230 UnsafeIoctl ) {
231
232 UDFPrint(("UDFVerifyVolume: compare\n"));
233
234 NewVcb = (PVCB)MyAllocatePool__(NonPagedPool,sizeof(VCB));
235 if(!NewVcb)
237 RtlZeroMemory(NewVcb,sizeof(VCB));
238
239 NewVcb->TargetDeviceObject = Vcb->TargetDeviceObject;
240 NewVcb->Vpb = Vpb;
241
242 // Set the removable media flag based on the real device's
243 // characteristics
244 if(Vpb->RealDevice->Characteristics & FILE_REMOVABLE_MEDIA) {
245 UDFSetFlag( NewVcb->VCBFlags, UDF_VCB_FLAGS_REMOVABLE_MEDIA );
246 }
247
248 RC = UDFGetDiskInfo(NewVcb->TargetDeviceObject,NewVcb);
249 if(!NT_SUCCESS(RC)) try_return(RC);
250 // Prevent modification attempts durring Verify
251 NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_READ_ONLY |
253 // Compare physical parameters (phase 1)
254 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
255 RC = UDFCompareVcb(Vcb,NewVcb, TRUE);
256 if(!NT_SUCCESS(RC)) try_return(RC);
257
258 if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
259 Vcb->MountPhErrorCount > MOUNT_ERR_THRESHOLD ) {
260 UDFPrint(("UDFVerifyVolume: it was very BAD volume. Do not perform Logical check\n"));
261 goto skip_logical_check;
262 }
263 // Initialize internal cache
264 // in *** READ ONLY *** mode
266
267 RC = WCacheInit__(&(NewVcb->FastCache),
270 NewVcb->WriteBlockSize,
271 5, NewVcb->BlockSizeBits,
273 0/*NewVcb->FirstLBA*/, NewVcb->LastPossibleLBA, Mode,
274 /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
275 (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
276 WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS, // speed up mount on bad disks
279#ifdef UDF_ASYNC_IO
280 UDFTWriteAsync, UDFTReadAsync,
281#else //UDF_ASYNC_IO
282 NULL, NULL,
283#endif //UDF_ASYNC_IO
286 if(!NT_SUCCESS(RC)) try_return(RC);
287
288 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
289 RC = UDFGetDiskInfoAndVerify(NewVcb->TargetDeviceObject,NewVcb);
290 UDFPrint((" NewVcb->NSRDesc=%x\n", NewVcb->NSRDesc));
291 if(!NT_SUCCESS(RC)) {
292 if((Vcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
293 (NewVcb->VCBFlags & UDF_VCB_FLAGS_RAW_DISK) &&
294 !(NewVcb->NSRDesc & VRS_ISO9660_FOUND)) {
295 UDFPrint(("UDFVerifyVolume: both are RAW -> remount\n", Vcb->Modified));
296 RC = STATUS_SUCCESS;
297 goto skip_logical_check;
298 }
301 }
302 try_return(RC);
303 }
304
305 WCacheChFlags__(&(Vcb->FastCache),
306 WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
307 WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
308
309 NewVcb->VCBFlags |= UDF_VCB_FLAGS_VOLUME_MOUNTED;
310 // Compare logical parameters (phase 2)
311 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
312 RC = UDFCompareVcb(Vcb,NewVcb, FALSE);
313 if(!NT_SUCCESS(RC)) try_return(RC);
314 // We have unitialized WCache, so it is better to
315 // force MOUNT_VOLUME call
316 if(!WCacheIsInitialized__(&(Vcb->FastCache)))
318
319skip_logical_check:;
320
321 }
322
323 UDFPrint(("UDFVerifyVolume: compared\n"));
324 UDFPrint(("UDFVerifyVolume: Modified=%d\n", Vcb->Modified));
325 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_LOCKED)) {
326 UDFPrint(("UDFVerifyVolume: set UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
328 Vcb->SoftEjectReq = FALSE;
329 }
330 UDFClearFlag( Vpb->RealDevice->Flags, DO_VERIFY_VOLUME );
331
332try_exit: NOTHING;
333
334 } _SEH2_FINALLY {
335
336 // Update the media change count to note that we have verified the volume
337 // at this value
338 Vcb->MediaChangeCount = MediaChangeCount;
339
340 // If we got the wrong volume, mark the Vcb as not mounted.
341 if(RC == STATUS_WRONG_VOLUME) {
342 UDFPrint(("UDFVerifyVolume: clear UDF_VCB_FLAGS_VOLUME_MOUNTED\n"));
343 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
344 Vcb->WriteSecurity = FALSE;
345// ASSERT(!(Vcb->EjectWaiter));
346 if(Vcb->EjectWaiter) {
347 UDFReleaseResource(&(Vcb->VCBResource));
349 UDFAcquireResourceExclusive(&(Vcb->VCBResource),TRUE);
350 }
351 } else
352 if(NT_SUCCESS(RC) &&
353 (Vcb->VCBFlags & UDF_VCB_FLAGS_VOLUME_MOUNTED)){
354 BOOLEAN CacheInitialized = FALSE;
355 UDFPrint((" !!! VerifyVolume - QUICK REMOUNT !!!\n"));
356 // Initialize internal cache
357 CacheInitialized = WCacheIsInitialized__(&(Vcb->FastCache));
358 if(!CacheInitialized) {
360 RC = WCacheInit__(&(Vcb->FastCache),
361 Vcb->WCacheMaxFrames,
362 Vcb->WCacheMaxBlocks,
363 Vcb->WriteBlockSize,
364 5, Vcb->BlockSizeBits,
365 Vcb->WCacheBlocksPerFrameSh,
366 0/*Vcb->FirstLBA*/, Vcb->LastPossibleLBA, Mode,
367 /*WCACHE_CACHE_WHOLE_PACKET*/ 0 |
368 (Vcb->DoNotCompareBeforeWrite ? WCACHE_DO_NOT_COMPARE : 0) |
369 (Vcb->CacheChainedIo ? WCACHE_CHAINED_IO : 0),
370 Vcb->WCacheFramesToKeepFree,
371// UDFTWrite, UDFTRead,
373#ifdef UDF_ASYNC_IO
374 UDFTWriteAsync, UDFTReadAsync,
375#else //UDF_ASYNC_IO
376 NULL, NULL,
377#endif //UDF_ASYNC_IO
380 }
381 if(NT_SUCCESS(RC)) {
382 if(!Vcb->VerifyCtx.VInited) {
383 RC = UDFVInit(Vcb);
384 }
385 }
386 if(NT_SUCCESS(RC)) {
387
388 if(!CacheInitialized) {
389 if(!(Vcb->VCBFlags & UDF_VCB_FLAGS_MEDIA_READ_ONLY)) {
390 if(!Vcb->CDR_Mode) {
391 if((Vcb->TargetDeviceObject->DeviceType == FILE_DEVICE_DISK) ||
392 CdrwMediaClassEx_IsRAM(Vcb->MediaClassEx)) {
393 UDFPrint(("UDFMountVolume: RAM mode\n"));
395 } else {
396 UDFPrint(("UDFMountVolume: RW mode\n"));
398 }
399 /* if(FsDeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM) {
400 } else {
401 Vcb->WriteSecurity = TRUE;
402 }*/
403 } else {
405 }
406 }
407 WCacheSetMode__(&(Vcb->FastCache), Mode);
408
409 WCacheChFlags__(&(Vcb->FastCache),
410 WCACHE_CACHE_WHOLE_PACKET, // enable cache whole packet
411 WCACHE_MARK_BAD_BLOCKS | WCACHE_RO_BAD_BLOCKS); // let user retry request on Bad Blocks
412 }
413 // we can't record ACL on old format disks
414 if(!UDFNtAclSupported(Vcb)) {
415 Vcb->WriteSecurity = FALSE;
416 Vcb->UseExtendedFE = FALSE;
417 }
418 UDFPrint(("UDFVerifyVolume: try start EjectWaiter\n"));
420 if(!NT_SUCCESS(RC)) {
421 UDFPrint(("UDFVerifyVolume: start EjectWaiter failed\n"));
422 Vcb->VCBFlags &= ~UDF_VCB_FLAGS_VOLUME_MOUNTED;
423 Vcb->WriteSecurity = FALSE;
424 }
425 }
426 }
427
428 if(NewVcb) {
429 // Release internal cache
430 UDFPrint(("UDFVerifyVolume: delete NewVcb\n"));
431 WCacheFlushAll__(&(NewVcb->FastCache),NewVcb);
432 WCacheRelease__(&(NewVcb->FastCache));
433
434 ASSERT(!(NewVcb->EjectWaiter));
435 // Waiter thread should be already stopped
436 // if MediaChangeCount have changed
437 ASSERT(!(Vcb->EjectWaiter));
438
439 UDFCleanupVCB(NewVcb);
440 MyFreePool__(NewVcb);
441 }
442 UDFReleaseResource(&(Vcb->VCBResource));
443 UDFReleaseResource(&(UDFGlobalData.GlobalDataResource));
444 } _SEH2_END;
445
446 // Complete the request if no exception.
447 Irp->IoStatus.Information = 0;
448
449 Irp->IoStatus.Status = RC;
451
452 UDFPrint(("UDFVerifyVolume: RC = %x\n", RC));
453
454 return RC;
455} // end UDFVerifyVolume ()
uint32 UDFIsBlockAllocated(IN void *_Vcb, IN uint32 Lba)
Definition: alloc.cpp:1164
#define CdrwMediaClassEx_IsRAM(MediaClassEx)
Definition: cdrw_usr.h:799
NTSTATUS UDFWCacheErrorHandler(IN PVOID Context, IN PWCACHE_ERROR_CONTEXT ErrorInfo)
Definition: misc.cpp:2583
NTSTATUS UDFStartEjectWaiter(IN PVCB Vcb)
Definition: fscntrl.cpp:850
_In_ ULONG Mode
Definition: hubbusif.h:303
OSSTATUS UDFGetDiskInfoAndVerify(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: mount.cpp:2983
OSSTATUS UDFGetDiskInfo(IN PDEVICE_OBJECT DeviceObject, IN PVCB Vcb)
Definition: phys_lib.cpp:3050
OSSTATUS UDFTReadVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T ReadBytes, IN uint32 Flags)
OSSTATUS UDFTWriteVerify(IN void *_Vcb, IN void *Buffer, IN SIZE_T Length, IN uint32 LBA, OUT PSIZE_T WrittenBytes, IN uint32 Flags)
#define FILE_DEVICE_DISK
Definition: winioctl.h:113
OSSTATUS UDFUpdateVAT(IN void *_Vcb, IN uint32 Lba, IN uint32 *RelocTab, IN uint32 BCount)
Definition: udf_info.cpp:5316
#define UDFNtAclSupported(Vcb)
Definition: udf_info.h:1040
#define VRS_ISO9660_FOUND
Definition: udf_rel.h:114
#define MOUNT_ERR_THRESHOLD
Definition: udffs.h:62
NTSTATUS UDFCompareVcb(IN PVCB OldVcb, IN PVCB NewVcb, IN BOOLEAN PhysicalOnly)
Definition: verfysup.cpp:849
BOOLEAN WCacheIsInitialized__(IN PW_CACHE Cache)
OSSTATUS WCacheInit__(IN PW_CACHE Cache, IN ULONG MaxFrames, IN ULONG MaxBlocks, IN SIZE_T MaxBytesToRead, IN ULONG PacketSizeSh, IN ULONG BlockSizeSh, IN ULONG BlocksPerFrameSh, IN lba_t FirstLba, IN lba_t LastLba, IN ULONG Mode, IN ULONG Flags, IN ULONG FramesToKeepFree, IN PWRITE_BLOCK WriteProc, IN PREAD_BLOCK ReadProc, IN PWRITE_BLOCK_ASYNC WriteProcAsync, IN PREAD_BLOCK_ASYNC ReadProcAsync, IN PCHECK_BLOCK CheckUsedProc, IN PUPDATE_RELOC UpdateRelocProc, IN PWC_ERROR_HANDLER ErrorHandlerProc)
Definition: wcache_lib.cpp:116
OSSTATUS WCacheSetMode__(IN PW_CACHE Cache, IN ULONG Mode)
ULONG WCacheChFlags__(IN PW_CACHE Cache, IN ULONG SetFlags, IN ULONG ClrFlags)
#define WCACHE_MODE_R
Definition: wcache_lib.h:126
#define WCACHE_MODE_RW
Definition: wcache_lib.h:125
#define WCACHE_RO_BAD_BLOCKS
Definition: wcache_lib.h:195
#define WCACHE_CACHE_WHOLE_PACKET
Definition: wcache_lib.h:191
#define WCACHE_MODE_ROM
Definition: wcache_lib.h:124
#define WCACHE_MODE_RAM
Definition: wcache_lib.h:127
#define WCACHE_MARK_BAD_BLOCKS
Definition: wcache_lib.h:194
#define WCACHE_DO_NOT_COMPARE
Definition: wcache_lib.h:192
#define WCACHE_CHAINED_IO
Definition: wcache_lib.h:193
#define SL_ALLOW_RAW_MOUNT
Definition: iotypes.h:1841

Referenced by UDFCommonFSControl().

◆ UDFWCacheErrorHandler()

NTSTATUS UDFWCacheErrorHandler ( IN PVOID  Context,
IN PWCACHE_ERROR_CONTEXT  ErrorInfo 
)

Definition at line 2583 of file misc.cpp.

2587{
2588 InterlockedIncrement((PLONG)&(((PVCB)Context)->IoErrorCounter));
2589 return ErrorInfo->Status;
2590}

Referenced by UDFMountVolume(), and UDFVerifyVolume().

◆ UDFWrite()

NTSTATUS NTAPI UDFWrite ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 42 of file write.cpp.

46{
48 PtrUDFIrpContext PtrIrpContext = NULL;
49 BOOLEAN AreWeTopLevel = FALSE;
50
51 TmPrint(("UDFWrite: , thrd:%8.8x\n",PsGetCurrentThread()));
52
55 ASSERT(Irp);
56
57 // set the top level context
58 AreWeTopLevel = UDFIsIrpTopLevel(Irp);
59 ASSERT(!UDFIsFSDevObj(DeviceObject));
60
61 _SEH2_TRY {
62
63 // get an IRP context structure and issue the request
64 PtrIrpContext = UDFAllocateIrpContext(Irp, DeviceObject);
65 if(PtrIrpContext) {
66
67 RC = UDFCommonWrite(PtrIrpContext, Irp);
68
69 } else {
71 Irp->IoStatus.Status = RC;
72 Irp->IoStatus.Information = 0;
73 // complete the IRP
75 }
76
78
79 RC = UDFExceptionHandler(PtrIrpContext, Irp);
80
82 } _SEH2_END;
83
84 if (AreWeTopLevel) {
86 }
87
89
90 return(RC);
91} // end UDFWrite()
NTSTATUS UDFCommonWrite(PtrUDFIrpContext PtrIrpContext, PIRP Irp)
Definition: write.cpp:112

Referenced by UDFInitializeFunctionPointers().

◆ UDFWriteSecurity()

NTSTATUS UDFWriteSecurity ( IN PVCB  Vcb,
IN PtrUDFFCB  Fcb,
IN PSECURITY_DESCRIPTOR SecurityDesc 
)

Definition at line 796 of file secursup.cpp.

801{
802#ifdef UDF_ENABLE_SECURITY
804 PUDF_FILE_INFO SDirInfo = NULL;
805 PUDF_FILE_INFO AclInfo = NULL;
806 PERESOURCE Res1 = NULL;
807 NTSTATUS RC;
808 ULONG NumberBytesRead;
809
810// UDFPrint(("UDFWriteSecurity\n"));
811
812#if !defined(UDF_READ_ONLY_BUILD)
813
814 if(!Vcb->WriteSecurity ||
815 (Vcb->VCBFlags & (UDF_VCB_FLAGS_VOLUME_READ_ONLY |
817
818#endif
819
820 return STATUS_SUCCESS;
821
822#if !defined(UDF_READ_ONLY_BUILD)
823
824 _SEH2_TRY {
825
826 FileInfo = Fcb->FileInfo;
828 if(!FileInfo) {
829 UDFPrint((" Volume Security\n"));
831 }
832
833 if(!(Fcb->NTRequiredFCB->NtReqFCBFlags & UDF_NTREQ_FCB_SD_MODIFIED))
835
836 // Open Stream Directory
837 RC = UDFOpenStreamDir__(Vcb, FileInfo, &SDirInfo);
838
839 if(RC == STATUS_NOT_FOUND) {
840 RC = UDFCreateStreamDir__(Vcb, FileInfo, &SDirInfo);
841 }
842 if(!NT_SUCCESS(RC)) {
843 if(UDFCleanUpFile__(Vcb, SDirInfo)) {
844 if(SDirInfo) MyFreePool__(SDirInfo);
845 }
846 SDirInfo = NULL;
847 try_return(RC);
848 }
849 // Acquire SDir exclusively if Fcb present
850 if(SDirInfo->Fcb) {
851 BrutePoint();
852 UDF_CHECK_PAGING_IO_RESOURCE(SDirInfo->Fcb->NTRequiredFCB);
853 UDFAcquireResourceExclusive(Res1 = &(SDirInfo->Fcb->NTRequiredFCB->MainResource),TRUE);
854 }
855
856 // Open Acl Stream
857 RC = UDFOpenFile__(Vcb,
859 SDirInfo,&AclInfo,NULL);
862 0, 0, FALSE, FALSE, SDirInfo, &AclInfo);
863 }
864 if(!NT_SUCCESS(RC)) {
865 if(UDFCleanUpFile__(Vcb, AclInfo)) {
866 if(AclInfo) MyFreePool__(AclInfo);
867 }
868 AclInfo = NULL;
869 try_return(RC);
870 }
871
872 if(!(*SecurityDesc)) {
873 UDFFlushFile__(Vcb, AclInfo);
874 RC = UDFUnlinkFile__(Vcb, AclInfo, TRUE);
875 try_return(RC);
876 }
877 NumberBytesRead = RtlLengthSecurityDescriptor(*SecurityDesc);
878
879 RC = UDFWriteFile__(Vcb, AclInfo, 0, NumberBytesRead,
880 FALSE, (PCHAR)(*SecurityDesc), &NumberBytesRead);
881 if(!NT_SUCCESS(RC))
882 try_return(RC);
883
884 Fcb->NTRequiredFCB->NtReqFCBFlags &= ~UDF_NTREQ_FCB_SD_MODIFIED;
885
886try_exit: NOTHING;
887
888 } _SEH2_FINALLY {
889
890 if(AclInfo) {
891 UDFCloseFile__(Vcb, AclInfo);
892 if(UDFCleanUpFile__(Vcb, AclInfo))
893 MyFreePool__(AclInfo);
894 }
895
896 if(SDirInfo) {
897 UDFCloseFile__(Vcb, SDirInfo);
898 if(UDFCleanUpFile__(Vcb, SDirInfo))
899 MyFreePool__(SDirInfo);
900 }
901 if(Res1)
902 UDFReleaseResource(Res1);
903 }
904
905 return RC;
906
907#endif
908#endif //UDF_ENABLE_SECURITY
909
910 return STATUS_SUCCESS;
911
912} // end UDFWriteSecurity()
NTSYSAPI ULONG WINAPI RtlLengthSecurityDescriptor(PSECURITY_DESCRIPTOR)
#define UDF_NTREQ_FCB_SD_MODIFIED
Definition: struct.h:233
OSSTATUS UDFCreateFile__(IN PVCB Vcb, IN BOOLEAN IgnoreCase, IN PUNICODE_STRING _fn, IN uint32 ExtAttrSz, IN uint32 ImpUseLen, IN BOOLEAN Extended, IN BOOLEAN CreateNew, IN OUT PUDF_FILE_INFO DirInfo, OUT PUDF_FILE_INFO *_FileInfo)
Definition: udf_info.cpp:2577
OSSTATUS UDFCreateStreamDir__(IN PVCB Vcb, IN PUDF_FILE_INFO FileInfo, OUT PUDF_FILE_INFO *_SDirInfo)
Definition: udf_info.cpp:4888

Referenced by UDFCloseFileInfoChain(), UDFFlushADirectory(), and UDFFlushAFile().