Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

udfprocs.h File Reference

#include <ntifs.h>
#include <ntddcdrm.h>
#include <ntddcdvd.h>
#include <ntdddisk.h>
#include "nodetype.h"
#include "Udf.h"
#include "UdfStruc.h"
#include "UdfData.h"

Go to the source code of this file.

Classes

union  _UCHAR1
union  _UCHAR2
union  _UCHAR4
union  _USHORT2

Defines

#define INLINE   __inline
#define BugCheckFileId   (UDFS_BUG_CHECK_STRUCSUP)
#define Dbg   (UDFS_DEBUG_LEVEL_STRUCSUP)
#define Min(a, b)   ((a) < (b) ? (a) : (b))
#define Max(a, b)   ((a) > (b) ? (a) : (b))
#define FlagMask(F, SF)
#define BooleanFlagOn(F, SF)
#define BooleanFlagOff(F, SF)
#define SetFlag(Flags, SingleFlag)
#define ClearFlag(Flags, SingleFlag)
#define Add2Ptr(PTR, INC, CAST)   ((CAST)((ULONG_PTR)(PTR) + (INC)))
#define PtrOffset(BASE, OFFSET)   ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
#define GenericTruncate(B, U)
#define GenericAlign(B, U)
#define GenericOffset(B, U)
#define GenericRemainder(B, U)
#define GenericTruncatePtr(B, U)
#define GenericAlignPtr(B, U)
#define GenericOffsetPtr(B, U)
#define GenericRemainderPtr(B, U)
#define WordAlign(B)   GenericAlign((B), 2)
#define LongAlign(B)   GenericAlign((B), 4)
#define QuadAlign(B)   GenericAlign((B), 8)
#define WordOffset(B)   GenericOffset((B), 2)
#define LongOffset(B)   GenericOffset((B), 4)
#define QuadOffset(B)   GenericOffset((B), 8)
#define WordAlignPtr(P)   GenericAlignPtr((P), 2)
#define LongAlignPtr(P)   GenericAlignPtr((P), 4)
#define QuadAlignPtr(P)   GenericAlignPtr((P), 8)
#define WordOffsetPtr(P)   GenericOffsetPtr((P), 2)
#define LongOffsetPtr(P)   GenericOffsetPtr((P), 4)
#define QuadOffsetPtr(P)   GenericOffsetPtr((P), 8)
#define SectorAlignN(SECTORSIZE, L)
#define SectorAlign(V, L)
#define LlSectorAlign(V, L)
#define SectorTruncate(V, L)
#define LlSectorTruncate(V, L)
#define BytesFromSectors(V, L)
#define SectorsFromBytes(V, L)
#define LlBytesFromSectors(V, L)
#define LlSectorsFromBytes(V, L)
#define SectorsFromBlocks(V, B)   (B)
#define SectorSize(V)   ((V)->SectorSize)
#define SectorOffset(V, L)
#define BlockAlignN(BLOCKSIZE, L)
#define BlockAlign(V, L)
#define LlBlockAlign(V, L)
#define BlockTruncate(V, L)
#define LlBlockTruncate(V, L)
#define BytesFromBlocks(V, L)
#define BlocksFromBytes(V, L)
#define LlBytesFromBlocks(V, L)
#define LlBlocksFromBytes(V, L)
#define BlocksFromSectors(V, S)   (S)
#define BlockSize(V)   (SectorSize(V))
#define BlockOffset(V, L)
#define CopyUchar1(Dst, Src)
#define CopyUchar2(Dst, Src)
#define SwapCopyUchar2(Dst, Src)
#define CopyUchar4(Dst, Src)
#define SwapCopyUchar4(Dst, Src)
#define CopyUshort2(Dst, Src)
#define CanFsdWait(I)   IoIsOperationSynchronous(I)
#define UdfIsFastIoPossible(F)
#define try_leave(S)   { S; leave; }
#define UdfPagedPool   PagedPool
#define UdfNonPagedPool   NonPagedPool
#define UdfNonPagedPoolCacheAligned   NonPagedPoolCacheAligned
#define UdfUnpinView(IC, V)   if (((V)->Bcb) != NULL) { CcUnpinData( ((V)->Bcb) ); ((V)->Bcb) = NULL; ((V)->View) = NULL; }
#define UdfUnpinData(IC, B)   if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
#define UdfMapUserBuffer(IC, UB)
#define UdfLockUserBuffer(IC, BL)
#define UdfAcquireUdfData(IC)   ExAcquireResourceExclusive( &UdfData.DataResource, TRUE )
#define UdfReleaseUdfData(IC)   ExReleaseResource( &UdfData.DataResource )
#define UdfAcquireVcbExclusive(IC, V, I)   UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
#define UdfAcquireVcbShared(IC, V, I)   UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
#define UdfReleaseVcb(IC, V)   ExReleaseResource( &(V)->VcbResource )
#define UdfAcquireAllFiles(IC, V)   UdfAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
#define UdfReleaseAllFiles(IC, V)   ExReleaseResource( &(V)->FileResource )
#define UdfAcquireFileExclusive(IC, F)   UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
#define UdfAcquireFileShared(IC, F)   UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
#define UdfAcquireFileSharedStarveExclusive(IC, F)   UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
#define UdfReleaseFile(IC, F)   ExReleaseResource( (F)->Resource )
#define UdfAcquireFcbExclusive(IC, F, I)   UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
#define UdfAcquireFcbShared(IC, F, I)   UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
#define UdfReleaseFcb(IC, F)   ExReleaseResource( &(F)->FcbNonpaged->FcbResource )
#define UdfLockUdfData()
#define UdfUnlockUdfData()
#define UdfLockVcb(IC, V)
#define UdfUnlockVcb(IC, V)
#define UdfLockFcb(IC, F)
#define UdfUnlockFcb(IC, F)
#define UdfCreateIrpContextLite(IC)   ExAllocatePoolWithTag( UdfNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
#define UdfFreeIrpContextLite(ICL)   ExFreePool( ICL )
#define UdfAllocateIoContext()
#define UdfFreeIoContext(IO)   ExFreePool( IO )
#define UdfIncrementCleanupCounts(IC, F)
#define UdfDecrementCleanupCounts(IC, F)
#define UdfIncrementReferenceCounts(IC, F, C, UC)
#define UdfDecrementReferenceCounts(IC, F, C, UC)
#define UdfIsRawDevice(IC, S)

Typedefs

typedef _UCHAR1 UCHAR1
typedef _UCHAR1PUCHAR1
typedef _UCHAR2 UCHAR2
typedef _UCHAR2PUCHAR2
typedef _UCHAR4 UCHAR4
typedef _UCHAR4PUCHAR4
typedef _USHORT2 USHORT2
typedef _USHORT2PUSHORT2
typedef enum _TYPE_OF_OPEN TYPE_OF_OPEN
typedef enum _TYPE_OF_OPENPTYPE_OF_OPEN
typedef enum _TYPE_OF_ACQUIRE TYPE_OF_ACQUIRE
typedef enum _TYPE_OF_ACQUIREPTYPE_OF_ACQUIRE

Enumerations

enum  _TYPE_OF_OPEN {
  UnopenedFileObject = 0, StreamFileOpen, UserVolumeOpen, UserDirectoryOpen,
  UserFileOpen, BeyondValidType
}
enum  _TYPE_OF_ACQUIRE { AcquireExclusive, AcquireShared, AcquireSharedStarveExclusive }

Functions

INLINE DECLSPEC_NORETURN VOID UdfRaiseStatus (IN PIRP_CONTEXT IrpContext, IN NTSTATUS Status)
INLINE VOID UdfNormalizeAndRaiseStatus (IN PIRP_CONTEXT IrpContext, IN NTSTATUS Status)
INLINE VOID UdfFreePool (IN PVOID *Pool)
INLINE BOOLEAN UdfEqualCountedString (IN PSTRING String, IN PCHAR Field)
NTSTATUS UdfFsdDispatch (IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject, IN PIRP Irp)
LONG UdfExceptionFilter (IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
NTSTATUS UdfProcessException (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PIRP Irp, IN NTSTATUS ExceptionCode)
VOID UdfCompleteRequest (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PIRP Irp OPTIONAL, IN NTSTATUS Status)
VOID UdfSetThreadContext (IN PIRP_CONTEXT IrpContext, IN PTHREAD_CONTEXT ThreadContext)
INLINE VOID UdfRestoreThreadContext (IN PIRP_CONTEXT IrpContext)
ULONG UdfSerial32 (IN PCHAR Buffer, IN ULONG ByteCount)
VOID UdfInitializeCrc16 (ULONG Polynomial)
USHORT UdfComputeCrc16 (IN PUCHAR Buffer, IN ULONG ByteCount)
USHORT UdfComputeCrc16Uni (PWCHAR Buffer, ULONG CharCount)
ULONG UdfHighBit (ULONG Word)
BOOLEAN UdfFastQueryBasicInfo (IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, IN OUT PFILE_BASIC_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
BOOLEAN 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)
BOOLEAN 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 UdfFastQueryNetworkInfo (IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, OUT PFILE_NETWORK_OPEN_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
BOOLEAN UdfFastQueryStdInfo (IN PFILE_OBJECT FileObject, IN BOOLEAN Wait, IN OUT PFILE_STANDARD_INFORMATION Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
BOOLEAN 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 UdfFastUnlockAll (IN PFILE_OBJECT FileObject, PEPROCESS ProcessId, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
BOOLEAN UdfFastUnlockAllByKey (IN PFILE_OBJECT FileObject, PVOID ProcessId, ULONG Key, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
INLINE BOOLEAN UdfIllegalFcbAccess (IN PIRP_CONTEXT IrpContext, IN TYPE_OF_OPEN TypeOfOpen, IN ACCESS_MASK DesiredAccess)
BOOLEAN UdfLookupAllocation (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN LONGLONG FileOffset, OUT PLONGLONG DiskOffset, OUT PULONG ByteCount)
VOID UdfDeletePcb (IN PPCB Pcb)
NTSTATUS UdfInitializePcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN OUT PPCB *Pcb, IN PNSR_LVOL LVD)
VOID UdfAddToPcb (IN PPCB Pcb, IN PNSR_PART PartitionDescriptor)
NTSTATUS UdfCompletePcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PPCB Pcb)
BOOLEAN UdfEquivalentPcb (IN PIRP_CONTEXT IrpContext, IN PPCB Pcb1, IN PPCB Pcb2)
ULONG UdfLookupPsnOfExtent (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT Reference, IN ULONG Lbn, IN ULONG Len)
ULONG UdfLookupMetaVsnOfExtent (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN USHORT Reference, IN ULONG Lbn, IN ULONG Len, IN BOOLEAN ExactEnd)
VOID UdfCreateInternalStream (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFCB Fcb)
VOID UdfDeleteInternalStream (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
NTSTATUS UdfCompleteMdl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
VOID UdfMapMetadataView (IN PIRP_CONTEXT IrpContext, IN PMAPPED_PVIEW View, IN PVCB Vcb, IN USHORT Partition, IN ULONG Lbn, IN ULONG Length)
NTSTATUS UdfPurgeVolume (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN DismountUnderway)
NTSTATUS UdfPerformDevIoCtrl (IN PIRP_CONTEXT IrpContext, IN ULONG IoControlCode, IN PDEVICE_OBJECT Device, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN BOOLEAN OverrideVerify, OUT PIO_STATUS_BLOCK Iosb OPTIONAL)
NTSTATUS UdfReadSectors (IN PIRP_CONTEXT IrpContext, IN LONGLONG StartingOffset, IN ULONG ByteCount, IN BOOLEAN ReturnError, IN OUT PVOID Buffer, IN PDEVICE_OBJECT TargetDeviceObject)
NTSTATUS UdfNonCachedRead (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN LONGLONG StartingOffset, IN ULONG ByteCount)
NTSTATUS UdfCreateUserMdl (IN PIRP_CONTEXT IrpContext, IN ULONG BufferLength, IN BOOLEAN RaiseOnError)
INLINE ULONG UdfRawBufferSize (IN PVCB Vcb, IN ULONG StructureSize)
INLINE ULONG UdfRawReadSize (IN PVCB Vcb, IN ULONG StructureSize)
INLINE ULONG UdfRawBufferSizeN (IN ULONG SectorSize, IN ULONG StructureSize)
INLINE ULONG UdfRawReadSizeN (IN ULONG SectorSize, IN ULONG StructureSize)
VOID UdfInitializeDirContext (IN PIRP_CONTEXT IrpContext, IN PDIR_ENUM_CONTEXT DirContext)
VOID UdfCleanupDirContext (IN PIRP_CONTEXT IrpContext, IN PDIR_ENUM_CONTEXT DirContext)
BOOLEAN UdfLookupInitialDirEntry (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PDIR_ENUM_CONTEXT DirContext, IN PLONGLONG InitialOffset OPTIONAL)
BOOLEAN UdfLookupNextDirEntry (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PDIR_ENUM_CONTEXT DirContext)
VOID UdfUpdateDirNames (IN PIRP_CONTEXT IrpContext, IN PDIR_ENUM_CONTEXT DirContext, IN BOOLEAN IgnoreCase)
BOOLEAN UdfFindDirEntry (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN BOOLEAN ShortName, IN PDIR_ENUM_CONTEXT DirContext)
VOID UdfSetFileObject (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN TYPE_OF_OPEN TypeOfOpen, IN PFCB Fcb OPTIONAL, IN PCCB Ccb OPTIONAL)
TYPE_OF_OPEN UdfDecodeFileObject (IN PFILE_OBJECT FileObject, OUT PFCB *Fcb, OUT PCCB *Ccb)
TYPE_OF_OPEN UdfFastDecodeFileObject (IN PFILE_OBJECT FileObject, OUT PFCB *Fcb)
VOID UdfStoreVolumeDescriptorIfPrevailing (IN OUT PNSR_VD_GENERIC *StoredVD, IN OUT PNSR_VD_GENERIC NewVD)
VOID UdfDissectName (IN PIRP_CONTEXT IrpContext, IN OUT PUNICODE_STRING RemainingName, OUT PUNICODE_STRING FinalName)
BOOLEAN UdfIs8dot3Name (IN PIRP_CONTEXT IrpContext, IN UNICODE_STRING FileName)
BOOLEAN UdfCandidateShortName (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING Name)
VOID UdfGenerate8dot3Name (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING FileName, OUT PUNICODE_STRING ShortFileName)
VOID UdfConvertCS0DstringToUnicode (IN PIRP_CONTEXT IrpContext, IN PUCHAR Dstring, IN UCHAR Length OPTIONAL, IN UCHAR FieldLength OPTIONAL, IN OUT PUNICODE_STRING Name)
BOOLEAN UdfCheckLegalCS0Dstring (PIRP_CONTEXT IrpContext, PUCHAR Dstring, UCHAR Length OPTIONAL, UCHAR FieldLength OPTIONAL, BOOLEAN ReturnOnError)
VOID UdfRenderNameToLegalUnicode (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING Name, IN PUNICODE_STRING RenderedName)
BOOLEAN UdfIsNameInExpression (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING CurrentName, IN PUNICODE_STRING SearchExpression, IN BOOLEAN Wild)
FSRTL_COMPARISON_RESULT UdfFullCompareNames (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING NameA, IN PUNICODE_STRING NameB)
INLINE VOID UdfUpcaseName (IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING Name, IN OUT PUNICODE_STRING UpcaseName)
INLINE USHORT UdfCS0DstringUnicodeSize (PIRP_CONTEXT IrpContext, PCHAR Dstring, UCHAR Length)
INLINE BOOLEAN UdfIsCharacterLegal (IN WCHAR Character)
INLINE BOOLEAN UdfCS0DstringContainsLegalCharacters (IN PCHAR Dstring, IN ULONG Length)
NTSTATUS UdfLockVolumeInternal (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject OPTIONAL)
NTSTATUS UdfUnlockVolumeInternal (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PFILE_OBJECT FileObject OPTIONAL)
PLCB UdfFindPrefix (IN PIRP_CONTEXT IrpContext, IN OUT PFCB *CurrentFcb, IN OUT PUNICODE_STRING RemainingName, IN BOOLEAN IgnoreCase)
VOID UdfInitializeLcbFromDirContext (IN PIRP_CONTEXT IrpContext, IN PLCB Lcb, IN PDIR_ENUM_CONTEXT DirContext)
PLCB UdfInsertPrefix (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PUNICODE_STRING Name, IN BOOLEAN ShortNameMatch, IN BOOLEAN IgnoreCase, IN PFCB ParentFcb)
VOID UdfRemovePrefix (IN PIRP_CONTEXT IrpContext, IN PLCB Lcb)
BOOLEAN UdfAcquireResource (IN PIRP_CONTEXT IrpContext, IN PERESOURCE Resource, IN BOOLEAN IgnoreWait, IN TYPE_OF_ACQUIRE Type)
BOOLEAN UdfNoopAcquire (IN PVOID Fcb, IN BOOLEAN Wait)
VOID UdfNoopRelease (IN PVOID Fcb)
BOOLEAN UdfAcquireForCache (IN PFCB Fcb, IN BOOLEAN Wait)
VOID UdfReleaseFromCache (IN PFCB Fcb)
VOID UdfAcquireForCreateSection (IN PFILE_OBJECT FileObject)
VOID UdfReleaseForCreateSection (IN PFILE_OBJECT FileObject)
BOOLEAN UdfInitializeVcb (IN PIRP_CONTEXT IrpContext, IN OUT PVCB Vcb, IN PDEVICE_OBJECT TargetDeviceObject, IN PVPB Vpb, IN PDISK_GEOMETRY DiskGeometry, IN ULONG MediaChangeCount)
VOID UdfUpdateVcbPhase0 (IN PIRP_CONTEXT IrpContext, IN OUT PVCB Vcb)
VOID UdfUpdateVcbPhase1 (IN PIRP_CONTEXT IrpContext, IN OUT PVCB Vcb, IN PNSR_FSD Fsd)
VOID UdfDeleteVcb (IN PIRP_CONTEXT IrpContext, IN OUT PVCB Vcb)
PIRP_CONTEXT UdfCreateIrpContext (IN PIRP Irp, IN BOOLEAN Wait)
VOID UdfCleanupIrpContext (IN PIRP_CONTEXT IrpContext, IN BOOLEAN Post)
VOID UdfInitializeStackIrpContext (OUT PIRP_CONTEXT IrpContext, IN PIRP_CONTEXT_LITE IrpContextLite)
VOID UdfTeardownStructures (IN PIRP_CONTEXT IrpContext, IN PFCB StartingFcb, IN BOOLEAN Recursive, OUT PBOOLEAN RemovedStartingFcb)
PFCB UdfLookupFcbTable (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN FILE_ID FileId)
PFCB UdfGetNextFcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN PVOID *RestartKey)
PFCB UdfCreateFcb (IN PIRP_CONTEXT IrpContext, IN FILE_ID FileId, IN NODE_TYPE_CODE NodeTypeCode, OUT PBOOLEAN FcbExisted OPTIONAL)
VOID UdfDeleteFcb (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
VOID UdfInitializeFcbFromIcbContext (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PICB_SEARCH_CONTEXT IcbContext)
PCCB UdfCreateCcb (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PLCB Lcb OPTIONAL, IN ULONG Flags)
VOID UdfDeleteCcb (IN PIRP_CONTEXT IrpContext, IN PCCB Ccb)
ULONG UdfFindInParseTable (IN PPARSE_KEYVALUE ParseTable, IN PCHAR Id, IN ULONG MaxIdLen)
BOOLEAN UdfVerifyDescriptor (IN PIRP_CONTEXT IrpContext, IN PDESTAG Descriptor, IN USHORT Tag, IN ULONG Size, IN ULONG Lbn, IN BOOLEAN ReturnError)
VOID UdfInitializeIcbContextFromFcb (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext, IN PFCB Fcb)
VOID UdfInitializeIcbContext (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext, IN PVCB Vcb, IN USHORT IcbType, IN USHORT Partition, IN ULONG Lbn, IN ULONG Length)
INLINE VOID UdfFastInitializeIcbContext (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext)
VOID UdfLookupActiveIcb (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext)
VOID UdfCleanupIcbContext (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext)
VOID UdfInitializeAllocations (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PICB_SEARCH_CONTEXT IcbContext)
VOID UdfUpdateTimestampsFromIcbContext (IN PIRP_CONTEXT IrpContext, IN PICB_SEARCH_CONTEXT IcbContext, IN PTIMESTAMP_BUNDLE Timestamps)
BOOLEAN UdfCreateFileLock (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PFCB Fcb, IN BOOLEAN RaiseOnError)
INLINE VOID UdfConvertUdfTimeToNtTime (IN PIRP_CONTEXT IrpContext, IN PTIMESTAMP UdfTime, OUT PLARGE_INTEGER NtTime)
INLINE BOOLEAN UdfEqualEntityId (IN PREGID RegID, IN PSTRING Id, IN OPTIONAL PSTRING Suffix)
INLINE BOOLEAN UdfDomainIdentifierContained (IN PREGID RegID, IN PSTRING Domain, IN USHORT RevisionMin, IN USHORT RevisionMax)
INLINE BOOLEAN UdfUdfIdentifierContained (IN PREGID RegID, IN PSTRING Type, IN USHORT RevisionMin, IN USHORT RevisionMax, IN UCHAR OSClass, IN UCHAR OSIdentifier)
BOOLEAN UdfCheckForDismount (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb, IN BOOLEAN Force)
BOOLEAN UdfDismountVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
VOID UdfVerifyVcb (IN PIRP_CONTEXT IrpContext, IN PVCB Vcb)
BOOLEAN UdfVerifyFcbOperation (IN PIRP_CONTEXT IrpContext OPTIONAL, IN PFCB Fcb)
VOID UdfInitializeVmcb (IN PVMCB Vmcb, IN POOL_TYPE PoolType, IN ULONG MaximumLbn, IN ULONG LbSize)
VOID UdfUninitializeVmcb (IN PVMCB Vmcb)
VOID UdfResetVmcb (IN PVMCB Vmcb)
VOID UdfSetMaximumLbnVmcb (IN PVMCB Vmcb, IN ULONG MaximumLbn)
BOOLEAN UdfVmcbVbnToLbn (IN PVMCB Vmcb, IN VBN Vbn, OUT PLBN Lbn, OUT PULONG SectorCount OPTIONAL)
BOOLEAN UdfVmcbLbnToVbn (IN PVMCB Vmcb, IN LBN Lbn, OUT PVBN Vbn, OUT PULONG SectorCount OPTIONAL)
BOOLEAN UdfAddVmcbMapping (IN PVMCB Vmcb, IN LBN Lbn, IN ULONG SectorCount, IN BOOLEAN ExactEnd, OUT PVBN Vbn, OUT PULONG AlignedSectorCount)
VOID UdfRemoveVmcbMapping (IN PVMCB Vmcb, IN LBN Lbn, IN ULONG SectorCount)
NTSTATUS UdfPerformVerify (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PDEVICE_OBJECT DeviceToVerify)
NTSTATUS UdfFsdPostRequest (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
VOID UdfPrePostIrp (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
VOID UdfOplockComplete (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
INLINE BOOLEAN UdfEqualCharspec (IN PCHARSPEC Charspec, IN PSTRING Identifier, IN UCHAR Type)
VOID UdfFspDispatch (IN PIRP_CONTEXT IrpContext)
VOID UdfFspClose (IN PVCB Vcb OPTIONAL)
NTSTATUS UdfCommonCleanup (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonClose (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonCreate (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonDevControl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonDirControl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonFsControl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonLockControl (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonPnp (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonQueryInfo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonQueryVolInfo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonRead (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)
NTSTATUS UdfCommonSetInfo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp)


Define Documentation

#define Add2Ptr PTR,
INC,
CAST   )     ((CAST)((ULONG_PTR)(PTR) + (INC)))
 

Definition at line 103 of file udfprocs.h.

#define BlockAlign V,
 ) 
 

Value:

( \ SectorAlign((V), (L)) \ )

Definition at line 244 of file udfprocs.h.

#define BlockAlignN BLOCKSIZE,
 ) 
 

Value:

( \ SectorAlighN((BLOCKSIZE), (L)) \ )

Definition at line 240 of file udfprocs.h.

#define BlockOffset V,
 ) 
 

Value:

( \ SectorOffset((V), (L)) \ )

Definition at line 280 of file udfprocs.h.

Referenced by UdfFindFileSetDescriptor(), UdfInitializeAllocations(), and UdfLookupMetaVsnOfExtent().

#define BlocksFromBytes V,
 ) 
 

Value:

( \ SectorsFromBytes((V), (L)) \ )

Definition at line 264 of file udfprocs.h.

Referenced by UdfLookupMetaVsnOfExtent(), and UdfLookupPsnOfExtent().

#define BlocksFromSectors V,
 )     (S)
 

Definition at line 276 of file udfprocs.h.

Referenced by UdfLookupMetaVsnOfExtent(), and UdfUpdateVcbPhase0().

#define BlockSize  )     (SectorSize(V))
 

Definition at line 278 of file udfprocs.h.

Referenced by ExInitializeRegion(), ExInitializeZone(), ExInterlockedExtendRegion(), InitLookaside(), KeCheckForTimer(), UdfFindFileSetDescriptor(), UdfGetNextAllocationPostProcessing(), UdfInitializeAllocations(), UdfInitializeFcbFromIcbContext(), UdfInitializeIcbContextFromFcb(), UdfLookupActiveIcbInExtent(), UdfLookupDirEntryPostProcessing(), UdfLookupPsnOfExtent(), UdfQueryFsSizeInfo(), and UdfUpdateVcbPhase0().

#define BlockTruncate V,
 ) 
 

Value:

( \ SectorTruncate((V), (L)) \ )

Definition at line 252 of file udfprocs.h.

#define BooleanFlagOff F,
SF   ) 
 

Value:

( \ (BOOLEAN)(FlagOn(F, SF)) == 0) \ )

Definition at line 76 of file udfprocs.h.

#define BooleanFlagOn F,
SF   ) 
 

Value:

( \ (BOOLEAN)(FlagOn(F, SF) != 0) \ )

Definition at line 72 of file udfprocs.h.

#define BugCheckFileId   (UDFS_BUG_CHECK_STRUCSUP)
 

Definition at line 44 of file udfprocs.h.

#define BytesFromBlocks V,
 ) 
 

Value:

( \ BytesFromSectors((V), (L)) \ )

Definition at line 260 of file udfprocs.h.

#define BytesFromSectors V,
 ) 
 

Value:

( \ ((ULONG) (L)) << ((V)->SectorShift) \ )

Definition at line 212 of file udfprocs.h.

#define CanFsdWait  )     IoIsOperationSynchronous(I)
 

Definition at line 371 of file udfprocs.h.

Referenced by UdfFsdDispatch().

#define ClearFlag Flags,
SingleFlag   ) 
 

Value:

( \ (Flags) &= ~(SingleFlag) \ )

Definition at line 84 of file udfprocs.h.

#define CopyUchar1 Dst,
Src   ) 
 

Value:

{ \ *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ }

Definition at line 313 of file udfprocs.h.

#define CopyUchar2 Dst,
Src   ) 
 

Value:

{ \ *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ }

Definition at line 321 of file udfprocs.h.

#define CopyUchar4 Dst,
Src   ) 
 

Value:

{ \ *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \ }

Definition at line 339 of file udfprocs.h.

#define CopyUshort2 Dst,
Src   ) 
 

Value:

{ \ *((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\ }

Definition at line 360 of file udfprocs.h.

#define Dbg   (UDFS_DEBUG_LEVEL_STRUCSUP)
 

Definition at line 50 of file udfprocs.h.

#define FlagMask F,
SF   ) 
 

Value:

( \ ((F) & (SF)) \ )

Definition at line 68 of file udfprocs.h.

Referenced by SepAdtOpenObjectAuditAlarm().

#define GenericAlign B,
 ) 
 

Value:

( \ GenericTruncate((B) + (U) - 1, U) \ )

Definition at line 118 of file udfprocs.h.

#define GenericAlignPtr B,
 ) 
 

Value:

( \ GenericTruncatePtr((B) + (U) - 1, (U)) \ )

Definition at line 135 of file udfprocs.h.

#define GenericOffset B,
 ) 
 

Value:

( \ (B) & ((U) - 1) \ )

Definition at line 122 of file udfprocs.h.

Referenced by UdfLookupInitialDirEntry().

#define GenericOffsetPtr B,
 ) 
 

Value:

( \ (ULONG)(((ULONG_PTR)(B)) & ((U) - 1)) \ )

Definition at line 139 of file udfprocs.h.

#define GenericRemainder B,
 ) 
 

Value:

( \ GenericOffset( (U) - GenericOffset((B), (U)), (U) ) \ )

Definition at line 126 of file udfprocs.h.

#define GenericRemainderPtr B,
 ) 
 

Value:

( \ (ULONG)GenericOffset( (U) - GenericOffsetPtr((B), (U)), (U) ) \ )

Definition at line 143 of file udfprocs.h.

Referenced by UdfLookupDirEntryPostProcessing().

#define GenericTruncate B,
 ) 
 

Value:

( \ (B) & ~((U) - 1) \ )

Definition at line 114 of file udfprocs.h.

Referenced by UdfLookupInitialDirEntry().

#define GenericTruncatePtr B,
 ) 
 

Value:

( \ (PVOID)(((ULONG_PTR)(B)) & ~((U) - 1)) \ )

Definition at line 131 of file udfprocs.h.

Referenced by UdfLookupDirEntryPostProcessing().

#define INLINE   __inline
 

Definition at line 32 of file udfprocs.h.

#define LlBlockAlign V,
 ) 
 

Value:

( \ LlSectorAlign((V), (L)) \ )

Definition at line 248 of file udfprocs.h.

Referenced by UdfInitializeFcbFromIcbContext(), and UdfQueryDirectory().

#define LlBlocksFromBytes V,
 ) 
 

Value:

( \ LlSectorsFromBytes((V), (L)) \ )

Definition at line 272 of file udfprocs.h.

Referenced by UdfQueryFsSizeInfo().

#define LlBlockTruncate V,
 ) 
 

Value:

( \ LlSectorTruncate((V), (L)) \ )

Definition at line 256 of file udfprocs.h.

#define LlBytesFromBlocks V,
 ) 
 

Value:

( \ LlBytesFromSectors((V), (L)) \ )

Definition at line 268 of file udfprocs.h.

Referenced by UdfFindFileSetDescriptor().

#define LlBytesFromSectors V,
 ) 
 

Value:

( \ Int64ShllMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \ )

Definition at line 220 of file udfprocs.h.

Referenced by UdfDvdReadStructure(), UdfDvdTransferKey(), UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfLookupAllocation(), UdfLookupMetaVsnOfExtent(), UdfMapMetadataView(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

#define LlSectorAlign V,
 ) 
 

Value:

( \ ((((LONGLONG)(L)) + (((V)->SectorSize) - 1)) & ~(((LONGLONG)(V)->SectorSize) - 1)) \ )

Definition at line 200 of file udfprocs.h.

Referenced by UdfUpdateVcbPhase0().

#define LlSectorsFromBytes V,
 ) 
 

Value:

( \ Int64ShrlMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \ )

Definition at line 224 of file udfprocs.h.

Referenced by UdfDvdReadStructure(), UdfDvdTransferKey(), UdfInitializeAllocations(), UdfLookupAllocation(), and UdfReadSectors().

#define LlSectorTruncate V,
 ) 
 

Value:

( \ ((LONGLONG)(L)) & ~(((LONGLONG)(V)->SectorSize) - 1) \ )

Definition at line 208 of file udfprocs.h.

Referenced by UdfPrepareBuffers().

#define LongAlign  )     GenericAlign((B), 4)
 

Definition at line 153 of file udfprocs.h.

#define LongAlignPtr  )     GenericAlignPtr((P), 4)
 

Definition at line 167 of file udfprocs.h.

Referenced by NtAdjustGroupsToken(), and SeQuerySecurityDescriptorInfo().

#define LongOffset  )     GenericOffset((B), 4)
 

Definition at line 160 of file udfprocs.h.

Referenced by UdfInitializeFcbFromIcbContext(), and UdfUpdateVcbPhase0().

#define LongOffsetPtr  )     GenericOffsetPtr((P), 4)
 

Definition at line 174 of file udfprocs.h.

Referenced by UdfInitializeAllocationContext(), UdfLookupEa(), and UdfSetThreadContext().

#define Max a,
 )     ((a) > (b) ? (a) : (b))
 

Definition at line 62 of file udfprocs.h.

Referenced by UdfInitializeEnumeration(), and UdfUpdateDirNames().

#define Min a,
 )     ((a) < (b) ? (a) : (b))
 

Definition at line 61 of file udfprocs.h.

Referenced by UdfConvertCS0DstringToUnicode(), and UdfLoadSparingTables().

#define PtrOffset BASE,
OFFSET   )     ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
 

Definition at line 105 of file udfprocs.h.

#define QuadAlign  )     GenericAlign((B), 8)
 

Definition at line 155 of file udfprocs.h.

#define QuadAlignPtr  )     GenericAlignPtr((P), 8)
 

Definition at line 169 of file udfprocs.h.

#define QuadOffset  )     GenericOffset((B), 8)
 

Definition at line 162 of file udfprocs.h.

#define QuadOffsetPtr  )     GenericOffsetPtr((P), 8)
 

Definition at line 176 of file udfprocs.h.

#define SectorAlign V,
 ) 
 

Value:

( \ ((((ULONG)(L)) + (((V)->SectorSize) - 1)) & ~(((V)->SectorSize) - 1)) \ )

Definition at line 196 of file udfprocs.h.

#define SectorAlignN SECTORSIZE,
 ) 
 

Value:

( \ ((((ULONG)(L)) + ((SECTORSIZE) - 1)) & ~((SECTORSIZE) - 1)) \ )

Definition at line 192 of file udfprocs.h.

#define SectorOffset V,
 ) 
 

Value:

( \ ((ULONG) (L)) & (((V)->SectorSize) - 1) \ )

Definition at line 232 of file udfprocs.h.

Referenced by MiCreateImageFileMap(), UdfCommonRead(), UdfLookupAllocation(), and UdfPrepareBuffers().

#define SectorsFromBlocks V,
 )     (B)
 

Definition at line 228 of file udfprocs.h.

Referenced by UdfLoadSparingTables(), and UdfLookupPsnOfExtent().

#define SectorsFromBytes V,
 ) 
 

Value:

( \ ((ULONG) (L)) >> ((V)->SectorShift) \ )

Definition at line 216 of file udfprocs.h.

#define SectorSize  )     ((V)->SectorSize)
 

Definition at line 230 of file udfprocs.h.

Referenced by FmtFillFormatBuffer(), FmtIsFatPartition(), FmtVerifySectors(), GetGeometry(), IsUdfsVolume(), LowGetDriveGeometry(), LowGetPartitionGeometry(), LowReadSectors(), LowWriteSectors(), UdfFindVolumeDescriptors(), UdfInitializeVmcb(), UdfLoadSparingTables(), UdfPrepareBuffers(), UdfQueryFsSizeInfo(), UdfRawBufferSizeN(), UdfRawReadSizeN(), UdfReadSectors(), UdfRecognizeVolume(), UdfUpdateVcbPhase0(), xHalExamineMBR(), xHalIoClearPartitionTable(), xHalIoReadPartitionTable(), xHalIoSetPartitionInformation(), xHalIoWritePartitionTable(), and ZapSector().

#define SectorTruncate V,
 ) 
 

Value:

( \ ((ULONG)(L)) & ~(((V)->SectorSize) - 1) \ )

Definition at line 204 of file udfprocs.h.

Referenced by UdfPrepareBuffers().

#define SetFlag Flags,
SingleFlag   ) 
 

Value:

( \ (Flags) |= (SingleFlag) \ )

Definition at line 80 of file udfprocs.h.

#define SwapCopyUchar2 Dst,
Src   ) 
 

Value:

{ \ *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 1); \ *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src)); \ }

Definition at line 330 of file udfprocs.h.

Referenced by UdfConvertCS0DstringToUnicode(), and UdfCS0DstringContainsLegalCharacters().

#define SwapCopyUchar4 Dst,
Src   ) 
 

Value:

{ \ *((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \ *((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \ *((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \ *((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \ }

Definition at line 348 of file udfprocs.h.

Referenced by UdfDetermineVolumeBounding(), and UdfUpdateVolumeSerialNumber().

#define try_leave  )     { S; leave; }
 

Definition at line 436 of file udfprocs.h.

Referenced by UdfAddVmcbMapping(), UdfCommonCreate(), UdfCommonRead(), UdfCommonSetInfo(), UdfDetermineVolumeBounding(), UdfFastLock(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfLookupDirEntryPostProcessing(), UdfLookupMetaVsnOfExtent(), UdfMountVolume(), UdfNonCachedRead(), UdfOpenObjectByFileId(), UdfQueryAlternateNameInfo(), UdfQueryDirectory(), UdfVerifyVolume(), and UdfVmcbVbnToLbn().

#define UdfAcquireAllFiles IC,
 )     UdfAcquireResource( (IC), &(V)->FileResource, FALSE, AcquireExclusive )
 

Definition at line 1524 of file udfprocs.h.

Referenced by UdfPurgeVolume().

#define UdfAcquireFcbExclusive IC,
F,
 )     UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireExclusive )
 

Definition at line 1542 of file udfprocs.h.

Referenced by UdfCommonCleanup(), UdfCommonClosePrivate(), UdfCommonCreate(), UdfFindPrefix(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfOplockRequest(), and UdfTeardownStructures().

#define UdfAcquireFcbShared IC,
F,
 )     UdfAcquireResource( (IC), &(F)->FcbNonpaged->FcbResource, (I), AcquireShared )
 

Definition at line 1545 of file udfprocs.h.

Referenced by UdfOplockRequest().

#define UdfAcquireFileExclusive IC,
 )     UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireExclusive )
 

Definition at line 1530 of file udfprocs.h.

#define UdfAcquireFileShared IC,
 )     UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireShared )
 

Definition at line 1533 of file udfprocs.h.

Referenced by UdfCommonQueryInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfQueryAlternateNameInfo(), and UdfQueryDirectory().

#define UdfAcquireFileSharedStarveExclusive IC,
 )     UdfAcquireResource( (IC), (F)->Resource, FALSE, AcquireSharedStarveExclusive )
 

Definition at line 1536 of file udfprocs.h.

Referenced by UdfCommonRead().

#define UdfAcquireUdfData IC   )     ExAcquireResourceExclusive( &UdfData.DataResource, TRUE )
 

Definition at line 1509 of file udfprocs.h.

Referenced by UdfCommonClose(), UdfFspClose(), UdfInvalidateVolumes(), UdfMountVolume(), UdfPerformVerify(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), and UdfVerifyVolume().

#define UdfAcquireVcbExclusive IC,
V,
 )     UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireExclusive )
 

Definition at line 1515 of file udfprocs.h.

Referenced by UdfCheckForDismount(), UdfCommonCleanup(), UdfCommonCreate(), UdfDismountVolume(), UdfLockVolume(), UdfLockVolumeInternal(), UdfMountVolume(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfUnlockVolume(), and UdfVerifyVolume().

#define UdfAcquireVcbShared IC,
V,
 )     UdfAcquireResource( (IC), &(V)->VcbResource, (I), AcquireShared )
 

Definition at line 1518 of file udfprocs.h.

Referenced by UdfCommonClosePrivate(), UdfCommonCreate(), UdfCommonQueryVolInfo(), UdfFspClose(), and UdfNotifyChangeDirectory().

 
#define UdfAllocateIoContext  ) 
 

Value:

FsRtlAllocatePoolWithTag( UdfNonPagedPool, \ sizeof( UDF_IO_CONTEXT ), \ TAG_IO_CONTEXT )

Definition at line 1701 of file udfprocs.h.

Referenced by UdfCommonRead().

#define UdfCreateIrpContextLite IC   )     ExAllocatePoolWithTag( UdfNonPagedPool, sizeof( IRP_CONTEXT_LITE ), TAG_IRP_CONTEXT_LITE )
 

Definition at line 1684 of file udfprocs.h.

Referenced by UdfQueueClose().

#define UdfDecrementCleanupCounts IC,
 ) 
 

Value:

{ \ ASSERT_LOCKED_VCB( (F)->Vcb ); \ (F)->FcbCleanup -= 1; \ (F)->Vcb->VcbCleanup -= 1; \ }

Definition at line 1756 of file udfprocs.h.

Referenced by UdfCommonCleanup().

#define UdfDecrementReferenceCounts IC,
F,
C,
UC   ) 
 

Value:

{ \ ASSERT_LOCKED_VCB( (F)->Vcb ); \ (F)->FcbReference -= (C); \ (F)->FcbUserReference -= (UC); \ (F)->Vcb->VcbReference -= (C); \ (F)->Vcb->VcbUserReference -= (UC); \ }

Definition at line 1770 of file udfprocs.h.

Referenced by UdfCommonClosePrivate(), UdfCreateInternalStream(), and UdfTeardownStructures().

#define UdfFreeIoContext IO   )     ExFreePool( IO )
 

Definition at line 1706 of file udfprocs.h.

Referenced by UdfCleanupIrpContext(), UdfMultiAsyncCompletionRoutine(), and UdfSingleAsyncCompletionRoutine().

#define UdfFreeIrpContextLite ICL   )     ExFreePool( ICL )
 

Definition at line 1687 of file udfprocs.h.

Referenced by UdfFspClose().

#define UdfIncrementCleanupCounts IC,
 ) 
 

Value:

{ \ ASSERT_LOCKED_VCB( (F)->Vcb ); \ (F)->FcbCleanup += 1; \ (F)->Vcb->VcbCleanup += 1; \ }

Definition at line 1750 of file udfprocs.h.

Referenced by UdfCompleteFcbOpen().

#define UdfIncrementReferenceCounts IC,
F,
C,
UC   ) 
 

Value:

{ \ ASSERT_LOCKED_VCB( (F)->Vcb ); \ (F)->FcbReference += (C); \ (F)->FcbUserReference += (UC); \ (F)->Vcb->VcbReference += (C); \ (F)->Vcb->VcbUserReference += (UC); \ }

Definition at line 1762 of file udfprocs.h.

Referenced by UdfCompleteFcbOpen(), UdfCreateInternalStream(), UdfOpenObjectFromDirContext(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

#define UdfIsFastIoPossible  ) 
 

Value:

((BOOLEAN) \ ((((F)->Vcb->VcbCondition != VcbMounted ) || \ !FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \ \ FastIoIsNotPossible : \ \ ((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \ \ FastIoIsQuestionable : \ \ FastIoIsPossible)) \ )

Definition at line 385 of file udfprocs.h.

Referenced by UdfCommonCleanup(), UdfCommonLockControl(), UdfCompleteFcbOpen(), UdfFastLock(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), and UdfOplockRequest().

#define UdfIsRawDevice IC,
 ) 
 

Value:

( \ ((S) == STATUS_DEVICE_NOT_READY) || \ ((S) == STATUS_NO_MEDIA_IN_DEVICE) \ )

Definition at line 2115 of file udfprocs.h.

Referenced by UdfRecognizeVolume(), and UdfVerifyVcb().

#define UdfLockFcb IC,
 ) 
 

Value:

{ \ PVOID _CurrentThread = PsGetCurrentThread(); \ if (_CurrentThread != (F)->FcbLockThread) { \ ExAcquireFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ ASSERT( (F)->FcbLockCount == 0 ); \ (F)->FcbLockThread = _CurrentThread; \ } \ (F)->FcbLockCount += 1; \ }

Definition at line 1567 of file udfprocs.h.

Referenced by UdfCommonCleanup(), UdfCommonLockControl(), UdfCommonSetInfo(), UdfCompleteFcbOpen(), UdfCreateFileLock(), UdfCreateInternalStream(), UdfDeleteInternalStream(), UdfFastLock(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfInitializeEnumeration(), UdfInitializeFcbFromIcbContext(), UdfLookupMetaVsnOfExtent(), UdfOplockRequest(), UdfQueryDirectory(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

 
#define UdfLockUdfData  ) 
 

Value:

Definition at line 1551 of file udfprocs.h.

Referenced by UdfQueueClose(), and UdfRemoveClose().

#define UdfLockUserBuffer IC,
BL   ) 
 

Value:

{ \ if ((IC)->Irp->MdlAddress == NULL) { \ (VOID) UdfCreateUserMdl( (IC), (BL), TRUE ); \ } \ }

Definition at line 911 of file udfprocs.h.

Referenced by UdfPrePostIrp().

#define UdfLockVcb IC,
 ) 
 

Value:

ExAcquireFastMutex( &(V)->VcbMutex ); \ (V)->VcbLockThread = PsGetCurrentThread()

Definition at line 1559 of file udfprocs.h.

Referenced by UdfCheckForDismount(), UdfCommonCleanup(), UdfCommonClosePrivate(), UdfCompleteFcbOpen(), UdfCreateInternalStream(), UdfDismountVcb(), UdfFindPrefix(), UdfInvalidateVolumes(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfPurgeVolume(), UdfTeardownStructures(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

#define UdfMapUserBuffer IC,
UB   ) 
 

Value:

{ \ *(UB) = ((PVOID) (((IC)->Irp->MdlAddress == NULL) ? \ (IC)->Irp->UserBuffer : \ MmGetSystemAddressForMdlSafe( (IC)->Irp->MdlAddress, NormalPagePriority ))); \ if (NULL == *(UB)) { \ UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES); \ } \ }

Definition at line 902 of file udfprocs.h.

Referenced by UdfCommonRead(), UdfNonCachedRead(), and UdfQueryDirectory().

#define UdfNonPagedPool   NonPagedPool
 

Definition at line 444 of file udfprocs.h.

Referenced by UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfPrepareBuffers(), UdfRecognizeVolume(), and UdfStoreVolumeDescriptorIfPrevailing().

#define UdfNonPagedPoolCacheAligned   NonPagedPoolCacheAligned
 

Definition at line 445 of file udfprocs.h.

#define UdfPagedPool   PagedPool
 

Definition at line 443 of file udfprocs.h.

Referenced by UdfAllocateTable(), UdfCreatePcb(), UdfDetermineVolumeBounding(), UdfEnumerateIndex(), UdfFindDirEntry(), UdfInitializeCrc16(), UdfInitializeEnumeration(), UdfInitializeFcbMcb(), UdfInsertPrefix(), UdfLookupDirEntryPostProcessing(), UdfNormalizeFileNames(), UdfUpdateDirNames(), and UdfUpdateVcbPhase0().

#define UdfReleaseAllFiles IC,
 )     ExReleaseResource( &(V)->FileResource )
 

Definition at line 1527 of file udfprocs.h.

Referenced by UdfPurgeVolume().

#define UdfReleaseFcb IC,
 )     ExReleaseResource( &(F)->FcbNonpaged->FcbResource )
 

Definition at line 1548 of file udfprocs.h.

Referenced by UdfCommonCleanup(), UdfCommonClosePrivate(), UdfCommonCreate(), UdfFindPrefix(), UdfOpenObjectFromDirContext(), UdfOplockComplete(), UdfOplockRequest(), UdfPrePostIrp(), and UdfTeardownStructures().

#define UdfReleaseFile IC,
 )     ExReleaseResource( (F)->Resource )
 

Definition at line 1539 of file udfprocs.h.

Referenced by UdfCommonQueryInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfQueryAlternateNameInfo(), and UdfQueryDirectory().

#define UdfReleaseUdfData IC   )     ExReleaseResource( &UdfData.DataResource )
 

Definition at line 1512 of file udfprocs.h.

Referenced by UdfCommonClose(), UdfFspClose(), UdfInvalidateVolumes(), UdfMountVolume(), UdfPerformVerify(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), and UdfVerifyVolume().

#define UdfReleaseVcb IC,
 )     ExReleaseResource( &(V)->VcbResource )
 

Definition at line 1521 of file udfprocs.h.

Referenced by UdfCheckForDismount(), UdfCommonCleanup(), UdfCommonClosePrivate(), UdfCommonCreate(), UdfCommonQueryVolInfo(), UdfDismountVolume(), UdfFspClose(), UdfLockVolume(), UdfLockVolumeInternal(), UdfMountVolume(), UdfNotifyChangeDirectory(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfUnlockVolume(), and UdfVerifyVolume().

#define UdfUnlockFcb IC,
 ) 
 

Value:

{ \ (F)->FcbLockCount -= 1; \ if ((F)->FcbLockCount == 0) { \ (F)->FcbLockThread = NULL; \ ExReleaseFastMutex( &(F)->FcbNonpaged->FcbMutex ); \ } \ }

Definition at line 1577 of file udfprocs.h.

Referenced by UdfCommonCleanup(), UdfCommonLockControl(), UdfCommonSetInfo(), UdfCompleteFcbOpen(), UdfCreateFileLock(), UdfCreateInternalStream(), UdfDeleteInternalStream(), UdfFastLock(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfInitializeEnumeration(), UdfInitializeFcbFromIcbContext(), UdfLookupMetaVsnOfExtent(), UdfOplockRequest(), UdfQueryDirectory(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

 
#define UdfUnlockUdfData  ) 
 

Value:

UdfData.UdfDataLockThread = NULL; \ ExReleaseFastMutex( &UdfData.UdfDataMutex )

Definition at line 1555 of file udfprocs.h.

Referenced by UdfQueueClose(), and UdfRemoveClose().

#define UdfUnlockVcb IC,
 ) 
 

Value:

(V)->VcbLockThread = NULL; \ ExReleaseFastMutex( &(V)->VcbMutex )

Definition at line 1563 of file udfprocs.h.

Referenced by UdfCheckForDismount(), UdfCommonCleanup(), UdfCommonClosePrivate(), UdfCompleteFcbOpen(), UdfCreateInternalStream(), UdfDismountVcb(), UdfFindPrefix(), UdfInvalidateVolumes(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfPurgeVolume(), UdfTeardownStructures(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

#define UdfUnpinData IC,
 )     if (*(B) != NULL) { CcUnpinData( *(B) ); *(B) = NULL; }
 

Definition at line 838 of file udfprocs.h.

Referenced by UdfCleanupDirContext(), UdfLookupDirEntryPostProcessing(), UdfLookupInitialDirEntry(), UdfLookupPsnOfExtent(), and UdfUpdateVcbPhase0().

#define UdfUnpinView IC,
 )     if (((V)->Bcb) != NULL) { CcUnpinData( ((V)->Bcb) ); ((V)->Bcb) = NULL; ((V)->View) = NULL; }
 

Definition at line 828 of file udfprocs.h.

Referenced by UdfCleanupIcbContext(), UdfLookupActiveIcb(), and UdfMapMetadataView().

#define WordAlign  )     GenericAlign((B), 2)
 

Definition at line 151 of file udfprocs.h.

#define WordAlignPtr  )     GenericAlignPtr((P), 2)
 

Definition at line 165 of file udfprocs.h.

#define WordOffset  )     GenericOffset((B), 2)
 

Definition at line 158 of file udfprocs.h.

#define WordOffsetPtr  )     GenericOffsetPtr((P), 2)
 

Definition at line 172 of file udfprocs.h.


Typedef Documentation

typedef enum _TYPE_OF_ACQUIRE * PTYPE_OF_ACQUIRE
 

typedef enum _TYPE_OF_OPEN * PTYPE_OF_OPEN
 

typedef union _UCHAR1 * PUCHAR1
 

typedef union _UCHAR2 * PUCHAR2
 

typedef union _UCHAR4 * PUCHAR4
 

typedef union _USHORT2 * PUSHORT2
 

typedef enum _TYPE_OF_ACQUIRE TYPE_OF_ACQUIRE
 

Referenced by UdfAcquireResource().

typedef enum _TYPE_OF_OPEN TYPE_OF_OPEN
 

Referenced by UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonLockControl(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfDecodeFileObject(), UdfFastDecodeFileObject(), UdfFastLock(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfIsVolumeDirty(), UdfOpenObjectByFileId(), and UdfOpenObjectFromDirContext().

typedef union _UCHAR1 UCHAR1
 

typedef union _UCHAR2 UCHAR2
 

typedef union _UCHAR4 UCHAR4
 

typedef union _USHORT2 USHORT2
 


Enumeration Type Documentation

enum _TYPE_OF_ACQUIRE
 

Enumeration values:
AcquireExclusive 
AcquireShared 
AcquireSharedStarveExclusive 

Definition at line 1381 of file udfprocs.h.

enum _TYPE_OF_OPEN
 

Enumeration values:
UnopenedFileObject 
StreamFileOpen 
UserVolumeOpen 
UserDirectoryOpen 
UserFileOpen 
BeyondValidType 

Definition at line 487 of file udfprocs.h.

00487 { 00488 00489 UnopenedFileObject = 0, 00490 StreamFileOpen, 00491 UserVolumeOpen, 00492 UserDirectoryOpen, 00493 UserFileOpen, 00494 BeyondValidType 00495 00496 } TYPE_OF_OPEN, *PTYPE_OF_OPEN;


Function Documentation

BOOLEAN UdfAcquireForCache IN PFCB  Fcb,
IN BOOLEAN  Wait
 

Definition at line 136 of file resrcsup.c.

References ASSERT, ExAcquireResourceShared, FSRTL_CACHE_TOP_LEVEL_IRP, IoGetTopLevelIrp(), IoSetTopLevelIrp(), NULL, and PAGED_CODE.

Referenced by UdfInitializeGlobalData().

00143 : 00144 00145 The address of this routine is specified when creating a CacheMap for 00146 a file. It is subsequently called by the Lazy Writer for synchronization. 00147 00148 Arguments: 00149 00150 Fcb - The pointer supplied as context to the cache initialization 00151 routine. 00152 00153 Wait - TRUE if the caller is willing to block. 00154 00155 Return Value: 00156 00157 None 00158 00159 --*/ 00160 00161 { 00162 PAGED_CODE(); 00163 00164 ASSERT(IoGetTopLevelIrp() == NULL); 00165 IoSetTopLevelIrp((PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); 00166 00167 return ExAcquireResourceShared( Fcb->Resource, Wait ); 00168 }

VOID UdfAcquireForCreateSection IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 267 of file resrcsup.c.

References ExAcquireResourceExclusive, PAGED_CODE, and TRUE.

Referenced by UdfInitializeGlobalData().

00273 : 00274 00275 This is the callback routine for MM to use to acquire the file exclusively. 00276 00277 Arguments: 00278 00279 FileObject - File object for a Udffs stream. 00280 00281 Return Value: 00282 00283 None 00284 00285 --*/ 00286 00287 { 00288 PAGED_CODE(); 00289 00290 // 00291 // Get the file resource exclusively. 00292 // 00293 00294 ExAcquireResourceExclusive( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource, 00295 TRUE ); 00296 00297 return; 00298 }

BOOLEAN UdfAcquireResource IN PIRP_CONTEXT  IrpContext,
IN PERESOURCE  Resource,
IN BOOLEAN  IgnoreWait,
IN TYPE_OF_ACQUIRE  Type
 

Definition at line 47 of file resrcsup.c.

References AcquireExclusive, AcquireShared, AcquireSharedStarveExclusive, ASSERT, ExAcquireResourceExclusive, ExAcquireResourceShared, ExAcquireSharedStarveExclusive(), FALSE, FlagOn, IRP_CONTEXT_FLAG_WAIT, PAGED_CODE, Resource, TRUE, TYPE_OF_ACQUIRE, and UdfRaiseStatus().

00056 : 00057 00058 This is the single routine used to acquire file system resources. It 00059 looks at the IgnoreWait flag to determine whether to try to acquire the 00060 resource without waiting. Returning TRUE/FALSE to indicate success or 00061 failure. Otherwise it is driven by the WAIT flag in the IrpContext and 00062 will raise CANT_WAIT on a failure. 00063 00064 Arguments: 00065 00066 Resource - This is the resource to try and acquire. 00067 00068 IgnoreWait - If TRUE then this routine will not wait to acquire the 00069 resource and will return a boolean indicating whether the resource was 00070 acquired. Otherwise we use the flag in the IrpContext and raise 00071 if the resource is not acquired. 00072 00073 Type - Indicates how we should try to get the resource. 00074 00075 Return Value: 00076 00077 BOOLEAN - TRUE if the resource is acquired. FALSE if not acquired and 00078 IgnoreWait is specified. Otherwise we raise CANT_WAIT. 00079 00080 --*/ 00081 00082 { 00083 BOOLEAN Wait = FALSE; 00084 BOOLEAN Acquired; 00085 PAGED_CODE(); 00086 00087 // 00088 // We look first at the IgnoreWait flag, next at the flag in the Irp 00089 // Context to decide how to acquire this resource. 00090 // 00091 00092 if (!IgnoreWait && FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00093 00094 Wait = TRUE; 00095 } 00096 00097 // 00098 // Attempt to acquire the resource either shared or exclusively. 00099 // 00100 00101 switch (Type) { 00102 case AcquireExclusive: 00103 00104 Acquired = ExAcquireResourceExclusive( Resource, Wait ); 00105 break; 00106 00107 case AcquireShared: 00108 00109 Acquired = ExAcquireResourceShared( Resource, Wait ); 00110 break; 00111 00112 case AcquireSharedStarveExclusive: 00113 00114 Acquired = ExAcquireSharedStarveExclusive( Resource, Wait ); 00115 break; 00116 00117 default: 00118 ASSERT( FALSE ); 00119 } 00120 00121 // 00122 // If not acquired and the user didn't specifiy IgnoreWait then 00123 // raise CANT_WAIT. 00124 // 00125 00126 if (!Acquired && !IgnoreWait) { 00127 00128 UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT ); 00129 } 00130 00131 return Acquired; 00132 }

VOID UdfAddToPcb IN PPCB  Pcb,
IN PNSR_PART  PartitionDescriptor
 

Definition at line 724 of file allocsup.c.

References ASSERT, ASSERT_PCB, Dbg, DebugTrace, FALSE, PAGED_CODE, Physical, PNSR_PART, PNSR_VD_GENERIC, UdfStoreVolumeDescriptorIfPrevailing(), USHORT, and Virtual.

Referenced by UdfFindVolumeDescriptors().

00731 : 00732 00733 This routine possibly adds a partition descriptor into a Pcb if it 00734 turns out to be of higher precendence than a descriptor already 00735 present. Used in building a Pcb already initialized in preperation 00736 for UdfCompletePcb. 00737 00738 Arguments: 00739 00740 Vcb - Vcb of the volume the Pcb describes 00741 00742 Pcb - Pcb being filled in 00743 00744 Return Value: 00745 00746 None. An old partition descriptor may be returned in the input field. 00747 00748 --*/ 00749 00750 { 00751 USHORT Reference; 00752 00753 PAGED_CODE(); 00754 00755 // 00756 // Check inputs 00757 // 00758 00759 ASSERT_PCB( Pcb ); 00760 ASSERT( PartitionDescriptor ); 00761 00762 for (Reference = 0; 00763 Reference < Pcb->Partitions; 00764 Reference++) { 00765 00766 DebugTrace(( 0, Dbg, "UdfAddToPcb, considering partition reference %d (type %d)\n", (ULONG)Reference, Pcb->Partition[Reference].Type)); 00767 00768 switch (Pcb->Partition[Reference].Type) { 00769 00770 case Physical: 00771 00772 // 00773 // Now possibly store this descriptor in the Pcb if it is 00774 // the partition number for this partition reference. 00775 // 00776 00777 if (Pcb->Partition[Reference].Physical.PartitionNumber == PartitionDescriptor->Number) { 00778 00779 // 00780 // It seems to be legal (if questionable) for multiple partition maps to reference 00781 // the same partition descriptor. So we make a copy of the descriptor for each 00782 // referencing partitionmap to make life easier when it comes to freeing it. 00783 // 00784 00785 UdfStoreVolumeDescriptorIfPrevailing( (PNSR_VD_GENERIC *) &Pcb->Partition[Reference].Physical.PartitionDescriptor, 00786 (PNSR_VD_GENERIC) PartitionDescriptor ); 00787 } 00788 00789 break; 00790 00791 case Virtual: 00792 break; 00793 00794 default: 00795 00796 ASSERT(FALSE); 00797 break; 00798 } 00799 } 00800 }

BOOLEAN UdfAddVmcbMapping IN PVMCB  Vmcb,
IN LBN  Lbn,
IN ULONG  SectorCount,
IN BOOLEAN  ExactEnd,
OUT PVBN  Vbn,
OUT PULONG  AlignedSectorCount
 

Definition at line 637 of file vmcbsup.c.

References ASSERT, Dbg, DebugTrace, DebugUnwind, Executive, FALSE, FsRtlAddMcbEntry(), FsRtlLookupLastMcbEntry(), FsRtlRemoveMcbEntry(), KeReleaseMutex(), KernelMode, KeWaitForSingleObject(), LBN, NULL, PageAlign, PAGED_CODE, TRUE, try_leave, UdfRemoveVmcbMapping(), UdfVmcbLookupMcbEntry(), VBN, and VOID().

Referenced by UdfLookupMetaVsnOfExtent().

00648 : 00649 00650 This routine adds a new LBN to VBN mapping to the VMCB structure. When 00651 a new LBN is added to the structure it does it only on page aligned 00652 boundaries. 00653 00654 If pool is not available to store the information this routine will 00655 raise a status value indicating insufficient resources. 00656 00657 Arguments: 00658 00659 Vmcb - Supplies the VMCB being updated. 00660 00661 Lbn - Supplies the starting LBN to add to VMCB. 00662 00663 SectorCount - Supplies the number of Sectors in the run 00664 00665 ExactEnd - Indicates that instead of aligning to map sectors beyond 00666 the end of the request, use a hole. Implies trying to look at 00667 these sectors could be undesireable. 00668 00669 Vbn - Receives the assigned VBN 00670 00671 AlignedSectorCount - Receives the actual sector count created in the 00672 Vmcb for page alignment purposes. Vbn+AlignedSectorCount-1 == LastVbn. 00673 00674 Return Value: 00675 00676 BOOLEAN - TRUE if this is a new mapping and FALSE if the mapping 00677 for the LBN already exists. If it already exists then the 00678 sector count for this new addition must already be in the 00679 VMCB structure 00680 00681 --*/ 00682 00683 { 00684 00685 BOOLEAN Result; 00686 00687 BOOLEAN VbnMcbAdded; 00688 BOOLEAN LbnMcbAdded; 00689 00690 LBN LocalLbn; 00691 VBN LocalVbn; 00692 ULONG LocalCount; 00693 00694 PAGED_CODE(); 00695 00696 DebugTrace(( +1, Dbg, "UdfAddVmcbMapping, Lbn = %08x\n", Lbn )); 00697 DebugTrace(( 0, Dbg, " SectorCount = %08x\n", SectorCount )); 00698 00699 ASSERT( SectorCount != 0 ); 00700 00701 VbnMcbAdded = FALSE; 00702 LbnMcbAdded = FALSE; 00703 00704 // 00705 // Now grab the mutex for the vmcb 00706 // 00707 00708 (VOID)KeWaitForSingleObject( &Vmcb->Mutex, 00709 Executive, 00710 KernelMode, 00711 FALSE, 00712 (PLARGE_INTEGER) NULL ); 00713 00714 try { 00715 00716 // 00717 // Check if the Lbn is already mapped, which means we find an entry 00718 // with a non zero mapping Vbn value. 00719 // 00720 00721 if (UdfVmcbLookupMcbEntry( &Vmcb->LbnIndexed, 00722 Lbn, 00723 Vbn, 00724 &LocalCount, 00725 NULL )) { 00726 00727 // 00728 // It is already mapped so now the sector count must not exceed 00729 // the count already in the run 00730 // 00731 00732 if (SectorCount <= LocalCount) { 00733 00734 try_leave( Result = FALSE ); 00735 } 00736 } 00737 00738 // 00739 // At this point, we did not find a full existing mapping for the 00740 // Lbn and count. But there might be some overlapping runs that we'll 00741 // need to now remove from the vmcb structure. So for each Lbn in 00742 // the range we're after, check to see if it is mapped and remove the 00743 // mapping. We only need to do this test if the sector count is less 00744 // than or equal to a page size. Because those are the only 00745 // structures that we know we'll try an remove/overwrite. 00746 // 00747 00748 if (SectorCount <= PageAlign(Vmcb, 1)) { 00749 00750 if (UdfVmcbLookupMcbEntry( &Vmcb->LbnIndexed, 00751 Lbn, 00752 Vbn, 00753 &LocalCount, 00754 NULL )) { 00755 00756 UdfRemoveVmcbMapping( Vmcb, *Vbn, PageAlign(Vmcb, 1) ); 00757 } 00758 } 00759 00760 // 00761 // We need to add this new run at the end of the Vbns. To do this we 00762 // need to look up the last mcb entry or use a vbn for the second 00763 // page, if the mcb is empty. We'll also special case the situation 00764 // where the last lbn of the mapping and the mapping we're adding 00765 // simply flow into each other in which case we'll not bother bumping 00766 // the vbn to a page alignment 00767 // 00768 00769 if (FsRtlLookupLastMcbEntry( &Vmcb->VbnIndexed, &LocalVbn, &LocalLbn )) { 00770 00771 if (LocalLbn + 1 == Lbn) { 00772 00773 LocalVbn = LocalVbn + 1; 00774 LocalLbn = LocalLbn + 1; 00775 00776 } else { 00777 00778 // 00779 // Get the next available Vbn Page, and calculate the 00780 // Lbn for the page containing the Lbn 00781 // 00782 00783 LocalVbn = PageAlign( Vmcb, LocalVbn + 1 ); 00784 LocalLbn = PageAlign( Vmcb, Lbn + 1 ) - PageAlign( Vmcb, 1 ); 00785 } 00786 00787 } else { 00788 00789 // 00790 // Get the first available Vbn page, and calculate the 00791 // Lbn for the page containing the Lbn. 00792 // 00793 00794 00795 LocalVbn = 0; 00796 LocalLbn = PageAlign( Vmcb, Lbn + 1 ) - PageAlign( Vmcb, 1 ); 00797 } 00798 00799 // 00800 // Calculate the number of sectors that we need to map to keep 00801 // everything on a page granularity. 00802 // 00803 00804 LocalCount = PageAlign( Vmcb, SectorCount + (Lbn - LocalLbn) ); 00805 00806 // 00807 // See if we should use a hole to map the alignment at the end of the request. 00808 // 00809 00810 if (ExactEnd && Lbn + SectorCount < LocalLbn + LocalCount) { 00811 00812 LocalCount = SectorCount + (Lbn - LocalLbn); 00813 } 00814 00815 // 00816 // Add the double mapping 00817 // 00818 00819 FsRtlAddMcbEntry( &Vmcb->VbnIndexed, 00820 LocalVbn, 00821 LocalLbn, 00822 LocalCount ); 00823 00824 VbnMcbAdded = TRUE; 00825 00826 FsRtlAddMcbEntry( &Vmcb->LbnIndexed, 00827 LocalLbn, 00828 LocalVbn, 00829 LocalCount ); 00830 00831 LbnMcbAdded = TRUE; 00832 00833 *Vbn = LocalVbn + (Lbn - LocalLbn); 00834 *AlignedSectorCount = LocalCount - (Lbn - LocalLbn); 00835 00836 try_leave( Result = TRUE ); 00837 00838 } finally { 00839 00840 // 00841 // If this is an abnormal termination then clean up any mcb's that we 00842 // might have modified. 00843 // 00844 00845 if (AbnormalTermination()) { 00846 00847 if (VbnMcbAdded) { FsRtlRemoveMcbEntry( &Vmcb->VbnIndexed, LocalVbn, LocalCount ); } 00848 if (LbnMcbAdded) { FsRtlRemoveMcbEntry( &Vmcb->LbnIndexed, LocalLbn, LocalCount ); } 00849 } 00850 00851 (VOID) KeReleaseMutex( &Vmcb->Mutex, FALSE ); 00852 00853 DebugUnwind("UdfAddVmcbMapping"); 00854 DebugTrace(( 0, Dbg, " LocalVbn = %08x\n", LocalVbn )); 00855 DebugTrace(( 0, Dbg, " LocalLbn = %08x\n", LocalLbn )); 00856 DebugTrace(( 0, Dbg, " LocalCount = %08x\n", LocalCount )); 00857 DebugTrace(( 0, Dbg, " *Vbn = %08x\n", *Vbn )); 00858 DebugTrace(( 0, Dbg, " *AlignedSectorCount = %08x\n", *AlignedSectorCount )); 00859 DebugTrace((-1, Dbg, "UdfAddVmcbMapping -> %08x\n", Result )); 00860 } 00861 00862 return Result; 00863 }

BOOLEAN UdfCandidateShortName IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  Name
 

Definition at line 301 of file namesup.c.

References ASSERT, ASSERT_IRP_CONTEXT, BYTE_COUNT_8_DOT_3, CRC_MARK, DOS_CRC_LEN, FALSE, Index, Name, PAGED_CODE, PERIOD, and TRUE.

Referenced by UdfCommonCreate().

00308 : 00309 00310 This routine is called to determine if the input name could be a generated 00311 short name. 00312 00313 Arguments: 00314 00315 Name - Pointer to the name to stare at. 00316 00317 Return Value: 00318 00319 BOOLEAN True if it is possible that this is a shortname, False otherwise. 00320 00321 --*/ 00322 00323 { 00324 ULONG Index, SubIndex; 00325 BOOLEAN LooksShort = FALSE; 00326 00327 PAGED_CODE(); 00328 00329 // 00330 // Check inputs. 00331 // 00332 00333 ASSERT_IRP_CONTEXT( IrpContext ); 00334 00335 // 00336 // The length can't be larger than an 8.3 name and must be 00337 // at least as big as the uniqifier stamp. 00338 // 00339 00340 ASSERT( Name->Length != 0 ); 00341 00342 if (Name->Length > BYTE_COUNT_8_DOT_3 || 00343 Name->Length < DOS_CRC_LEN * sizeof(WCHAR)) { 00344 00345 return FALSE; 00346 } 00347 00348 // 00349 // Walk across the name looking for the uniquifier stamp. The stamp 00350 // is of the form #<hex><hex><hex> so if we can stop before the end 00351 // of the full name. 00352 // 00353 00354 for ( Index = 0; 00355 Index <= (Name->Length / sizeof(WCHAR)) - DOS_CRC_LEN; 00356 Index++ ) { 00357 00358 // 00359 // Is the current character the stamp UDF uses to offset the stamp? 00360 // 00361 00362 if (Name->Buffer[Index] == CRC_MARK) { 00363 00364 // 00365 // We may potentially have just a CRC at the end 00366 // of the name OR have a period following. If we 00367 // do, it is reasonable to think the name may be 00368 // a generated shorty. 00369 // 00370 // #123 (a very special case - orignal name was ".") 00371 // FOO#123 00372 // FOO#123.TXT 00373 // 00374 00375 if (Index == (Name->Length / sizeof(WCHAR)) - DOS_CRC_LEN || 00376 Name->Buffer[Index + DOS_CRC_LEN] == PERIOD) { 00377 00378 LooksShort = TRUE; 00379 break; 00380 } 00381 } 00382 } 00383 00384 return LooksShort; 00385 }

BOOLEAN UdfCheckForDismount IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  Force
 

Definition at line 236 of file udfs/verfysup.c.

References ASSERT_EXCLUSIVE_UDFDATA, ASSERT_IRP_CONTEXT, ASSERT_VCB, FALSE, IoAcquireVpbSpinLock(), IoReleaseVpbSpinLock(), TRUE, UdfAcquireVcbExclusive, UdfDeleteVcb(), UdfDismountVcb(), UdfFspClose(), UdfLockVcb, UdfReleaseVcb, UdfUnlockVcb, and VcbDismountInProgress.

Referenced by UdfCommonClose(), UdfFspClose(), UdfInvalidateVolumes(), UdfPerformVerify(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfScanForDismountedVcb(), and UdfVerifyVolume().

00244 : 00245 00246 This routine is called to check if a volume is ready for dismount. This 00247 occurs when only file system references are left on the volume. 00248 00249 If the dismount is not currently underway and the user reference count 00250 has gone to zero then we can begin the dismount. 00251 00252 If the dismount is in progress and there are no references left on the 00253 volume (we check the Vpb for outstanding references as well to catch 00254 any create calls dispatched to the file system) then we can delete 00255 the Vcb. 00256 00257 Arguments: 00258 00259 Vcb - Vcb for the volume to try to dismount. 00260 00261 Force - Whether we will force this volume to be dismounted. 00262 00263 Return Value: 00264 00265 BOOLEAN - True if the Vcb was not gone by the time this function finished, 00266 False if it was deleted. 00267 00268 This is only a trustworthy indication to the caller if it had the vcb 00269 exclusive itself. 00270 00271 --*/ 00272 00273 { 00274 BOOLEAN UnlockVcb = TRUE; 00275 BOOLEAN VcbPresent = TRUE; 00276 KIRQL SavedIrql; 00277 00278 ASSERT_IRP_CONTEXT( IrpContext ); 00279 ASSERT_VCB( Vcb ); 00280 00281 ASSERT_EXCLUSIVE_UDFDATA; 00282 00283 // 00284 // Acquire and lock this Vcb to check the dismount state. 00285 // 00286 00287 UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE ); 00288 00289 // 00290 // Lets get rid of any pending closes for this volume. 00291 // 00292 00293 UdfFspClose( Vcb ); 00294 00295 UdfLockVcb( IrpContext, Vcb ); 00296 00297 // 00298 // If the dismount is not already underway then check if the 00299 // user reference count has gone to zero or we are being forced 00300 // to disconnect. If so start the teardown on the Vcb. 00301 // 00302 00303 if (Vcb->VcbCondition != VcbDismountInProgress) { 00304 00305 if (Vcb->VcbUserReference <= Vcb->VcbResidualUserReference || Force) { 00306 00307 UdfUnlockVcb( IrpContext, Vcb ); 00308 UnlockVcb = FALSE; 00309 VcbPresent = UdfDismountVcb( IrpContext, Vcb ); 00310 } 00311 00312 // 00313 // If the teardown is underway and there are absolutely no references 00314 // remaining then delete the Vcb. References here include the 00315 // references in the Vcb and Vpb. 00316 // 00317 00318 } else if (Vcb->VcbReference == 0) { 00319 00320 IoAcquireVpbSpinLock( &SavedIrql ); 00321 00322 // 00323 // If there are no file objects and no reference counts in the 00324 // Vpb we can delete the Vcb. Don't forget that we have the 00325 // last reference in the Vpb. 00326 // 00327 00328 if (Vcb->Vpb->ReferenceCount == 1) { 00329 00330 IoReleaseVpbSpinLock( SavedIrql ); 00331 UdfUnlockVcb( IrpContext, Vcb ); 00332 UnlockVcb = FALSE; 00333 UdfDeleteVcb( IrpContext, Vcb ); 00334 VcbPresent = FALSE; 00335 00336 } else { 00337 00338 IoReleaseVpbSpinLock( SavedIrql ); 00339 } 00340 } 00341 00342 // 00343 // Unlock the Vcb if still held. 00344 // 00345 00346 if (UnlockVcb) { 00347 00348 UdfUnlockVcb( IrpContext, Vcb ); 00349 } 00350 00351 // 00352 // Release any resources still acquired. 00353 // 00354 00355 if (VcbPresent) { 00356 00357 UdfReleaseVcb( IrpContext, Vcb ); 00358 } 00359 00360 return VcbPresent; 00361 }

BOOLEAN UdfCheckLegalCS0Dstring PIRP_CONTEXT  IrpContext,
PUCHAR  Dstring,
UCHAR Length  OPTIONAL,
UCHAR FieldLength  OPTIONAL,
BOOLEAN  ReturnOnError
 

Definition at line 819 of file namesup.c.

References ASSERT, ASSERT_IRP_CONTEXT, Dbg, DebugTrace, FALSE, FlagOn, TRUE, and UdfRaiseStatus().

Referenced by UdfUpdateDirNames(), and UdfUpdateVolumeLabel().

00829 : 00830 00831 This routine inspects a CS0 Dstring for conformance. 00832 00833 Arguments: 00834 00835 Dstring - a dstring to check 00836 00837 Length - length of the dstring. If unspecified, we assume that the characters come 00838 from a proper 1/7.2.12 dstring that specifies length in the last character of the 00839 field. 00840 00841 FieldLength - length of the dstring field. If unspecified, we assume that the characters 00842 come from an uncounted length of CS0 characters and that the Length parameter is 00843 specified. 00844 00845 ReturnOnError - whether to return or raise on a discovered error 00846 00847 Return Value: 00848 00849 None. Raised status if corruption is found. 00850 00851 --*/ 00852 00853 { 00854 UCHAR NameLength; 00855 00856 // 00857 // Check input. 00858 // 00859 00860 ASSERT_IRP_CONTEXT( IrpContext ); 00861 00862 // 00863 // If the length is unspecified, this is a real 1/7.2.12 dstring and the length is in 00864 // the last character of the field. 00865 // 00866 00867 ASSERT( Length || FieldLength ); 00868 00869 if (Length) { 00870 00871 NameLength = FieldLength = Length; 00872 00873 } else { 00874 00875 NameLength = *(Dstring + FieldLength - 1); 00876 } 00877 00878 DebugTrace(( +1, Dbg, 00879 "UdfCheckLegalCS0Dstring, Dstring %08x Length %02x FieldLength %02x (NameLength %02x)\n", 00880 Dstring, 00881 Length, 00882 FieldLength, 00883 NameLength )); 00884 00885 // 00886 // The string must be "compressed" in 8bit or 16bit chunks. If it 00887 // is in 16bit chunks, we better have an integral number of them - 00888 // remember we have the compression ID, so the length will be odd. 00889 // 00890 00891 if ((NameLength <= 1 && 00892 DebugTrace(( 0, Dbg, 00893 "UdfCheckLegalCS0Dstring, NameLength is too small!\n" ))) || 00894 00895 (NameLength > FieldLength && 00896 DebugTrace(( 0, Dbg, 00897 "UdfCheckLegalCS0Dstring, NameLength is bigger than the field itself!\n" ))) || 00898 00899 ((*Dstring != 8 && *Dstring != 16) && 00900 DebugTrace(( 0, Dbg, 00901 "UdfCheckLegalCS0Dstring, claims encoding %02x, unknown! (not 0x8 or 0x10)\n", 00902 *Dstring ))) || 00903 00904 ((*Dstring == 16 && !FlagOn( NameLength, 1)) && 00905 DebugTrace(( 0, Dbg, 00906 "UdfCheckLegalCS0Dstring, NameLength not odd, encoding 0x10!\n" )))) { 00907 00908 if (ReturnOnError) { 00909 00910 DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> FALSE\n" )); 00911 00912 return FALSE; 00913 } 00914 00915 DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> raised status\n" )); 00916 00917 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 00918 } 00919 00920 DebugTrace(( -1, Dbg, "UdfCheckLegalCS0Dstring -> TRUE\n" )); 00921 00922 return TRUE; 00923 }

VOID UdfCleanupDirContext IN PIRP_CONTEXT  IrpContext,
IN PDIR_ENUM_CONTEXT  DirContext
 

Definition at line 99 of file dirsup.c.

References ASSERT_IRP_CONTEXT, DIR_CONTEXT_FLAG_FID_BUFFERED, FlagOn, PAGED_CODE, UdfFreePool(), and UdfUnpinData.

Referenced by UdfCleanupCompoundDirContext(), UdfCommonCreate(), UdfInitializeEnumeration(), and UdfQueryAlternateNameInfo().

00106 : 00107 00108 This routine cleans up a directory enumeration context for reuse. 00109 00110 Arguments: 00111 00112 DirContext - a context to clean. 00113 00114 Return Value: 00115 00116 None. 00117 00118 --*/ 00119 00120 { 00121 PAGED_CODE(); 00122 00123 // 00124 // Check input. 00125 // 00126 00127 ASSERT_IRP_CONTEXT( IrpContext ); 00128 00129 // 00130 // Dump the allocation we store the triple of names in. 00131 // 00132 00133 UdfFreePool( &DirContext->NameBuffer ); 00134 00135 // 00136 // And the short name. 00137 // 00138 00139 UdfFreePool( &DirContext->ShortObjectName.Buffer ); 00140 00141 // 00142 // Unpin the view. 00143 // 00144 00145 UdfUnpinData( IrpContext, &DirContext->Bcb ); 00146 00147 // 00148 // Free a buffered Fid that may remain. 00149 // 00150 00151 if (FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED )) { 00152 00153 UdfFreePool( &DirContext->Fid ); 00154 } 00155 00156 // 00157 // Zero everything else out. 00158 // 00159 00160 RtlZeroMemory( DirContext, sizeof( DIR_ENUM_CONTEXT ) ); 00161 }

VOID UdfCleanupIcbContext IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext
 

Definition at line 3183 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT, PAGED_CODE, and UdfUnpinView.

Referenced by UdfCleanupCompoundDirContext(), UdfLookupFileEntryInEnumeration(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

03190 : 03191 03192 This routine cleans an Icb search context for reuse/deletion. 03193 03194 Arguments: 03195 03196 IcbContext - context to clean 03197 03198 Return Value: 03199 03200 None. 03201 03202 --*/ 03203 03204 { 03205 PAGED_CODE(); 03206 03207 // 03208 // Check inputs 03209 // 03210 03211 ASSERT_IRP_CONTEXT( IrpContext ); 03212 03213 UdfUnpinView( IrpContext, &IcbContext->Active ); 03214 UdfUnpinView( IrpContext, &IcbContext->Current ); 03215 03216 RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 03217 }

VOID UdfCleanupIrpContext IN PIRP_CONTEXT  IrpContext,
IN BOOLEAN  Post
 

Definition at line 1437 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT, ClearFlag, ExFreeToNPagedLookasideList(), FlagOn, IRP_CONTEXT_FLAG_ALLOC_IO, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FLAG_ON_STACK, IRP_CONTEXT_FLAGS_CLEAR_ON_POST, IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY, NULL, PAGED_CODE, UdfFreeIoContext, UdfIrpContextLookasideList, and UdfRestoreThreadContext().

Referenced by UdfCompleteRequest(), UdfFsdDispatch(), UdfFspDispatch(), UdfPrePostIrp(), and UdfQueueClose().

01444 : 01445 01446 This routine is called to cleanup and possibly deallocate the Irp Context. 01447 If the request is being posted or this Irp Context is possibly on the 01448 stack then we only cleanup any auxilary structures. 01449 01450 Arguments: 01451 01452 Post - TRUE if we are posting this request, FALSE if we are deleting 01453 or retrying this in the current thread. 01454 01455 Return Value: 01456 01457 None. 01458 01459 --*/ 01460 01461 { 01462 PAGED_CODE(); 01463 01464 ASSERT_IRP_CONTEXT( IrpContext ); 01465 01466 // 01467 // If we aren't doing more processing then deallocate this as appropriate. 01468 // 01469 01470 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING)) { 01471 01472 // 01473 // If this context is the top level UDFS context then we need to 01474 // restore the top level thread context. 01475 // 01476 01477 if (IrpContext->ThreadContext != NULL) { 01478 01479 UdfRestoreThreadContext( IrpContext ); 01480 } 01481 01482 // 01483 // Deallocate the Io context if allocated. 01484 // 01485 01486 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) { 01487 01488 UdfFreeIoContext( IrpContext->IoContext ); 01489 } 01490 01491 // 01492 // Deallocate the IrpContext if not from the stack. 01493 // 01494 01495 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ON_STACK )) { 01496 01497 ExFreeToNPagedLookasideList( &UdfIrpContextLookasideList, IrpContext ); 01498 } 01499 01500 // 01501 // Clear the appropriate flags. 01502 // 01503 01504 } else if (Post) { 01505 01506 // 01507 // If this context is the top level UDFS context then we need to 01508 // restore the top level thread context. 01509 // 01510 01511 if (IrpContext->ThreadContext != NULL) { 01512 01513 UdfRestoreThreadContext( IrpContext ); 01514 } 01515 01516 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_POST ); 01517 01518 } else { 01519 01520 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAGS_CLEAR_ON_RETRY ); 01521 } 01522 01523 return; 01524 }

NTSTATUS UdfCommonCleanup IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 42 of file udfs/cleanup.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, CcUninitializeCacheMap(), ClearFlag, Dbg, DebugTrace, _VCB::DirNotifyList, FALSE, _FILE_OBJECT::Flags, FO_CLEANUP_COMPLETE, FSRTL_VOLUME_UNLOCK, FsRtlCheckOplock(), FsRtlFastUnlockAll(), FsRtlNotifyCleanup(), FsRtlNotifyVolumeEvent(), IoGetCurrentIrpStackLocation, IoGetRequestorProcess(), IoRemoveShareAccess(), Irp, _VCB::NotifySync, NULL, PAGED_CODE, PCCB, SetFlag, _FCB::ShareAccess, StreamFileOpen, TRUE, TYPE_OF_OPEN, UdfAcquireFcbExclusive, UdfAcquireVcbExclusive, UdfBugCheck, UdfCompleteRequest(), UdfDecodeFileObject(), UdfDecrementCleanupCounts, UdfIsFastIoPossible, UdfLockFcb, UdfLockVcb, UdfPurgeVolume(), UdfReleaseFcb, UdfReleaseVcb, UdfUnlockFcb, UdfUnlockVcb, UserDirectoryOpen, UserFileOpen, UserVolumeOpen, _FCB::Vcb, VCB_STATE_LOCKED, _VCB::VcbCleanup, _VCB::VcbCondition, VcbNotMounted, _VCB::VcbState, and _VCB::VolumeLockFileObject.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00049 : 00050 00051 This is the common routine for cleanup of a file/directory called by both 00052 the fsd and fsp threads. 00053 00054 Cleanup is invoked whenever the last handle to a file object is closed. 00055 This is different than the Close operation which is invoked when the last 00056 reference to a file object is deleted. 00057 00058 The function of cleanup is to essentially "cleanup" the file/directory 00059 after a user is done with it. The Fcb/Dcb remains around (because MM 00060 still has the file object referenced) but is now available for another 00061 user to open (i.e., as far as the user is concerned the is now closed). 00062 00063 See close for a more complete description of what close does. 00064 00065 We do no synchronization in this routine until we get to the point 00066 where we modify the counts, share access and volume lock field. 00067 00068 We need to update the Fcb and Vcb to show that a user handle has been closed. 00069 The following structures and fields are affected. 00070 00071 Vcb: 00072 00073 VolumeLockFileObject - Did the user lock the volume with this file object. 00074 VcbState - Check if we are unlocking the volume here. 00075 VcbCleanup - Count of outstanding handles on the volume. 00076 DirNotifyQueue - If this file object has pending DirNotify Irps. 00077 00078 Fcb: 00079 00080 ShareAccess - If this is a user handle. 00081 FcbCleanup - Count of outstanding handles on this Fcb. 00082 Oplock - Any outstanding oplocks on this file object. 00083 FileLock - Any outstanding filelocks on this file object. 00084 00085 Arguments: 00086 00087 Irp - Supplies the Irp to process 00088 00089 Return Value: 00090 00091 NTSTATUS - The return status for the operation. 00092 00093 --*/ 00094 00095 { 00096 PFILE_OBJECT FileObject; 00097 TYPE_OF_OPEN TypeOfOpen; 00098 00099 BOOLEAN SendUnlockNotification = FALSE; 00100 BOOLEAN AttemptTeardown; 00101 00102 PVCB Vcb; 00103 PFCB Fcb; 00104 PCCB Ccb; 00105 00106 PAGED_CODE(); 00107 00108 ASSERT_IRP_CONTEXT( IrpContext ); 00109 ASSERT_IRP( Irp ); 00110 00111 // 00112 // If we were called with our file system device object instead of a 00113 // volume device object, just complete this request with STATUS_SUCCESS. 00114 // 00115 00116 if (IrpContext->Vcb == NULL) { 00117 00118 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00119 return STATUS_SUCCESS; 00120 } 00121 00122 // 00123 // Get the file object out of the Irp and decode the type of open. 00124 // 00125 00126 FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject; 00127 00128 TypeOfOpen = UdfDecodeFileObject( FileObject, 00129 &Fcb, 00130 &Ccb ); 00131 00132 // 00133 // No work here for either an UnopenedFile object or a StreamFileObject. 00134 // 00135 00136 if (TypeOfOpen <= StreamFileOpen) { 00137 00138 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00139 00140 return STATUS_SUCCESS; 00141 } 00142 00143 // 00144 // Keep a local pointer to the Vcb. 00145 // 00146 00147 Vcb = Fcb->Vcb; 00148 00149 // 00150 // Acquire the current file. 00151 // 00152 00153 UdfAcquireFcbExclusive( IrpContext, Fcb, FALSE ); 00154 00155 // 00156 // Use a try-finally to facilitate cleanup. 00157 // 00158 00159 try { 00160 00161 // 00162 // Set the flag in the FileObject to indicate that cleanup is complete. 00163 // 00164 00165 SetFlag( FileObject->Flags, FO_CLEANUP_COMPLETE ); 00166 00167 // 00168 // Case on the type of open that we are trying to cleanup. 00169 // 00170 00171 switch (TypeOfOpen) { 00172 00173 case UserDirectoryOpen: 00174 00175 DebugTrace(( +1, Dbg, 00176 "UdfCommonCleanup, Fcb %08x FO %08x DIR\n", 00177 Fcb, 00178 FileObject )); 00179 00180 // 00181 // Check if we need to complete any dir notify Irps on this file object. 00182 // 00183 00184 FsRtlNotifyCleanup( Vcb->NotifySync, 00185 &Vcb->DirNotifyList, 00186 Ccb ); 00187 00188 break; 00189 00190 case UserFileOpen: 00191 00192 DebugTrace(( +1, Dbg, 00193 "UdfCommonCleanup, Fcb %08x FO %08x FILE\n", 00194 Fcb, 00195 FileObject )); 00196 00197 // 00198 // Coordinate the cleanup operation with the oplock state. 00199 // Oplock cleanup operations can always cleanup immediately so no 00200 // need to check for STATUS_PENDING. 00201 // 00202 00203 FsRtlCheckOplock( &Fcb->Oplock, 00204 Irp, 00205 IrpContext, 00206 NULL, 00207 NULL ); 00208 00209 // 00210 // Unlock all outstanding file locks. 00211 // 00212 00213 if (Fcb->FileLock != NULL) { 00214 00215 FsRtlFastUnlockAll( Fcb->FileLock, 00216 FileObject, 00217 IoGetRequestorProcess( Irp ), 00218 NULL ); 00219 } 00220 00221 // 00222 // Cleanup the cache map. 00223 // 00224 00225 CcUninitializeCacheMap( FileObject, NULL, NULL ); 00226 00227 // 00228 // Check the fast io state. 00229 // 00230 00231 UdfLockFcb( IrpContext, Fcb ); 00232 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00233 UdfUnlockFcb( IrpContext, Fcb ); 00234 00235 break; 00236 00237 case UserVolumeOpen : 00238 00239 DebugTrace(( +1, Dbg, 00240 "UdfCommonCleanup, Fcb %08x FO %08x VOL\n", 00241 Fcb, 00242 FileObject )); 00243 00244 break; 00245 00246 default : 00247 00248 UdfBugCheck( TypeOfOpen, 0, 0 ); 00249 } 00250 00251 // 00252 // Now lock the Vcb in order to modify the fields in the in-memory 00253 // structures. 00254 // 00255 00256 UdfLockVcb( IrpContext, Vcb ); 00257 00258 // 00259 // Decrement the cleanup counts in the Vcb and Fcb. 00260 // 00261 00262 UdfDecrementCleanupCounts( IrpContext, Fcb ); 00263 00264 // 00265 // If the cleanup count hit zero and the volume is not mounted, we 00266 // will want to try to spark teardown. 00267 // 00268 00269 AttemptTeardown = (Vcb->VcbCleanup == 0 && Vcb->VcbCondition == VcbNotMounted); 00270 00271 // 00272 // If this file object has locked the volume then perform the unlock operation. 00273 // 00274 00275 if (FileObject == Vcb->VolumeLockFileObject) { 00276 00277 ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED ); 00278 Vcb->VolumeLockFileObject = NULL; 00279 SendUnlockNotification = TRUE; 00280 } 00281 00282 UdfUnlockVcb( IrpContext, Vcb ); 00283 00284 // 00285 // We must clean up the share access at this time, since we may not 00286 // get a Close call for awhile if the file was mapped through this 00287 // File Object. 00288 // 00289 00290 IoRemoveShareAccess( FileObject, &Fcb->ShareAccess ); 00291 00292 } finally { 00293 00294 UdfReleaseFcb( IrpContext, Fcb ); 00295 00296 if (SendUnlockNotification) { 00297 00298 FsRtlNotifyVolumeEvent( FileObject, FSRTL_VOLUME_UNLOCK ); 00299 } 00300 } 00301 00302 DebugTrace(( -1, Dbg, 00303 "UdfCommonCleanup, Fcb %08x FO %08x -> SUCCESS\n", 00304 Fcb, 00305 FileObject )); 00306 00307 // 00308 // If appropriate, try to spark teardown by purging the volume. Should 00309 // this very fileobject we were cleaning up be the last reason for the 00310 // volume to remain, teardown will commence on completion of this Irp. 00311 // 00312 00313 if (AttemptTeardown) { 00314 00315 UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE ); 00316 00317 try { 00318 00319 UdfPurgeVolume( IrpContext, Vcb, FALSE ); 00320 00321 } finally { 00322 00323 UdfReleaseVcb( IrpContext, Vcb ); 00324 } 00325 } 00326 00327 // 00328 // If this is a normal termination then complete the request 00329 // 00330 00331 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00332 00333 return STATUS_SUCCESS; 00334 }

NTSTATUS UdfCommonClose IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 319 of file close.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, FALSE, _FCB::FcbReference, FlagOn, IoGetCurrentIrpStackLocation, Irp, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, NULL, PAGED_CODE, TRUE, TYPE_OF_OPEN, UdfAcquireUdfData, UdfCheckForDismount(), UdfCommonClosePrivate(), UdfCompleteRequest(), UdfDecodeFileObject(), UdfDeleteCcb(), UdfQueueClose(), UdfReleaseUdfData, UnopenedFileObject, UserDirectoryOpen, UserFileOpen, _FCB::Vcb, _VCB::VcbCleanup, _VCB::VcbCondition, VcbMounted, and VcbMountInProgress.

Referenced by UdfFsdDispatch().

00326 : 00327 00328 This routine is the Fsd entry for the close operation. We decode the file 00329 object to find the UDFS structures and type of open. We call our internal 00330 worker routine to perform the actual work. If the work wasn't completed 00331 then we post to one of our worker queues. The Ccb isn't needed after this 00332 point so we delete the Ccb and return STATUS_SUCCESS to our caller in all 00333 cases. 00334 00335 Arguments: 00336 00337 Irp - Supplies the Irp to process 00338 00339 Return Value: 00340 00341 STATUS_SUCCESS 00342 00343 --*/ 00344 00345 { 00346 TYPE_OF_OPEN TypeOfOpen; 00347 00348 PVCB Vcb; 00349 PFCB Fcb; 00350 PCCB Ccb; 00351 ULONG UserReference = 0; 00352 00353 BOOLEAN DelayedClose; 00354 BOOLEAN ReleaseUdfData = FALSE; 00355 00356 PAGED_CODE(); 00357 00358 // 00359 // Check input. 00360 // 00361 00362 ASSERT_IRP_CONTEXT( IrpContext ); 00363 ASSERT_IRP( Irp ); 00364 00365 // 00366 // If we were called with our file system device object instead of a 00367 // volume device object, just complete this request with STATUS_SUCCESS. 00368 // 00369 00370 if (IrpContext->Vcb == NULL) { 00371 00372 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00373 return STATUS_SUCCESS; 00374 } 00375 00376 // 00377 // Decode the file object to get the type of open and Fcb/Ccb. 00378 // 00379 00380 TypeOfOpen = UdfDecodeFileObject( IoGetCurrentIrpStackLocation( Irp )->FileObject, 00381 &Fcb, 00382 &Ccb ); 00383 00384 // 00385 // No work to do for unopened file objects. 00386 // 00387 00388 if (TypeOfOpen == UnopenedFileObject) { 00389 00390 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00391 00392 return STATUS_SUCCESS; 00393 } 00394 00395 Vcb = Fcb->Vcb; 00396 00397 // 00398 // Call the worker routine to perform the actual work. This routine 00399 // should never raise except for a fatal error. 00400 // 00401 00402 if (Ccb != NULL) { 00403 00404 UserReference = 1; 00405 00406 // 00407 // We can always deallocate the Ccb if present. 00408 // 00409 00410 UdfDeleteCcb( IrpContext, Ccb ); 00411 } 00412 00413 // 00414 // If this is a user file or directory then check if we should post 00415 // this to the delayed close queue. This has to be the last reference 00416 // for a user file or directory open. 00417 // 00418 00419 if ((Vcb->VcbCondition == VcbMounted) && 00420 (Fcb->FcbReference == 1) && 00421 ((TypeOfOpen == UserFileOpen) || 00422 (TypeOfOpen == UserDirectoryOpen))) { 00423 00424 UdfQueueClose( IrpContext, Fcb, UserReference, TRUE ); 00425 IrpContext = NULL; 00426 00427 // 00428 // Otherwise try to process this close. Post to the async close queue 00429 // if we can't acquire all of the resources. 00430 // 00431 00432 } else { 00433 00434 // 00435 // If we may be dismounting this volume then acquire the UdfData 00436 // resource. 00437 // 00438 // Since we now must make volumes go away as soon as reasonable after 00439 // the last user handles closes, key off of the cleanup count. It is 00440 // OK to do this more than neccesary. Since this Fcb could be holding 00441 // a number of other Fcbs (and thus their references), a simple check 00442 // on reference count is not appropriate. 00443 // 00444 00445 if ((Vcb->VcbCleanup == 0) && 00446 (Vcb->VcbCondition != VcbMounted) && 00447 (Vcb->VcbCondition != VcbMountInProgress) && 00448 FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS )) { 00449 00450 UdfAcquireUdfData( IrpContext ); 00451 ReleaseUdfData = TRUE; 00452 } 00453 00454 if (!UdfCommonClosePrivate( IrpContext, Vcb, Fcb, UserReference, TRUE )) { 00455 00456 // 00457 // If we didn't complete the request then post the request as needed. 00458 // 00459 00460 UdfQueueClose( IrpContext, Fcb, UserReference, FALSE ); 00461 IrpContext = NULL; 00462 00463 // 00464 // Check whether we should be dismounting the volume and then complete 00465 // the request. 00466 // 00467 00468 } else if (ReleaseUdfData) { 00469 00470 UdfCheckForDismount( IrpContext, Vcb, FALSE ); 00471 } 00472 } 00473 00474 // 00475 // Always complete this request with STATUS_SUCCESS. 00476 // 00477 00478 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00479 00480 if (ReleaseUdfData) { 00481 00482 UdfReleaseUdfData( IrpContext ); 00483 } 00484 00485 // 00486 // Always return STATUS_SUCCESS for closes. 00487 // 00488 00489 return STATUS_SUCCESS; 00490 }

NTSTATUS UdfCommonCreate IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 108 of file udfs/create.c.

References ASSERT, BooleanFlagOn, DIR_ENUM_CONTEXT, FALSE, _DIR_ENUM_CONTEXT::Fid, _FCB::FileAttributes, _FILE_OBJECT::FileName, FileName, _IO_STACK_LOCATION::FileObject, FlagOn, NSR_FID::Flags, _IO_STACK_LOCATION::Flags, IoGetCurrentIrpStackLocation, Irp, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH, IRP_CONTEXT_FLAG_WAIT, NSR_FID_F_DIRECTORY, NT_SUCCESS, NTSTATUS(), NULL, _DIR_ENUM_CONTEXT::ObjectName, PAGED_CODE, _IO_STACK_LOCATION::Parameters, _FILE_OBJECT::RelatedFileObject, _VCB::RootIndexFcb, SafeNodeType, SL_CASE_SENSITIVE, SL_OPEN_PAGING_FILE, SL_OPEN_TARGET_DIRECTORY, Status, TRUE, try_leave, TYPE_OF_OPEN, UdfAcquireFcbExclusive, UdfAcquireVcbExclusive, UdfAcquireVcbShared, UdfCandidateShortName(), UdfCleanupDirContext(), UdfCompleteRequest(), UdfDecodeFileObject(), UdfDissectName(), UdfFindDirEntry(), UdfFindPrefix(), UdfInitializeDirContext(), UdfNormalizeFileNames(), UdfOpenExistingFcb(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfRaiseStatus(), UdfReleaseFcb, UdfReleaseVcb, UDFS_NTC_FCB_DATA, UdfTeardownStructures(), UdfVerifyVcb(), UnopenedFileObject, UserDirectoryOpen, UserFileOpen, UserVolumeOpen, VCB_STATE_LOCKED, _VCB::VcbState, _VCB::VolumeDasdFcb, and _FILE_OBJECT::Vpb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00115 : 00116 00117 This is the common routine for opening a file called by both the 00118 Fsp and Fsd threads. 00119 00120 The file can be opened either by name or by file Id either with or without 00121 a relative name. The file name field in the file object passed to this routine 00122 contains either a unicode string or a 64 bit value which is the file Id. 00123 If there is a related file object with a name then we will already have converted 00124 that name to Oem. 00125 00126 We will store the full name for the file in the file object on a successful 00127 open. We will allocate a larger buffer if necessary and combine the 00128 related and file object names. The only exception is the relative open 00129 when the related file object is for an OpenByFileId file. If we need to 00130 allocate a buffer for a case insensitive name then we allocate it at 00131 the tail of the buffer we will store into the file object. The upcased 00132 portion will begin immediately after the name defined by the FileName 00133 in the file object. 00134 00135 Once we have the full name in the file object we don't want to split the 00136 name in the event of a retry. We use a flag in the IrpContext to indicate 00137 that the name has been split. 00138 00139 Arguments: 00140 00141 Irp - Supplies the Irp to process 00142 00143 Return Value: 00144 00145 NTSTATUS - This is the status from this open operation. 00146 00147 --*/ 00148 00149 { 00150 NTSTATUS Status = STATUS_SUCCESS; 00151 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00152 00153 PFILE_OBJECT FileObject; 00154 00155 DIR_ENUM_CONTEXT DirContext; 00156 BOOLEAN CleanupDirContext = FALSE; 00157 00158 BOOLEAN FoundEntry; 00159 00160 PVCB Vcb; 00161 00162 BOOLEAN OpenByFileId; 00163 BOOLEAN IgnoreCase; 00164 ULONG CreateDisposition; 00165 00166 BOOLEAN ShortNameMatch; 00167 00168 BOOLEAN VolumeOpen = FALSE; 00169 00170 // 00171 // We will be acquiring and releasing file Fcb's as we move down the 00172 // directory tree during opens. At any time we need to know the deepest 00173 // point we have traversed down in the tree in case we need to cleanup 00174 // any structures created here. 00175 // 00176 // CurrentFcb - represents this point. If non-null it means we have 00177 // acquired it and need to release it in finally clause. 00178 // 00179 // NextFcb - represents the NextFcb to walk to but haven't acquired yet. 00180 // 00181 // CurrentLcb - represents the name of the CurrentFcb. 00182 // 00183 00184 TYPE_OF_OPEN RelatedTypeOfOpen = UnopenedFileObject; 00185 PFILE_OBJECT RelatedFileObject; 00186 PCCB RelatedCcb = NULL; 00187 00188 PFCB NextFcb; 00189 PFCB CurrentFcb = NULL; 00190 00191 PLCB CurrentLcb = NULL; 00192 00193 // 00194 // During the open we need to combine the related file object name 00195 // with the remaining name. We also may need to upcase the file name 00196 // in order to do a case-insensitive name comparison. We also need 00197 // to restore the name in the file object in the event that we retry 00198 // the request. We use the following string variables to manage the 00199 // name. We will can put these strings into either Unicode or Ansi 00200 // form. 00201 // 00202 // FileName - Pointer to name as currently stored in the file 00203 // object. We store the full name into the file object early in 00204 // the open operation. 00205 // 00206 // RelatedFileName - Pointer to the name in the related file object. 00207 // 00208 // RemainingName - String containing remaining name to parse. 00209 // 00210 00211 PUNICODE_STRING FileName; 00212 PUNICODE_STRING RelatedFileName; 00213 00214 UNICODE_STRING RemainingName; 00215 UNICODE_STRING FinalName; 00216 00217 PAGED_CODE(); 00218 00219 // 00220 // If we were called with our file system device object instead of a 00221 // volume device object, just complete this request with STATUS_SUCCESS. 00222 // 00223 00224 if (IrpContext->Vcb == NULL) { 00225 00226 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00227 return STATUS_SUCCESS; 00228 } 00229 00230 // 00231 // Get create parameters from the Irp. 00232 // 00233 00234 OpenByFileId = BooleanFlagOn( IrpSp->Parameters.Create.Options, FILE_OPEN_BY_FILE_ID ); 00235 IgnoreCase = !BooleanFlagOn( IrpSp->Flags, SL_CASE_SENSITIVE ); 00236 CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0x000000ff; 00237 00238 // 00239 // Do some preliminary checks to make sure the operation is supported. 00240 // We fail in the following cases immediately. 00241 // 00242 // - Open a paging file. 00243 // - Open a target directory. 00244 // - Open a file with Eas. 00245 // - Create a file. 00246 // 00247 00248 if (FlagOn( IrpSp->Flags, SL_OPEN_PAGING_FILE | SL_OPEN_TARGET_DIRECTORY) || 00249 (IrpSp->Parameters.Create.EaLength != 0) || 00250 (CreateDisposition == FILE_CREATE)) { 00251 00252 UdfCompleteRequest( IrpContext, Irp, STATUS_ACCESS_DENIED ); 00253 return STATUS_ACCESS_DENIED; 00254 } 00255 00256 // 00257 // Copy the Vcb to a local. Assume the starting directory is the root. 00258 // 00259 00260 Vcb = IrpContext->Vcb; 00261 NextFcb = Vcb->RootIndexFcb; 00262 00263 // 00264 // Reference our input parameters to make things easier 00265 // 00266 00267 FileObject = IrpSp->FileObject; 00268 RelatedFileObject = NULL; 00269 00270 FileName = &FileObject->FileName; 00271 00272 // 00273 // Set up the file object's Vpb pointer in case anything happens. 00274 // This will allow us to get a reasonable pop-up. 00275 // 00276 00277 if ((FileObject->RelatedFileObject != NULL) && !OpenByFileId) { 00278 00279 RelatedFileObject = FileObject->RelatedFileObject; 00280 FileObject->Vpb = RelatedFileObject->Vpb; 00281 00282 RelatedTypeOfOpen = UdfDecodeFileObject( RelatedFileObject, &NextFcb, &RelatedCcb ); 00283 00284 // 00285 // Fail the request if this is not a user file object. 00286 // 00287 00288 if (RelatedTypeOfOpen < UserVolumeOpen) { 00289 00290 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00291 return STATUS_INVALID_PARAMETER; 00292 } 00293 00294 // 00295 // Remember the name in the related file object. 00296 // 00297 00298 RelatedFileName = &RelatedFileObject->FileName; 00299 } 00300 00301 // 00302 // If we haven't initialized the names then make sure the strings are valid. 00303 // If this an OpenByFileId then verify the file id buffer. 00304 // 00305 // After this routine returns we know that the full name is in the 00306 // FileName buffer and the buffer will hold the upcased portion 00307 // of the name yet to parse immediately after the full name in the 00308 // buffer. Any trailing backslash has been removed and the flag 00309 // in the IrpContext will indicate whether we removed the 00310 // backslash. 00311 // 00312 00313 Status = UdfNormalizeFileNames( IrpContext, 00314 Vcb, 00315 OpenByFileId, 00316 IgnoreCase, 00317 RelatedTypeOfOpen, 00318 RelatedCcb, 00319 RelatedFileName, 00320 FileName, 00321 &RemainingName ); 00322 00323 // 00324 // Return the error code if not successful. 00325 // 00326 00327 if (!NT_SUCCESS( Status )) { 00328 00329 UdfCompleteRequest( IrpContext, Irp, Status ); 00330 return Status; 00331 } 00332 00333 // 00334 // We want to acquire the Vcb. Exclusively for a volume open, shared otherwise. 00335 // The file name is empty for a volume open. 00336 // 00337 00338 if ((FileName->Length == 0) && 00339 (RelatedTypeOfOpen <= UserVolumeOpen) && 00340 !OpenByFileId) { 00341 00342 VolumeOpen = TRUE; 00343 UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE ); 00344 00345 } else { 00346 00347 UdfAcquireVcbShared( IrpContext, Vcb, FALSE ); 00348 } 00349 00350 // 00351 // Use a try-finally to facilitate cleanup. 00352 // 00353 00354 try { 00355 00356 // 00357 // Verify that the Vcb is not in an unusable condition. This routine 00358 // will raise if not usable. 00359 // 00360 00361 UdfVerifyVcb( IrpContext, Vcb ); 00362 00363 // 00364 // If the Vcb is locked then we cannot open another file 00365 // 00366 00367 if (FlagOn( Vcb->VcbState, VCB_STATE_LOCKED )) { 00368 00369 try_leave( Status = STATUS_ACCESS_DENIED ); 00370 } 00371 00372 // 00373 // If we are opening this file by FileId then process this immediately 00374 // and exit. 00375 // 00376 00377 if (OpenByFileId) { 00378 00379 // 00380 // The only create disposition we allow is OPEN. 00381 // 00382 00383 if ((CreateDisposition != FILE_OPEN) && 00384 (CreateDisposition != FILE_OPEN_IF)) { 00385 00386 try_leave( Status = STATUS_ACCESS_DENIED ); 00387 } 00388 00389 try_leave( Status = UdfOpenObjectByFileId( IrpContext, 00390 IrpSp, 00391 Vcb, 00392 &CurrentFcb )); 00393 } 00394 00395 // 00396 // If we are opening this volume Dasd then process this immediately 00397 // and exit. 00398 // 00399 00400 if (VolumeOpen) { 00401 00402 // 00403 // The only create disposition we allow is OPEN. 00404 // 00405 00406 if ((CreateDisposition != FILE_OPEN) && 00407 (CreateDisposition != FILE_OPEN_IF)) { 00408 00409 try_leave( Status = STATUS_ACCESS_DENIED ); 00410 } 00411 00412 // 00413 // If they wanted to open a directory, surprise. 00414 // 00415 00416 if (FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { 00417 00418 try_leave( Status = STATUS_NOT_A_DIRECTORY ); 00419 } 00420 00421 // 00422 // Acquire the Fcb first. 00423 // 00424 00425 CurrentFcb = Vcb->VolumeDasdFcb; 00426 UdfAcquireFcbExclusive( IrpContext, CurrentFcb, FALSE ); 00427 00428 try_leave( Status = UdfOpenExistingFcb( IrpContext, 00429 IrpSp, 00430 &CurrentFcb, 00431 NULL, 00432 UserVolumeOpen, 00433 FALSE, 00434 NULL )); 00435 } 00436 00437 // 00438 // Acquire the Fcb at the beginning of our search to keep it from being 00439 // deleted beneath us. 00440 // 00441 00442 UdfAcquireFcbExclusive( IrpContext, NextFcb, FALSE ); 00443 CurrentFcb = NextFcb; 00444 00445 // 00446 // Do a prefix search if there is more of the name to parse. 00447 // 00448 00449 if (RemainingName.Length != 0) { 00450 00451 // 00452 // Do the prefix search to find the longest matching name. 00453 // 00454 00455 CurrentLcb = UdfFindPrefix( IrpContext, 00456 &CurrentFcb, 00457 &RemainingName, 00458 IgnoreCase ); 00459 } 00460 00461 // 00462 // At this point CurrentFcb points at the lowest Fcb in the tree for this 00463 // file name, CurrentLcb is that name, and RemainingName is the rest of the 00464 // name we have to do any directory traversals for. 00465 // 00466 00467 // 00468 // If the remaining name length is zero then we have found our 00469 // target. 00470 // 00471 00472 if (RemainingName.Length == 0) { 00473 00474 // 00475 // If this is a file so verify the user didn't want to open 00476 // a directory. 00477 // 00478 00479 if (SafeNodeType( CurrentFcb ) == UDFS_NTC_FCB_DATA) { 00480 00481 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) || 00482 FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) { 00483 00484 try_leave( Status = STATUS_NOT_A_DIRECTORY ); 00485 } 00486 00487 // 00488 // The only create disposition we allow is OPEN. 00489 // 00490 00491 if ((CreateDisposition != FILE_OPEN) && 00492 (CreateDisposition != FILE_OPEN_IF)) { 00493 00494 try_leave( Status = STATUS_ACCESS_DENIED ); 00495 } 00496 00497 try_leave( Status = UdfOpenExistingFcb( IrpContext, 00498 IrpSp, 00499 &CurrentFcb, 00500 CurrentLcb, 00501 UserFileOpen, 00502 IgnoreCase, 00503 RelatedCcb )); 00504 00505 // 00506 // This is a directory. Verify the user didn't want to open 00507 // as a file. 00508 // 00509 00510 } else if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE )) { 00511 00512 try_leave( Status = STATUS_FILE_IS_A_DIRECTORY ); 00513 00514 // 00515 // Open the file as a directory. 00516 // 00517 00518 } else { 00519 00520 // 00521 // The only create disposition we allow is OPEN. 00522 // 00523 00524 if ((CreateDisposition != FILE_OPEN) && 00525 (CreateDisposition != FILE_OPEN_IF)) { 00526 00527 try_leave( Status = STATUS_ACCESS_DENIED ); 00528 } 00529 00530 try_leave( Status = UdfOpenExistingFcb( IrpContext, 00531 IrpSp, 00532 &CurrentFcb, 00533 CurrentLcb, 00534 UserDirectoryOpen, 00535 IgnoreCase, 00536 RelatedCcb )); 00537 } 00538 } 00539 00540 // 00541 // We have more work to do. We have a starting Fcb which we own shared. 00542 // We also have the remaining name to parse. Walk through the name 00543 // component by component looking for the full name. 00544 // 00545 00546 // 00547 // Our starting Fcb better be a directory. 00548 // 00549 00550 if (!FlagOn( CurrentFcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { 00551 00552 try_leave( Status = STATUS_OBJECT_PATH_NOT_FOUND ); 00553 } 00554 00555 // 00556 // If we can't wait then post this request. 00557 // 00558 00559 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00560 00561 UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT ); 00562 } 00563 00564 // 00565 // Prepare the enumeration context for use. 00566 // 00567 00568 UdfInitializeDirContext( IrpContext, &DirContext ); 00569 CleanupDirContext = TRUE; 00570 00571 while (TRUE) { 00572 00573 ShortNameMatch = FALSE; 00574 00575 // 00576 // Split off the next component from the name. 00577 // 00578 00579 UdfDissectName( IrpContext, 00580 &RemainingName, 00581 &FinalName ); 00582 00583 // 00584 // Go ahead and look this entry up in the directory. 00585 // 00586 00587 FoundEntry = UdfFindDirEntry( IrpContext, 00588 CurrentFcb, 00589 &FinalName, 00590 IgnoreCase, 00591 FALSE, 00592 &DirContext ); 00593 00594 // 00595 // If we didn't find the entry then check if the current name 00596 // is a possible short name. 00597 // 00598 00599 if (!FoundEntry && UdfCandidateShortName( IrpContext, &FinalName)) { 00600 00601 // 00602 // If the name looks like it could be a short name, try to find 00603 // a matching real directory entry. 00604 // 00605 00606 ShortNameMatch = 00607 FoundEntry = UdfFindDirEntry( IrpContext, 00608 CurrentFcb, 00609 &FinalName, 00610 IgnoreCase, 00611 TRUE, 00612 &DirContext ); 00613 } 00614 00615 // 00616 // If we didn't find a match then check what the caller was trying to do to 00617 // determine which error code to return. 00618 // 00619 00620 if (!FoundEntry) { 00621 00622 if ((CreateDisposition == FILE_OPEN) || 00623 (CreateDisposition == FILE_OVERWRITE)) { 00624 00625 try_leave( Status = STATUS_OBJECT_NAME_NOT_FOUND ); 00626 } 00627 00628 // 00629 // Any other operation return STATUS_ACCESS_DENIED. 00630 // 00631 00632 try_leave( Status = STATUS_ACCESS_DENIED ); 00633 } 00634 00635 // 00636 // If this is an ignore case open then copy the exact case 00637 // in the file object name. 00638 // 00639 00640 if (IgnoreCase && !ShortNameMatch) { 00641 00642 ASSERT( FinalName.Length == DirContext.ObjectName.Length ); 00643 00644 RtlCopyMemory( FinalName.Buffer, 00645 DirContext.ObjectName.Buffer, 00646 DirContext.ObjectName.Length ); 00647 } 00648 00649 // 00650 // If we have found the last component then break out to open for the caller. 00651 // 00652 00653 if (RemainingName.Length == 0) { 00654 00655 break; 00656 } 00657 00658 // 00659 // The object we just found must be a directory. 00660 // 00661 00662 if (!FlagOn( DirContext.Fid->Flags, NSR_FID_F_DIRECTORY )) { 00663 00664 try_leave( Status = STATUS_OBJECT_PATH_NOT_FOUND ); 00665 } 00666 00667 // 00668 // Now open an Fcb for this intermediate index Fcb. 00669 // 00670 00671 UdfOpenObjectFromDirContext( IrpContext, 00672 IrpSp, 00673 Vcb, 00674 &CurrentFcb, 00675 ShortNameMatch, 00676 IgnoreCase, 00677 &DirContext, 00678 FALSE, 00679 NULL ); 00680 } 00681 00682 // 00683 // Make sure our opener is about to get what they expect. 00684 // 00685 00686 if ((FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TRAIL_BACKSLASH ) || 00687 FlagOn( IrpSp->Parameters.Create.Options, FILE_DIRECTORY_FILE )) && 00688 !FlagOn( DirContext.Fid->Flags, NSR_FID_F_DIRECTORY )) { 00689 00690 try_leave( Status = STATUS_NOT_A_DIRECTORY ); 00691 00692 } 00693 00694 if (FlagOn( IrpSp->Parameters.Create.Options, FILE_NON_DIRECTORY_FILE ) && 00695 FlagOn( DirContext.Fid->Flags, NSR_FID_F_DIRECTORY )) { 00696 00697 try_leave( Status = STATUS_FILE_IS_A_DIRECTORY ); 00698 } 00699 00700 // 00701 // The only create disposition we allow is OPEN. 00702 // 00703 00704 if ((CreateDisposition != FILE_OPEN) && 00705 (CreateDisposition != FILE_OPEN_IF)) { 00706 00707 try_leave( Status = STATUS_ACCESS_DENIED ); 00708 } 00709 00710 // 00711 // Open the object for the caller. 00712 // 00713 00714 try_leave( Status = UdfOpenObjectFromDirContext( IrpContext, 00715 IrpSp, 00716 Vcb, 00717 &CurrentFcb, 00718 ShortNameMatch, 00719 IgnoreCase, 00720 &DirContext, 00721 TRUE, 00722 RelatedCcb )); 00723 } finally { 00724 00725 // 00726 // Cleanup the enumeration context if initialized. 00727 // 00728 00729 if (CleanupDirContext) { 00730 00731 UdfCleanupDirContext( IrpContext, &DirContext ); 00732 } 00733 00734 // 00735 // The result of this open could be success, pending or some error 00736 // condition. 00737 // 00738 00739 if (AbnormalTermination()) { 00740 00741 00742 // 00743 // In the error path we start by calling our teardown routine if we 00744 // have a CurrentFcb. 00745 // 00746 00747 if (CurrentFcb != NULL) { 00748 00749 BOOLEAN RemovedFcb; 00750 00751 UdfTeardownStructures( IrpContext, CurrentFcb, FALSE, &RemovedFcb ); 00752 00753 if (RemovedFcb) { 00754 00755 CurrentFcb = NULL; 00756 } 00757 } 00758 00759 // 00760 // No need to complete the request. 00761 // 00762 00763 IrpContext = NULL; 00764 Irp = NULL; 00765 00766 // 00767 // If we posted this request through the oplock package we need 00768 // to show that there is no reason to complete the request. 00769 // 00770 00771 } else if (Status == STATUS_PENDING) { 00772 00773 IrpContext = NULL; 00774 Irp = NULL; 00775 } 00776 00777 // 00778 // Release the Current Fcb if still acquired. 00779 // 00780 00781 if (CurrentFcb != NULL) { 00782 00783 UdfReleaseFcb( IrpContext, CurrentFcb ); 00784 } 00785 00786 // 00787 // Release the Vcb. 00788 // 00789 00790 UdfReleaseVcb( IrpContext, Vcb ); 00791 00792 // 00793 // Call our completion routine. It will handle the case where either 00794 // the Irp and/or IrpContext are gone. 00795 // 00796 00797 UdfCompleteRequest( IrpContext, Irp, Status ); 00798 } 00799 00800 return Status; 00801 }

NTSTATUS UdfCommonDevControl IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 69 of file udfs/devctrl.c.

References _IRP::AssociatedIrp, _IO_STACK_LOCATION::FileObject, IoCallDriver, IoCopyCurrentIrpStackLocationToNext, IoGetCurrentIrpStackLocation, IoSetCompletionRoutine, _IRP::IoStatus, Irp, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, Status, TRUE, TYPE_OF_OPEN, UdfCompleteRequest(), UdfDecodeFileObject(), UdfDevCtrlCompletionRoutine(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfVerifyVcb(), UserFileOpen, UserVolumeOpen, and _FCB::Vcb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00076 : 00077 00078 This is the common routine for doing Device control operations called 00079 by both the fsd and fsp threads 00080 00081 Arguments: 00082 00083 Irp - Supplies the Irp to process 00084 00085 Return Value: 00086 00087 NTSTATUS - The return status for the operation 00088 00089 --*/ 00090 00091 { 00092 NTSTATUS Status; 00093 00094 TYPE_OF_OPEN TypeOfOpen; 00095 PFCB Fcb; 00096 PCCB Ccb; 00097 00098 PIO_STACK_LOCATION IrpSp; 00099 00100 PVOID TargetBuffer; 00101 00102 PAGED_CODE(); 00103 00104 // 00105 // Extract and decode the file object. 00106 // 00107 00108 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00109 00110 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, 00111 &Fcb, 00112 &Ccb ); 00113 00114 // 00115 // A few IOCTLs actually require some intervention on our part to 00116 // translate some information from file-based to device-based units. 00117 // 00118 00119 if (TypeOfOpen == UserFileOpen) { 00120 00121 switch (IrpSp->Parameters.DeviceIoControl.IoControlCode) { 00122 case IOCTL_DVD_READ_KEY: 00123 case IOCTL_DVD_SEND_KEY: 00124 00125 Status = UdfDvdTransferKey( IrpContext, Irp, Fcb ); 00126 break; 00127 00128 case IOCTL_DVD_READ_STRUCTURE: 00129 00130 Status = UdfDvdReadStructure( IrpContext, Irp, Fcb ); 00131 break; 00132 00133 case IOCTL_STORAGE_SET_READ_AHEAD: 00134 00135 // 00136 // We're just going to no-op this for now. 00137 // 00138 00139 Status = STATUS_SUCCESS; 00140 UdfCompleteRequest( IrpContext, Irp, Status ); 00141 break; 00142 00143 default: 00144 00145 Status = STATUS_INVALID_PARAMETER; 00146 UdfCompleteRequest( IrpContext, Irp, Status ); 00147 break; 00148 } 00149 00150 return Status; 00151 } 00152 00153 // 00154 // Now the only type of opens we accept are user volume opens. 00155 // 00156 00157 if (TypeOfOpen != UserVolumeOpen) { 00158 00159 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00160 return STATUS_INVALID_PARAMETER; 00161 } 00162 00163 // 00164 // Handle the case of the disk type ourselves. We're really just going to 00165 // lie about this, but it is a good lie. 00166 // 00167 00168 if (IrpSp->Parameters.DeviceIoControl.IoControlCode == IOCTL_CDROM_DISK_TYPE) { 00169 00170 // 00171 // Verify the Vcb in this case to detect if the volume has changed. 00172 // 00173 00174 UdfVerifyVcb( IrpContext, Fcb->Vcb ); 00175 00176 // 00177 // Check the size of the output buffer. 00178 // 00179 00180 if (IrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( CDROM_DISK_DATA )) { 00181 00182 UdfCompleteRequest( IrpContext, Irp, STATUS_BUFFER_TOO_SMALL ); 00183 return STATUS_BUFFER_TOO_SMALL; 00184 } 00185 00186 // 00187 // Copy the data from the Vcb. 00188 // 00189 00190 ((PCDROM_DISK_DATA) Irp->AssociatedIrp.SystemBuffer)->DiskData = CDROM_DISK_DATA_TRACK; 00191 00192 Irp->IoStatus.Information = sizeof( CDROM_DISK_DATA ); 00193 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00194 return STATUS_SUCCESS; 00195 } 00196 00197 // 00198 // Copy the arguments and set up the completion routine 00199 // 00200 00201 IoCopyCurrentIrpStackLocationToNext( Irp ); 00202 00203 IoSetCompletionRoutine( Irp, 00204 UdfDevCtrlCompletionRoutine, 00205 NULL, 00206 TRUE, 00207 TRUE, 00208 TRUE ); 00209 00210 // 00211 // Send the request. 00212 // 00213 00214 Status = IoCallDriver( IrpContext->Vcb->TargetDeviceObject, Irp ); 00215 00216 // 00217 // Cleanup our Irp Context. The driver has completed the Irp. 00218 // 00219 00220 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00221 00222 return Status; 00223 }

NTSTATUS UdfCommonDirControl IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 255 of file dirctrl.c.

References _IO_STACK_LOCATION::FileObject, IoGetCurrentIrpStackLocation, Irp, IRP_MN_NOTIFY_CHANGE_DIRECTORY, IRP_MN_QUERY_DIRECTORY, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, Status, UdfCompleteRequest(), UdfDecodeFileObject(), UdfNotifyChangeDirectory(), UdfQueryDirectory(), and UserDirectoryOpen.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00262 : 00263 00264 This routine is the entry point for the directory control operations. These 00265 are directory enumerations and directory notify calls. We verify the 00266 user's handle is for a directory and then call the appropriate routine. 00267 00268 Arguments: 00269 00270 Irp - Irp for this request. 00271 00272 Return Value: 00273 00274 NTSTATUS - Status returned from the lower level routines. 00275 00276 --*/ 00277 00278 { 00279 NTSTATUS Status; 00280 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00281 00282 PFCB Fcb; 00283 PCCB Ccb; 00284 00285 PAGED_CODE(); 00286 00287 // 00288 // Decode the user file object and fail this request if it is not 00289 // a user directory. 00290 // 00291 00292 if (UdfDecodeFileObject( IrpSp->FileObject, 00293 &Fcb, 00294 &Ccb ) != UserDirectoryOpen) { 00295 00296 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00297 return STATUS_INVALID_PARAMETER; 00298 } 00299 00300 // 00301 // We know this is a directory control so we'll case on the 00302 // minor function, and call a internal worker routine to complete 00303 // the irp. 00304 // 00305 00306 switch (IrpSp->MinorFunction) { 00307 00308 case IRP_MN_QUERY_DIRECTORY: 00309 00310 Status = UdfQueryDirectory( IrpContext, Irp, IrpSp, Fcb, Ccb ); 00311 break; 00312 00313 case IRP_MN_NOTIFY_CHANGE_DIRECTORY: 00314 00315 Status = UdfNotifyChangeDirectory( IrpContext, Irp, IrpSp, Ccb ); 00316 break; 00317 00318 default: 00319 00320 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); 00321 Status = STATUS_INVALID_DEVICE_REQUEST; 00322 break; 00323 } 00324 00325 return Status; 00326 }

NTSTATUS UdfCommonFsControl IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 283 of file udfs/fsctrl.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, IoGetCurrentIrpStackLocation, Irp, IRP_MN_MOUNT_VOLUME, IRP_MN_USER_FS_REQUEST, IRP_MN_VERIFY_VOLUME, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), PAGED_CODE, Status, UdfCompleteRequest(), UdfMountVolume(), UdfUserFsctl(), and UdfVerifyVolume().

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00290 : 00291 00292 This is the common routine for doing FileSystem control operations called 00293 by both the fsd and fsp threads 00294 00295 Arguments: 00296 00297 Irp - Supplies the Irp to process 00298 00299 Return Value: 00300 00301 NTSTATUS - The return status for the operation 00302 00303 --*/ 00304 00305 { 00306 NTSTATUS Status; 00307 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00308 00309 PAGED_CODE(); 00310 00311 // 00312 // Check the input parameters 00313 // 00314 00315 ASSERT_IRP_CONTEXT( IrpContext ); 00316 ASSERT_IRP( Irp ); 00317 00318 // 00319 // Get a pointer to the current Irp stack location 00320 // 00321 00322 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00323 00324 // 00325 // We know this is a file system control so we'll case on the 00326 // minor function, and call a internal worker routine to complete 00327 // the irp. 00328 // 00329 00330 switch (IrpSp->MinorFunction) { 00331 00332 case IRP_MN_MOUNT_VOLUME: 00333 00334 Status = UdfMountVolume( IrpContext, Irp ); 00335 break; 00336 00337 case IRP_MN_VERIFY_VOLUME: 00338 00339 Status = UdfVerifyVolume( IrpContext, Irp ); 00340 break; 00341 00342 case IRP_MN_USER_FS_REQUEST: 00343 00344 Status = UdfUserFsctl( IrpContext, Irp ); 00345 break; 00346 00347 default: 00348 00349 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); 00350 Status = STATUS_INVALID_DEVICE_REQUEST; 00351 break; 00352 } 00353 00354 return Status; 00355 }

NTSTATUS UdfCommonLockControl IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 46 of file lockctrl.c.

References _IO_STACK_LOCATION::FileObject, FsRtlCheckOplock(), FsRtlProcessFileLock(), IoGetCurrentIrpStackLocation, Irp, NTSTATUS(), NULL, PAGED_CODE, Status, TRUE, TYPE_OF_OPEN, UdfCompleteRequest(), UdfCreateFileLock(), UdfDecodeFileObject(), UdfIsFastIoPossible, UdfLockFcb, UdfOplockComplete(), UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00053 : 00054 00055 This is the common routine for Lock Control called by both the fsd and fsp 00056 threads. 00057 00058 Arguments: 00059 00060 Irp - Supplies the Irp to process 00061 00062 Return Value: 00063 00064 NTSTATUS - The return status for the operation 00065 00066 --*/ 00067 00068 { 00069 NTSTATUS Status; 00070 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00071 00072 TYPE_OF_OPEN TypeOfOpen; 00073 PFCB Fcb; 00074 PCCB Ccb; 00075 00076 PAGED_CODE(); 00077 00078 // 00079 // Extract and decode the type of file object we're being asked to process 00080 // 00081 00082 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb ); 00083 00084 // 00085 // If the file is not a user file open then we reject the request 00086 // as an invalid parameter 00087 // 00088 00089 if (TypeOfOpen != UserFileOpen) { 00090 00091 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00092 return STATUS_INVALID_PARAMETER; 00093 } 00094 00095 // 00096 // We check whether we can proceed based on the state of the file oplocks. 00097 // This call might post the irp for us. 00098 // 00099 00100 Status = FsRtlCheckOplock( &Fcb->Oplock, 00101 Irp, 00102 IrpContext, 00103 UdfOplockComplete, 00104 NULL ); 00105 00106 // 00107 // If we don't get success then the oplock package completed the request. 00108 // 00109 00110 if (Status != STATUS_SUCCESS) { 00111 00112 return Status; 00113 } 00114 00115 // 00116 // Verify the Fcb. 00117 // 00118 00119 UdfVerifyFcbOperation( IrpContext, Fcb ); 00120 00121 // 00122 // If we don't have a file lock, then get one now. 00123 // 00124 00125 if (Fcb->FileLock == NULL) { UdfCreateFileLock( IrpContext, Fcb, TRUE ); } 00126 00127 // 00128 // Now call the FsRtl routine to do the actual processing of the 00129 // Lock request 00130 // 00131 00132 Status = FsRtlProcessFileLock( Fcb->FileLock, Irp, NULL ); 00133 00134 // 00135 // Set the flag indicating if Fast I/O is possible 00136 // 00137 00138 UdfLockFcb( IrpContext, Fcb ); 00139 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00140 UdfUnlockFcb( IrpContext, Fcb ); 00141 00142 // 00143 // Complete the request. 00144 // 00145 00146 UdfCompleteRequest( IrpContext, NULL, Status ); 00147 return Status; 00148 }

NTSTATUS UdfCommonPnp IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 75 of file udfs/pnp.c.

References _VOLUME_DEVICE_OBJECT::DeviceObject, _IO_STACK_LOCATION::DeviceObject, IoCallDriver, IoGetCurrentIrpStackLocation, IoSkipCurrentIrpStackLocation, Irp, IRP_CONTEXT_FLAG_WAIT, IRP_MN_CANCEL_REMOVE_DEVICE, IRP_MN_QUERY_REMOVE_DEVICE, IRP_MN_REMOVE_DEVICE, IRP_MN_SURPRISE_REMOVAL, _IO_STACK_LOCATION::MinorFunction, NodeType, NTSTATUS(), NULL, SetFlag, _DEVICE_OBJECT::Size, Status, _VCB::TargetDeviceObject, UdfCompleteRequest(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UDFS_NTC_VCB, and _VOLUME_DEVICE_OBJECT::Vcb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00082 : 00083 00084 This is the common routine for doing PnP operations called 00085 by both the fsd and fsp threads 00086 00087 Arguments: 00088 00089 Irp - Supplies the Irp to process 00090 00091 Return Value: 00092 00093 NTSTATUS - The return status for the operation 00094 00095 --*/ 00096 00097 { 00098 NTSTATUS Status; 00099 00100 PIO_STACK_LOCATION IrpSp; 00101 00102 PVOLUME_DEVICE_OBJECT OurDeviceObject; 00103 PVCB Vcb; 00104 00105 // 00106 // Get the current Irp stack location. 00107 // 00108 00109 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00110 00111 // 00112 // Find our Vcb. This is tricky since we have no file object in the Irp. 00113 // 00114 00115 OurDeviceObject = (PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject; 00116 00117 // 00118 // Make sure this device object really is big enough to be a volume device 00119 // object. If it isn't, we need to get out before we try to reference some 00120 // field that takes us past the end of an ordinary device object. 00121 // 00122 00123 if (OurDeviceObject->DeviceObject.Size != sizeof(VOLUME_DEVICE_OBJECT) || 00124 NodeType( &OurDeviceObject->Vcb ) != UDFS_NTC_VCB) { 00125 00126 // 00127 // We were called with something we don't understand. 00128 // 00129 00130 Status = STATUS_INVALID_PARAMETER; 00131 UdfCompleteRequest( IrpContext, Irp, Status ); 00132 return Status; 00133 } 00134 00135 // 00136 // Force all PnP operations to be synchronous. 00137 // 00138 00139 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); 00140 00141 Vcb = &OurDeviceObject->Vcb; 00142 00143 // 00144 // Case on the minor code. 00145 // 00146 00147 switch ( IrpSp->MinorFunction ) { 00148 00149 case IRP_MN_QUERY_REMOVE_DEVICE: 00150 00151 Status = UdfPnpQueryRemove( IrpContext, Irp, Vcb ); 00152 break; 00153 00154 case IRP_MN_SURPRISE_REMOVAL: 00155 00156 Status = UdfPnpSurpriseRemove( IrpContext, Irp, Vcb ); 00157 break; 00158 00159 case IRP_MN_REMOVE_DEVICE: 00160 00161 Status = UdfPnpRemove( IrpContext, Irp, Vcb ); 00162 break; 00163 00164 case IRP_MN_CANCEL_REMOVE_DEVICE: 00165 00166 Status = UdfPnpCancelRemove( IrpContext, Irp, Vcb ); 00167 break; 00168 00169 default: 00170 00171 // 00172 // Just pass the IRP on. As we do not need to be in the 00173 // way on return, ellide ourselves out of the stack. 00174 // 00175 00176 IoSkipCurrentIrpStackLocation( Irp ); 00177 00178 Status = IoCallDriver(Vcb->TargetDeviceObject, Irp); 00179 00180 // 00181 // Cleanup our Irp Context. The driver has completed the Irp. 00182 // 00183 00184 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00185 00186 break; 00187 } 00188 00189 return Status; 00190 }

NTSTATUS UdfCommonQueryInfo IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 156 of file fileinfo.c.

References ASSERT, _IRP::AssociatedIrp, Buffer, CCB_FLAG_OPEN_BY_ID, FALSE, FCB_STATE_INITIALIZED, _FCB::FcbState, _IO_STACK_LOCATION::FileObject, FlagOn, _CCB::Flags, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, NTSTATUS(), PAGED_CODE, _IO_STACK_LOCATION::Parameters, Status, TRUE, TYPE_OF_OPEN, UdfAcquireFileShared, UdfCompleteRequest(), UdfDecodeFileObject(), UdfQueryAlternateNameInfo(), UdfQueryBasicInfo(), UdfQueryEaInfo(), UdfQueryInternalInfo(), UdfQueryNameInfo(), UdfQueryNetworkInfo(), UdfQueryPositionInfo(), UdfQueryStandardInfo(), UdfReleaseFile, UdfVerifyFcbOperation(), UserDirectoryOpen, and UserFileOpen.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00163 : 00164 00165 This is the common routine for query file information called by both the 00166 fsd and fsp threads. 00167 00168 Arguments: 00169 00170 Irp - Supplies the Irp to process. 00171 00172 Return Value: 00173 00174 NTSTATUS - The return status for this operation. 00175 00176 --*/ 00177 00178 { 00179 NTSTATUS Status = STATUS_SUCCESS; 00180 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00181 00182 ULONG Length; 00183 FILE_INFORMATION_CLASS FileInformationClass; 00184 PFILE_ALL_INFORMATION Buffer; 00185 00186 TYPE_OF_OPEN TypeOfOpen; 00187 PFCB Fcb; 00188 PCCB Ccb; 00189 00190 BOOLEAN ReleaseFcb = FALSE; 00191 00192 PAGED_CODE(); 00193 00194 // 00195 // Reference our input parameters to make things easier 00196 // 00197 00198 Length = IrpSp->Parameters.QueryFile.Length; 00199 FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass; 00200 Buffer = Irp->AssociatedIrp.SystemBuffer; 00201 00202 // 00203 // Decode the file object 00204 // 00205 00206 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb ); 00207 00208 // 00209 // Use a try-finally to facilitate cleanup. 00210 // 00211 00212 try { 00213 00214 // 00215 // We only support query on file and directory handles. 00216 // 00217 00218 switch (TypeOfOpen) { 00219 00220 case UserDirectoryOpen : 00221 case UserFileOpen : 00222 00223 // 00224 // Acquire shared access to this file. 00225 // 00226 00227 UdfAcquireFileShared( IrpContext, Fcb ); 00228 ReleaseFcb = TRUE; 00229 00230 ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )); 00231 00232 // 00233 // Make sure the Fcb is in a usable condition. This will raise 00234 // an error condition if the volume is unusable 00235 // 00236 00237 UdfVerifyFcbOperation( IrpContext, Fcb ); 00238 00239 // 00240 // Based on the information class we'll do different 00241 // actions. Each of hte procedures that we're calling fills 00242 // up the output buffer, if possible. They will raise the 00243 // status STATUS_BUFFER_OVERFLOW for an insufficient buffer. 00244 // This is considered a somewhat unusual case and is handled 00245 // more cleanly with the exception mechanism rather than 00246 // testing a return status value for each call. 00247 // 00248 00249 switch (FileInformationClass) { 00250 00251 case FileAllInformation: 00252 00253 // 00254 // We don't allow this operation on a file opened by file Id. 00255 // 00256 00257 if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { 00258 00259 Status = STATUS_INVALID_PARAMETER; 00260 break; 00261 } 00262 00263 // 00264 // In this case go ahead and call the individual routines to 00265 // fill in the buffer. Only the name routine will 00266 // pointer to the output buffer and then call the 00267 // individual routines to fill in the buffer. 00268 // 00269 00270 Length -= (sizeof( FILE_ACCESS_INFORMATION ) + 00271 sizeof( FILE_MODE_INFORMATION ) + 00272 sizeof( FILE_ALIGNMENT_INFORMATION )); 00273 00274 UdfQueryBasicInfo( IrpContext, Fcb, Ccb, &Buffer->BasicInformation, &Length ); 00275 UdfQueryStandardInfo( IrpContext, Fcb, &Buffer->StandardInformation, &Length ); 00276 UdfQueryInternalInfo( IrpContext, Fcb, &Buffer->InternalInformation, &Length ); 00277 UdfQueryEaInfo( IrpContext, Fcb, &Buffer->EaInformation, &Length ); 00278 UdfQueryPositionInfo( IrpContext, IrpSp->FileObject, &Buffer->PositionInformation, &Length ); 00279 Status = UdfQueryNameInfo( IrpContext, IrpSp->FileObject, &Buffer->NameInformation, &Length ); 00280 00281 break; 00282 00283 case FileBasicInformation: 00284 00285 UdfQueryBasicInfo( IrpContext, Fcb, Ccb, (PFILE_BASIC_INFORMATION) Buffer, &Length ); 00286 break; 00287 00288 case FileStandardInformation: 00289 00290 UdfQueryStandardInfo( IrpContext, Fcb, (PFILE_STANDARD_INFORMATION) Buffer, &Length ); 00291 break; 00292 00293 case FileInternalInformation: 00294 00295 UdfQueryInternalInfo( IrpContext, Fcb, (PFILE_INTERNAL_INFORMATION) Buffer, &Length ); 00296 break; 00297 00298 case FileEaInformation: 00299 00300 UdfQueryEaInfo( IrpContext, Fcb, (PFILE_EA_INFORMATION) Buffer, &Length ); 00301 break; 00302 00303 case FilePositionInformation: 00304 00305 UdfQueryPositionInfo( IrpContext, IrpSp->FileObject, (PFILE_POSITION_INFORMATION) Buffer, &Length ); 00306 break; 00307 00308 case FileNameInformation: 00309 00310 // 00311 // We don't allow this operation on a file opened by file Id. 00312 // 00313 00314 if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { 00315 00316 Status = UdfQueryNameInfo( IrpContext, IrpSp->FileObject, (PFILE_NAME_INFORMATION) Buffer, &Length ); 00317 00318 } else { 00319 00320 Status = STATUS_INVALID_PARAMETER; 00321 } 00322 00323 break; 00324 00325 case FileAlternateNameInformation: 00326 00327 if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) { 00328 00329 Status = UdfQueryAlternateNameInfo( IrpContext, Fcb, Ccb, (PFILE_NAME_INFORMATION) Buffer, &Length ); 00330 00331 } else { 00332 00333 Status = STATUS_INVALID_PARAMETER; 00334 } 00335 00336 break; 00337 00338 case FileNetworkOpenInformation: 00339 00340 UdfQueryNetworkInfo( IrpContext, Fcb, Ccb, (PFILE_NETWORK_OPEN_INFORMATION) Buffer, &Length ); 00341 break; 00342 00343 default : 00344 00345 Status = STATUS_INVALID_PARAMETER; 00346 } 00347 00348 break; 00349 00350 default : 00351 00352 Status = STATUS_INVALID_PARAMETER; 00353 } 00354 00355 // 00356 // Set the information field to the number of bytes actually filled in 00357 // and then complete the request 00358 // 00359 00360 Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length; 00361 00362 } finally { 00363 00364 // 00365 // Release the file. 00366 // 00367 00368 if (ReleaseFcb) { 00369 00370 UdfReleaseFile( IrpContext, Fcb ); 00371 } 00372 } 00373 00374 // 00375 // Complete the request if we didn't raise. 00376 // 00377 00378 UdfCompleteRequest( IrpContext, Irp, Status ); 00379 00380 return Status; 00381 }

NTSTATUS UdfCommonQueryVolInfo IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 82 of file volinfo.c.

References _IRP::AssociatedIrp, FALSE, _IO_STACK_LOCATION::FileObject, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, NTSTATUS(), PAGED_CODE, _IO_STACK_LOCATION::Parameters, Status, TYPE_OF_OPEN, UdfAcquireVcbShared, UdfCompleteRequest(), UdfDecodeFileObject(), UdfQueryFsAttributeInfo(), UdfQueryFsDeviceInfo(), UdfQueryFsSizeInfo(), UdfQueryFsVolumeInfo(), UdfReleaseVcb, UdfVerifyVcb(), UnopenedFileObject, and _FCB::Vcb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00089 : 00090 00091 This is the common routine for querying volume information called by both 00092 the fsd and fsp threads. 00093 00094 Arguments: 00095 00096 Irp - Supplies the Irp being processed 00097 00098 Return Value: 00099 00100 NTSTATUS - The return status for the operation 00101 00102 --*/ 00103 00104 { 00105 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00106 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00107 00108 ULONG Length; 00109 00110 TYPE_OF_OPEN TypeOfOpen; 00111 PFCB Fcb; 00112 PCCB Ccb; 00113 00114 PAGED_CODE(); 00115 00116 // 00117 // Reference our input parameters to make things easier 00118 // 00119 00120 Length = IrpSp->Parameters.QueryVolume.Length; 00121 00122 // 00123 // Decode the file object and fail if this an unopened file object. 00124 // 00125 00126 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb ); 00127 00128 if (TypeOfOpen == UnopenedFileObject) { 00129 00130 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER ); 00131 return STATUS_INVALID_PARAMETER; 00132 } 00133 00134 // 00135 // Acquire the Vcb for this volume. 00136 // 00137 00138 UdfAcquireVcbShared( IrpContext, Fcb->Vcb, FALSE ); 00139 00140 // 00141 // Use a try-finally to facilitate cleanup. 00142 // 00143 00144 try { 00145 00146 // 00147 // Verify the Vcb. 00148 // 00149 00150 UdfVerifyVcb( IrpContext, Fcb->Vcb ); 00151 00152 // 00153 // Based on the information class we'll do different actions. Each 00154 // of the procedures that we're calling fills up the output buffer 00155 // if possible and returns true if it successfully filled the buffer 00156 // and false if it couldn't wait for any I/O to complete. 00157 // 00158 00159 switch (IrpSp->Parameters.QueryVolume.FsInformationClass) { 00160 00161 case FileFsSizeInformation: 00162 00163 Status = UdfQueryFsSizeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); 00164 break; 00165 00166 case FileFsVolumeInformation: 00167 00168 Status = UdfQueryFsVolumeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); 00169 break; 00170 00171 case FileFsDeviceInformation: 00172 00173 Status = UdfQueryFsDeviceInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); 00174 break; 00175 00176 case FileFsAttributeInformation: 00177 00178 Status = UdfQueryFsAttributeInfo( IrpContext, Fcb->Vcb, Irp->AssociatedIrp.SystemBuffer, &Length ); 00179 break; 00180 } 00181 00182 // 00183 // Set the information field to the number of bytes actually filled in 00184 // 00185 00186 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length; 00187 00188 } finally { 00189 00190 // 00191 // Release the Vcb. 00192 // 00193 00194 UdfReleaseVcb( IrpContext, Fcb->Vcb ); 00195 } 00196 00197 // 00198 // Complete the request if we didn't raise. 00199 // 00200 00201 UdfCompleteRequest( IrpContext, Irp, Status ); 00202 00203 return Status; 00204 }

NTSTATUS UdfCommonRead IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 68 of file udfs/read.c.

References Add2Ptr, ASSERT, BooleanFlagOn, BytesFromSectors, _UDF_DATA::CacheManagerCallbacks, CcCopyRead(), CcInitializeCacheMap(), CcMdlRead(), CcSetReadAheadGranularity(), ClearFlag, _FILE_OBJECT::CurrentByteOffset, DebugUnwind, _FCB::EmbeddedOffset, _FCB::EmbeddedVsn, ExGetCurrentResourceThread, FALSE, FCB_STATE_EMBEDDED_DATA, _FCB::FcbState, _IO_STACK_LOCATION::FileObject, FlagOn, _FILE_OBJECT::Flags, _IRP::Flags, FO_SYNCHRONOUS_IO, FsRtlCheckLockForReadAccess(), FsRtlCheckOplock(), FsRtlNormalizeNtstatus(), IoGetCurrentIrpStackLocation, IoIsErrorUserInduced, _IRP::IoStatus, Irp, IRP_CONTEXT_FLAG_ALLOC_IO, IRP_CONTEXT_FLAG_WAIT, IRP_MN_MDL, IRP_NOCACHE, IRP_PAGING_IO, KeInitializeEvent, _IRP::MdlAddress, _VCB::MetadataFcb, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PCC_FILE_SIZES, _FILE_OBJECT::PrivateCacheMap, READ_AHEAD_GRANULARITY, SafeZeroMemory, SectorAlign, SectorOffset, SetFlag, Status, SynchronousIo, TRUE, try_leave, TYPE_OF_OPEN, UDF_IO_CONTEXT, UdfAcquireFileShared, UdfAcquireFileSharedStarveExclusive, UdfAllocateIoContext, UdfCompleteRequest(), UdfData, UdfDecodeFileObject(), UdfFsdPostRequest(), UdfMapUserBuffer, UdfNonCachedRead(), UdfNormalizeAndRaiseStatus(), UdfOplockComplete(), UdfPrePostIrp(), UdfRaiseStatus(), UdfReleaseFile, UdfVerifyFcbOperation(), UnopenedFileObject, UserDirectoryOpen, UserFileOpen, UserVolumeOpen, and _FCB::Vcb.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00075 : 00076 00077 This is the common entry point for NtReadFile calls. For synchronous requests, 00078 CommonRead will complete the request in the current thread. If not 00079 synchronous the request will be passed to the Fsp if there is a need to 00080 block. 00081 00082 Arguments: 00083 00084 Irp - Supplies the Irp to process 00085 00086 Return Value: 00087 00088 NTSTATUS - The result of this operation. 00089 00090 --*/ 00091 00092 { 00093 NTSTATUS Status; 00094 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00095 00096 TYPE_OF_OPEN TypeOfOpen; 00097 PFCB Fcb; 00098 PCCB Ccb; 00099 PVCB Vcb; 00100 00101 BOOLEAN Wait; 00102 ULONG PagingIo; 00103 ULONG SynchronousIo; 00104 ULONG NonCachedIo; 00105 00106 LONGLONG StartingOffset; 00107 LONGLONG ByteRange; 00108 ULONG ByteCount; 00109 ULONG ReadByteCount; 00110 ULONG OriginalByteCount; 00111 00112 PVOID SystemBuffer, UserBuffer; 00113 00114 BOOLEAN ReleaseFile = TRUE; 00115 00116 PFILE_OBJECT MappingFileObject; 00117 00118 UDF_IO_CONTEXT LocalIoContext; 00119 00120 PAGED_CODE(); 00121 00122 // 00123 // If this is a zero length read then return SUCCESS immediately. 00124 // 00125 00126 if (IrpSp->Parameters.Read.Length == 0) { 00127 00128 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00129 return STATUS_SUCCESS; 00130 } 00131 00132 // 00133 // Decode the file object and verify we support read on this. It 00134 // must be a user file, stream file or volume file (for a data disk). 00135 // 00136 00137 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb ); 00138 00139 Vcb = Fcb->Vcb; 00140 00141 if ((TypeOfOpen == UnopenedFileObject) || (TypeOfOpen == UserDirectoryOpen)) { 00142 00143 UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST ); 00144 return STATUS_INVALID_DEVICE_REQUEST; 00145 } 00146 00147 // 00148 // Examine our input parameters to determine if this is noncached and/or 00149 // a paging io operation. 00150 // 00151 00152 Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); 00153 PagingIo = FlagOn( Irp->Flags, IRP_PAGING_IO ); 00154 NonCachedIo = FlagOn( Irp->Flags, IRP_NOCACHE ); 00155 SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO ); 00156 00157 // 00158 // Extract the range of the Io. 00159 // 00160 00161 StartingOffset = IrpSp->Parameters.Read.ByteOffset.QuadPart; 00162 OriginalByteCount = ByteCount = IrpSp->Parameters.Read.Length; 00163 00164 ByteRange = StartingOffset + ByteCount; 00165 00166 // 00167 // Make sure that Dasd access is always non-cached. 00168 // 00169 00170 if (TypeOfOpen == UserVolumeOpen) { 00171 00172 NonCachedIo = TRUE; 00173 } 00174 00175 // 00176 // Acquire the file shared to perform the read. If we are doing paging IO, 00177 // it may be the case that we would have a deadlock imminent because we may 00178 // block on shared access, so starve out any exclusive waiters. This requires 00179 // a degree of caution - we believe that any paging IO bursts will recede and 00180 // allow the exclusive waiter in. 00181 // 00182 00183 if (PagingIo) { 00184 00185 UdfAcquireFileSharedStarveExclusive( IrpContext, Fcb ); 00186 00187 } else { 00188 00189 UdfAcquireFileShared( IrpContext, Fcb ); 00190 } 00191 00192 // 00193 // Use a try-finally to facilitate cleanup. 00194 // 00195 00196 try { 00197 00198 // 00199 // Verify the Fcb. 00200 // 00201 00202 UdfVerifyFcbOperation( IrpContext, Fcb ); 00203 00204 // 00205 // If this is a user request then verify the oplock and filelock state. 00206 // 00207 00208 if (TypeOfOpen == UserFileOpen) { 00209 00210 // 00211 // We check whether we can proceed 00212 // based on the state of the file oplocks. 00213 // 00214 00215 Status = FsRtlCheckOplock( &Fcb->Oplock, 00216 Irp, 00217 IrpContext, 00218 UdfOplockComplete, 00219 UdfPrePostIrp ); 00220 00221 // 00222 // If the result is not STATUS_SUCCESS then the Irp was completed 00223 // elsewhere. 00224 // 00225 00226 if (Status != STATUS_SUCCESS) { 00227 00228 Irp = NULL; 00229 IrpContext = NULL; 00230 00231 try_leave( Status ); 00232 } 00233 00234 if (!PagingIo && 00235 (Fcb->FileLock != NULL) && 00236 !FsRtlCheckLockForReadAccess( Fcb->FileLock, Irp )) { 00237 00238 try_leave( Status = STATUS_FILE_LOCK_CONFLICT ); 00239 } 00240 } 00241 00242 // 00243 // Complete the request if it begins beyond the end of file. 00244 // 00245 00246 if (StartingOffset >= Fcb->FileSize.QuadPart) { 00247 00248 try_leave( Status = STATUS_END_OF_FILE ); 00249 } 00250 00251 // 00252 // Truncate the read if it extends beyond the end of the file. 00253 // 00254 00255 if (ByteRange > Fcb->FileSize.QuadPart) { 00256 00257 ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset); 00258 ByteRange = Fcb->FileSize.QuadPart; 00259 } 00260 00261 // 00262 // Now if the data is embedded in the ICB, map through the metadata 00263 // stream to retrieve the bytes. 00264 // 00265 00266 if (FlagOn( Fcb->FcbState, FCB_STATE_EMBEDDED_DATA )) { 00267 00268 // 00269 // The metadata stream better be here by now. 00270 // 00271 00272 ASSERT( Vcb->MetadataFcb->FileObject != NULL ); 00273 00274 // 00275 // Bias our starting offset by the offset of the ICB in the metadata 00276 // stream plus the offset of the data bytes in that ICB. Obviously, 00277 // we aren't doing non-cached IO here. 00278 // 00279 00280 StartingOffset += (BytesFromSectors( Vcb, Fcb->EmbeddedVsn ) + Fcb->EmbeddedOffset); 00281 MappingFileObject = Vcb->MetadataFcb->FileObject; 00282 NonCachedIo = FALSE; 00283 00284 // 00285 // We are mapping through the caller's fileobject 00286 // 00287 00288 } else { 00289 00290 MappingFileObject = IrpSp->FileObject; 00291 } 00292 00293 // 00294 // Handle the non-cached read first. 00295 // 00296 00297 if (NonCachedIo) { 00298 00299 // 00300 // If we have an unaligned transfer then post this request if 00301 // we can't wait. Unaligned means that the starting offset 00302 // is not on a sector boundary or the read is not integral 00303 // sectors. 00304 // 00305 00306 ReadByteCount = SectorAlign( Vcb, ByteCount ); 00307 00308 if (SectorOffset( Vcb, StartingOffset ) || 00309 (ReadByteCount > OriginalByteCount)) { 00310 00311 if (!Wait) { 00312 00313 UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT ); 00314 } 00315 00316 // 00317 // Make sure we don't overwrite the buffer. 00318 // 00319 00320 ReadByteCount = ByteCount; 00321 } 00322 00323 // 00324 // Initialize the IoContext for the read. 00325 // If there is a context pointer, we need to make sure it was 00326 // allocated and not a stale stack pointer. 00327 // 00328 00329 if (IrpContext->IoContext == NULL || 00330 !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO )) { 00331 00332 // 00333 // If we can wait, use the context on the stack. Otherwise 00334 // we need to allocate one. 00335 // 00336 00337 if (Wait) { 00338 00339 IrpContext->IoContext = &LocalIoContext; 00340 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); 00341 00342 } else { 00343 00344 IrpContext->IoContext = UdfAllocateIoContext(); 00345 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); 00346 } 00347 } 00348 00349 RtlZeroMemory( IrpContext->IoContext, sizeof( UDF_IO_CONTEXT )); 00350 00351 // 00352 // Store whether we allocated this context structure in the structure 00353 // itself. 00354 // 00355 00356 IrpContext->IoContext->AllocatedContext = 00357 BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); 00358 00359 if (Wait) { 00360 00361 KeInitializeEvent( &IrpContext->IoContext->SyncEvent, 00362 NotificationEvent, 00363 FALSE ); 00364 00365 } else { 00366 00367 IrpContext->IoContext->ResourceThreadId = ExGetCurrentResourceThread(); 00368 IrpContext->IoContext->Resource = Fcb->Resource; 00369 IrpContext->IoContext->RequestedByteCount = ByteCount; 00370 } 00371 00372 Irp->IoStatus.Information = ReadByteCount; 00373 00374 // 00375 // Call the NonCacheIo routine to perform the actual read. 00376 // 00377 00378 Status = UdfNonCachedRead( IrpContext, Fcb, StartingOffset, ReadByteCount ); 00379 00380 // 00381 // Don't complete this request now if STATUS_PENDING was returned. 00382 // 00383 00384 if (Status == STATUS_PENDING) { 00385 00386 Irp = NULL; 00387 ReleaseFile = FALSE; 00388 00389 // 00390 // Test is we should zero part of the buffer or update the 00391 // synchronous file position. 00392 // 00393 00394 } else { 00395 00396 // 00397 // Convert any unknown error code to IO_ERROR. 00398 // 00399 00400 if (!NT_SUCCESS( Status )) { 00401 00402 // 00403 // Set the information field to zero. 00404 // 00405 00406 Irp->IoStatus.Information = 0; 00407 00408 // 00409 // Raise if this is a user induced error. 00410 // 00411 00412 if (IoIsErrorUserInduced( Status )) { 00413 00414 UdfRaiseStatus( IrpContext, Status ); 00415 } 00416 00417 Status = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR ); 00418 00419 // 00420 // Check if there is any portion of the user's buffer to zero. 00421 // 00422 00423 } else if (ReadByteCount != ByteCount) { 00424 00425 UdfMapUserBuffer( IrpContext, &UserBuffer ); 00426 00427 SafeZeroMemory( IrpContext, 00428 Add2Ptr( UserBuffer, 00429 ByteCount, 00430 PVOID ), 00431 ReadByteCount - ByteCount ); 00432 00433 Irp->IoStatus.Information = ByteCount; 00434 } 00435 00436 // 00437 // Update the file position if this is a synchronous request. 00438 // 00439 00440 if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) { 00441 00442 IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange; 00443 } 00444 } 00445 00446 try_leave( NOTHING ); 00447 } 00448 00449 // 00450 // Handle the cached case. Start by initializing the private 00451 // cache map. 00452 // 00453 00454 if (MappingFileObject->PrivateCacheMap == NULL) { 00455 00456 // 00457 // The metadata Fcb stream was fired up before any data read. We should never 00458 // see it here. 00459 // 00460 00461 ASSERT( MappingFileObject != Vcb->MetadataFcb->FileObject ); 00462 00463 // 00464 // Now initialize the cache map. 00465 // 00466 00467 CcInitializeCacheMap( IrpSp->FileObject, 00468 (PCC_FILE_SIZES) &Fcb->AllocationSize, 00469 FALSE, 00470 &UdfData.CacheManagerCallbacks, 00471 Fcb ); 00472 00473 CcSetReadAheadGranularity( IrpSp->FileObject, READ_AHEAD_GRANULARITY ); 00474 } 00475 00476 // 00477 // Read from the cache if this is not an Mdl read. 00478 // 00479 00480 if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) { 00481 00482 // 00483 // If we are in the Fsp now because we had to wait earlier, 00484 // we must map the user buffer, otherwise we can use the 00485 // user's buffer directly. 00486 // 00487 00488 UdfMapUserBuffer( IrpContext, &SystemBuffer); 00489 00490 // 00491 // Now try to do the copy. 00492 // 00493 00494 if (!CcCopyRead( MappingFileObject, 00495 (PLARGE_INTEGER) &StartingOffset, 00496 ByteCount, 00497 Wait, 00498 SystemBuffer, 00499 &Irp->IoStatus )) { 00500 00501 try_leave( Status = STATUS_CANT_WAIT ); 00502 } 00503 00504 // 00505 // If the call didn't succeed, raise the error status 00506 // 00507 00508 if (!NT_SUCCESS( Irp->IoStatus.Status )) { 00509 00510 UdfNormalizeAndRaiseStatus( IrpContext, Irp->IoStatus.Status ); 00511 } 00512 00513 Status = Irp->IoStatus.Status; 00514 00515 // 00516 // Otherwise perform the MdlRead operation. 00517 // 00518 00519 } else { 00520 00521 CcMdlRead( MappingFileObject, 00522 (PLARGE_INTEGER) &StartingOffset, 00523 ByteCount, 00524 &Irp->MdlAddress, 00525 &Irp->IoStatus ); 00526 00527 Status = Irp->IoStatus.Status; 00528 } 00529 00530 // 00531 // Update the current file position in the user file object. 00532 // 00533 00534 if (SynchronousIo && !PagingIo && NT_SUCCESS( Status )) { 00535 00536 IrpSp->FileObject->CurrentByteOffset.QuadPart = ByteRange; 00537 } 00538 00539 } finally { 00540 00541 DebugUnwind( "UdfCommonRead" ); 00542 00543 // 00544 // Release the Fcb. 00545 // 00546 00547 if (ReleaseFile) { 00548 00549 UdfReleaseFile( IrpContext, Fcb ); 00550 } 00551 } 00552 00553 // 00554 // Post the request if we got CANT_WAIT. 00555 // 00556 00557 if (Status == STATUS_CANT_WAIT) { 00558 00559 Status = UdfFsdPostRequest( IrpContext, Irp ); 00560 00561 // 00562 // Otherwise complete the request. 00563 // 00564 00565 } else { 00566 00567 UdfCompleteRequest( IrpContext, Irp, Status ); 00568 } 00569 00570 return Status; 00571 }

NTSTATUS UdfCommonSetInfo IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 385 of file fileinfo.c.

References _DEVICE_OBJECT::AlignmentRequirement, _IRP::AssociatedIrp, Buffer, _FILE_OBJECT::CurrentByteOffset, _IO_STACK_LOCATION::DeviceObject, _IO_STACK_LOCATION::FileObject, FlagOn, _FILE_OBJECT::Flags, FO_NO_INTERMEDIATE_BUFFERING, IoGetCurrentIrpStackLocation, Irp, NTSTATUS(), PAGED_CODE, _IO_STACK_LOCATION::Parameters, Status, try_leave, TYPE_OF_OPEN, UdfAcquireFileShared, UdfCompleteRequest(), UdfDecodeFileObject(), UdfLockFcb, UdfReleaseFile, UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

Referenced by UdfFsdDispatch(), and UdfFspDispatch().

00392 : 00393 00394 This is the common routine for set file information called by both the 00395 fsd and fsp threads. We only support operations which set the file position. 00396 00397 Arguments: 00398 00399 Irp - Supplies the Irp to process. 00400 00401 Return Value: 00402 00403 NTSTATUS - The return status for this operation. 00404 00405 --*/ 00406 00407 { 00408 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00409 00410 TYPE_OF_OPEN TypeOfOpen; 00411 PFCB Fcb; 00412 PCCB Ccb; 00413 00414 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00415 00416 PFILE_POSITION_INFORMATION Buffer; 00417 00418 PAGED_CODE(); 00419 00420 // 00421 // Decode the file object 00422 // 00423 00424 TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb ); 00425 00426 // 00427 // We only support a SetPositionInformation on a user file. 00428 // 00429 00430 if ((TypeOfOpen != UserFileOpen) || 00431 (IrpSp->Parameters.QueryFile.FileInformationClass != FilePositionInformation)) { 00432 00433 UdfCompleteRequest( IrpContext, Irp, Status ); 00434 return Status; 00435 } 00436 00437 // 00438 // Acquire shared access to this file. 00439 // 00440 00441 UdfAcquireFileShared( IrpContext, Fcb ); 00442 00443 try { 00444 00445 // 00446 // Make sure the Fcb is in a usable condition. This 00447 // will raise an error condition if the fcb is unusable 00448 // 00449 00450 UdfVerifyFcbOperation( IrpContext, Fcb ); 00451 00452 Buffer = Irp->AssociatedIrp.SystemBuffer; 00453 00454 // 00455 // Check if the file does not use intermediate buffering. If it 00456 // does not use intermediate buffering then the new position we're 00457 // supplied must be aligned properly for the device 00458 // 00459 00460 if (FlagOn( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ) && 00461 ((Buffer->CurrentByteOffset.LowPart & IrpSp->DeviceObject->AlignmentRequirement) != 0)) { 00462 00463 try_leave( NOTHING ); 00464 } 00465 00466 // 00467 // The input parameter is fine so set the current byte offset and 00468 // complete the request 00469 // 00470 00471 // 00472 // Lock the Fcb to provide synchronization. 00473 // 00474 00475 UdfLockFcb( IrpContext, Fcb ); 00476 IrpSp->FileObject->CurrentByteOffset = Buffer->CurrentByteOffset; 00477 UdfUnlockFcb( IrpContext, Fcb ); 00478 00479 Status = STATUS_SUCCESS; 00480 00481 } finally { 00482 00483 UdfReleaseFile( IrpContext, Fcb ); 00484 } 00485 00486 // 00487 // Complete the request if there was no raise. 00488 // 00489 00490 UdfCompleteRequest( IrpContext, Irp, Status ); 00491 return Status; 00492 }

NTSTATUS UdfCompleteMdl IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 285 of file udfs/cachesup.c.

References CcMdlReadComplete(), IoGetCurrentIrpStackLocation, Irp, _IRP::MdlAddress, NULL, PAGED_CODE, and UdfCompleteRequest().

Referenced by UdfFsdDispatch().

00292 : 00293 00294 This routine performs the function of completing Mdl reads. 00295 It should be called only from UdfCommonRead. 00296 00297 Arguments: 00298 00299 Irp - Supplies the originating Irp. 00300 00301 Return Value: 00302 00303 NTSTATUS - Will always be STATUS_SUCCESS. 00304 00305 --*/ 00306 00307 { 00308 PFILE_OBJECT FileObject; 00309 00310 PAGED_CODE(); 00311 00312 // 00313 // Do completion processing. 00314 // 00315 00316 FileObject = IoGetCurrentIrpStackLocation( Irp )->FileObject; 00317 00318 CcMdlReadComplete( FileObject, Irp->MdlAddress ); 00319 00320 // 00321 // Mdl is now deallocated. 00322 // 00323 00324 Irp->MdlAddress = NULL; 00325 00326 // 00327 // Complete the request and exit right away. 00328 // 00329 00330 UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS ); 00331 00332 return STATUS_SUCCESS; 00333 }

NTSTATUS UdfCompletePcb IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PPCB  Pcb
 

Definition at line 804 of file allocsup.c.

References ASSERT, ASSERT_IRP_CONTEXT, ASSERT_PCB, ASSERT_VCB, Dbg, DebugTrace, FALSE, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, Physical, Status, UdfFreePool(), UdfLoadSparingTables(), and Virtual.

Referenced by UdfMountVolume(), and UdfVerifyVolume().

00812 : 00813 00814 This routine completes initialization of a Pcb which has been filled 00815 in with partition descriptors. Initialization-time data such as the 00816 physical partition descriptors will be returned to the system. 00817 00818 Arguments: 00819 00820 Vcb - Vcb of the volume the Pcb describes 00821 00822 Pcb - Pcb being completed 00823 00824 Return Value: 00825 00826 NTSTATUS according to whether intialization completion was succesful 00827 00828 --*/ 00829 00830 { 00831 ULONG Reference; 00832 00833 NTSTATUS Status; 00834 00835 PAGED_CODE(); 00836 00837 // 00838 // Check inputs 00839 // 00840 00841 ASSERT_IRP_CONTEXT( IrpContext ); 00842 ASSERT_VCB( Vcb ); 00843 ASSERT_PCB( Pcb ); 00844 00845 DebugTrace(( +1, Dbg, "UdfCompletePcb, Vcb %08x Pcb %08x\n", Vcb, Pcb )); 00846 00847 // 00848 // Complete intialization all physical partitions 00849 // 00850 00851 for (Reference = 0; 00852 Reference < Pcb->Partitions; 00853 Reference++) { 00854 00855 DebugTrace(( 0, Dbg, "UdfCompletePcb, Examining Ref %u (type %u)!\n", Reference, Pcb->Partition[Reference].Type)); 00856 00857 switch (Pcb->Partition[Reference].Type) { 00858 00859 case Physical: 00860 00861 if (Pcb->Partition[Reference].Physical.PartitionDescriptor == NULL) { 00862 00863 DebugTrace(( 0, Dbg, 00864 "UdfCompletePcb, ... but didn't find Partition# %u!\n", 00865 Pcb->Partition[Reference].Physical.PartitionNumber )); 00866 00867 DebugTrace(( -1, Dbg, "UdfCompletePcb -> STATUS_DISK_CORRUPT_ERROR\n" )); 00868 00869 return STATUS_DISK_CORRUPT_ERROR; 00870 } 00871 00872 Pcb->Partition[Reference].Physical.Start = 00873 Pcb->Partition[Reference].Physical.PartitionDescriptor->Start; 00874 Pcb->Partition[Reference].Physical.Length = 00875 Pcb->Partition[Reference].Physical.PartitionDescriptor->Length; 00876 00877 00878 // 00879 // Retrieve the sparing information at this point if appropriate. 00880 // We have to do this when we can map logical -> physical blocks. 00881 // 00882 00883 if (Pcb->Partition[Reference].Physical.SparingMap) { 00884 00885 Status = UdfLoadSparingTables( IrpContext, 00886 Vcb, 00887 Pcb, 00888 Reference ); 00889 00890 if (!NT_SUCCESS( Status )) { 00891 00892 DebugTrace(( -1, Dbg, 00893 "UdfCompletePcb -> %08x\n", Status )); 00894 return Status; 00895 } 00896 } 00897 00898 // 00899 // We will not need the descriptor or sparing map anymore, so drop them. 00900 // 00901 00902 UdfFreePool( &Pcb->Partition[Reference].Physical.PartitionDescriptor ); 00903 UdfFreePool( &Pcb->Partition[Reference].Physical.SparingMap ); 00904 break; 00905 00906 case Virtual: 00907 break; 00908 00909 default: 00910 00911 ASSERT(FALSE); 00912 break; 00913 } 00914 } 00915 00916 DebugTrace(( -1, Dbg, "UdfCompletePcb -> STATUS_SUCCESS\n" )); 00917 00918 return STATUS_SUCCESS; 00919 }

VOID UdfCompleteRequest IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PIRP Irp  OPTIONAL,
IN NTSTATUS  Status
 

Definition at line 809 of file udfdata.c.

References ASSERT_OPTIONAL_IRP, ASSERT_OPTIONAL_IRP_CONTEXT, FALSE, FlagOn, _IRP::Flags, IO_CD_ROM_INCREMENT, IoCompleteRequest, _IRP::IoStatus, Irp, IRP_INPUT_OPERATION, NT_ERROR, Status, and UdfCleanupIrpContext().

Referenced by UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteMdl(), UdfDismountVolume(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfFsdDispatch(), UdfFspClose(), UdfFspDispatch(), UdfInvalidateVolumes(), UdfIsPathnameValid(), UdfIsVolumeDirty(), UdfIsVolumeMounted(), UdfLockVolume(), UdfMountVolume(), UdfNotifyChangeDirectory(), UdfOplockComplete(), UdfOplockRequest(), UdfPerformVerify(), UdfPnpCancelRemove(), UdfPnpQueryRemove(), UdfPnpRemove(), UdfPnpSurpriseRemove(), UdfProcessException(), UdfQueryDirectory(), UdfQueueClose(), UdfUnlockVolume(), UdfUserFsctl(), and UdfVerifyVolume().

00817 : 00818 00819 This routine completes a Irp and cleans up the IrpContext. Either or 00820 both of these may not be specified. 00821 00822 Arguments: 00823 00824 Irp - Supplies the Irp being processed. 00825 00826 Status - Supplies the status to complete the Irp with 00827 00828 Return Value: 00829 00830 None. 00831 00832 --*/ 00833 00834 { 00835 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00836 ASSERT_OPTIONAL_IRP( Irp ); 00837 00838 // 00839 // Cleanup the IrpContext if passed in here. 00840 // 00841 00842 if (ARGUMENT_PRESENT( IrpContext )) { 00843 00844 UdfCleanupIrpContext( IrpContext, FALSE ); 00845 } 00846 00847 // 00848 // If we have an Irp then complete the irp. 00849 // 00850 00851 if (ARGUMENT_PRESENT( Irp )) { 00852 00853 // 00854 // Clear the information field in case we have used this Irp 00855 // internally. 00856 // 00857 00858 if (NT_ERROR( Status ) && 00859 FlagOn( Irp->Flags, IRP_INPUT_OPERATION )) { 00860 00861 Irp->IoStatus.Information = 0; 00862 } 00863 00864 Irp->IoStatus.Status = Status; 00865 IoCompleteRequest( Irp, IO_CD_ROM_INCREMENT ); 00866 } 00867 00868 return; 00869 }

USHORT UdfComputeCrc16 IN PUCHAR  Buffer,
IN ULONG  ByteCount
 

Referenced by UdfVerifyDescriptor().

USHORT UdfComputeCrc16Uni PWCHAR  Buffer,
ULONG  CharCount
 

Definition at line 1194 of file udfdata.c.

References Buffer, UdfCrcTable, and USHORT.

Referenced by UdfGenerate8dot3Name(), and UdfRenderNameToLegalUnicode().

01201 : 01202 01203 This routine generates a 16 bit CRC of the input buffer in accordance 01204 with the precomputed CRC table. 01205 01206 It performs a byte-order independent crc (hi then lo). This is a bit 01207 suspect, but is called for in the specification. 01208 01209 Arguments: 01210 01211 Buffer - Pointer to the buffer to generate the CRC for. 01212 01213 ShortCount - Number of wide characters in the buffer. 01214 01215 Return Value: 01216 01217 USHORT - The 16bit CRC 01218 01219 --*/ 01220 01221 { 01222 USHORT Crc = 0; 01223 01224 // 01225 // Byte order independent CRC, hi byte to low byte per character. 01226 // 01227 01228 while (CharCount-- > 0) { 01229 01230 Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer >> 8)) & 0xff] ^ (Crc << 8); 01231 Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer++ & 0xff)) & 0xff] ^ (Crc << 8); 01232 } 01233 01234 return Crc; 01235 }

VOID UdfConvertCS0DstringToUnicode IN PIRP_CONTEXT  IrpContext,
IN PUCHAR  Dstring,
IN UCHAR Length  OPTIONAL,
IN UCHAR FieldLength  OPTIONAL,
IN OUT PUNICODE_STRING  Name
 

Definition at line 689 of file namesup.c.

References ASSERT, ASSERT_IRP_CONTEXT, CHAR, Min, Name, PAGED_CODE, SwapCopyUchar2, UdfCS0DstringUnicodeSize(), and Unicode.

Referenced by UdfUpdateDirNames(), and UdfUpdateVolumeLabel().

00699 : 00700 00701 This routine will convert the CS0 input dstring (1/7.2.12) to Unicode. We assume that 00702 the length is sane. 00703 00704 This "compression" in CS0 is really just a special case hack for ASCII. 00705 00706 Arguments: 00707 00708 Dstring - the input dstring field 00709 00710 Length - length of the dstring. If unspecified, we assume that the characters come 00711 from a proper 1/7.2.12 dstring that specifies length in the last character of the 00712 field. 00713 00714 FieldLength - length of the dstring field. If unspecified, we assume that the characters 00715 come from an uncounted length of CS0 characters and that the Length parameter is 00716 specified. 00717 00718 Name - the output Unicode string 00719 00720 Return Value: 00721 00722 None. 00723 00724 --*/ 00725 00726 { 00727 ULONG CompressID; 00728 ULONG UnicodeIndex, ByteIndex; 00729 PWCHAR Unicode = Name->Buffer; 00730 00731 UCHAR NameLength; 00732 ULONG CopyNameLength; 00733 00734 PAGED_CODE(); 00735 00736 // 00737 // Check input. 00738 // 00739 00740 ASSERT_IRP_CONTEXT( IrpContext ); 00741 00742 CompressID = *Dstring; 00743 00744 // 00745 // If the length is unspecified, this is a real 1/7.2.12 dstring and the length is in 00746 // the last character of the field. 00747 // 00748 00749 ASSERT( Length || FieldLength ); 00750 00751 if (Length) { 00752 00753 NameLength = FieldLength = Length; 00754 00755 } else { 00756 00757 NameLength = *(Dstring + FieldLength - 1); 00758 } 00759 00760 // 00761 // If the caller specified a size, they should have made sure the buffer is big enough. 00762 // Otherwise, we will trim to fit. 00763 // 00764 00765 ASSERT( Length == 0 || Name->MaximumLength >= UdfCS0DstringUnicodeSize( IrpContext, Dstring, NameLength ) ); 00766 00767 // 00768 // Decide how many UNICODE bytes to "copy". 00769 // 00770 00771 CopyNameLength = Min( Name->MaximumLength, UdfCS0DstringUnicodeSize( IrpContext, Dstring, NameLength )); 00772 00773 // 00774 // Reset the name length and advance over the compression ID in the dstring. 00775 // 00776 00777 Name->Length = 0; 00778 Dstring++; 00779 00780 // 00781 // Loop through all the bytes. 00782 // 00783 00784 while (CopyNameLength > Name->Length) { 00785 00786 if (CompressID == 16) { 00787 00788 // 00789 // We're little endian, and this is the single place in the entire UDF/ISO standard 00790 // where they use big endian. 00791 // 00792 // Thank you. Thank you very much. 00793 // 00794 // Do an unaligned swapcopy of this 16bit value. 00795 // 00796 00797 SwapCopyUchar2( Unicode, Dstring ); 00798 Dstring += sizeof(WCHAR); 00799 00800 } else { 00801 00802 // 00803 // Drop the byte into the low bits. 00804 // 00805 00806 *Unicode = *Dstring; 00807 Dstring += sizeof(CHAR); 00808 } 00809 00810 Name->Length += sizeof(WCHAR); 00811 Unicode++; 00812 } 00813 00814 return; 00815 }

INLINE VOID UdfConvertUdfTimeToNtTime IN PIRP_CONTEXT  IrpContext,
IN PTIMESTAMP  UdfTime,
OUT PLARGE_INTEGER  NtTime
 

Definition at line 1921 of file udfprocs.h.

References PTIMESTAMP, RtlTimeFieldsToTime(), TIMESTAMP_Z_MAX, TIMESTAMP_Z_MIN, and TIMESTAMP_Z_NONE.

Referenced by UdfUpdateTimestampsFromIcbContext().

01926 { 01927 TIME_FIELDS TimeField; 01928 01929 TimeField.Year = UdfTime->Year; 01930 TimeField.Month = UdfTime->Month; 01931 TimeField.Day = UdfTime->Day; 01932 TimeField.Hour = UdfTime->Hour; 01933 TimeField.Minute = UdfTime->Minute; 01934 TimeField.Second = UdfTime->Second; 01935 01936 // 01937 // This is where it gets hairy. For some unholy reason, ISO 13346 timestamps 01938 // carve the right of the decimal point up into three fields of precision 01939 // 10-2, 10-4, and 10-6, each ranging from 0-99. Lawdy. 01940 // 01941 // To make it easier, since they cannot cause a wrap into the next second, 01942 // just save it all up and add it in after the conversion. 01943 // 01944 01945 TimeField.Milliseconds = 0; 01946 01947 if (UdfTime->Type <= 1 && 01948 ((UdfTime->Zone >= TIMESTAMP_Z_MIN && UdfTime->Zone <= TIMESTAMP_Z_MAX) || 01949 UdfTime->Zone == TIMESTAMP_Z_NONE) && 01950 RtlTimeFieldsToTime( &TimeField, NtTime )) { 01951 01952 // 01953 // Now fold in the remaining sub-second "precision". Read as coversions 01954 // through the 10-3 units, then into our 10-7 base. (centi->milli->micro, 01955 // etc). 01956 // 01957 01958 NtTime->QuadPart += ((UdfTime->CentiSecond * (10 * 1000)) + 01959 (UdfTime->Usec100 * 100) + 01960 UdfTime->Usec) * 10; 01961 01962 // 01963 // Perform TZ normalization if this is a local time with 01964 // specified timezone. 01965 // 01966 01967 if (UdfTime->Type == 1 && UdfTime->Zone != TIMESTAMP_Z_NONE) { 01968 01969 NtTime->QuadPart += Int32x32To64( -UdfTime->Zone, (60 * 10 * 1000 * 1000) ); 01970 } 01971 01972 } else { 01973 01974 // 01975 // Epoch. Malformed timestamp. 01976 // 01977 01978 NtTime->QuadPart = 0; 01979 } 01980 }

PCCB UdfCreateCcb IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PLCB Lcb  OPTIONAL,
IN ULONG  Flags
 

Definition at line 2433 of file udfs/strucsup.c.

References ASSERT_FCB, ASSERT_IRP_CONTEXT, ASSERT_OPTIONAL_LCB, CCB, _CCB::CurrentFileIndex, _CCB::Fcb, _CCB::Flags, _CCB::HighestReturnableFileIndex, _CCB::Lcb, _CCB::NodeByteSize, _CCB::NodeTypeCode, NULL, PAGED_CODE, _CCB::SearchExpression, UdfAllocateCcb, and UDFS_NTC_CCB.

Referenced by UdfCompleteFcbOpen().

02442 : 02443 02444 This routine is called to allocate and initialize the Ccb structure. 02445 02446 Arguments: 02447 02448 Fcb - This is the Fcb for the file being opened. 02449 02450 Lcb - This is the Lcb the Fcb is opened by. 02451 02452 Flags - User flags to set in this Ccb. 02453 02454 Return Value: 02455 02456 PCCB - Pointer to the created Ccb. 02457 02458 --*/ 02459 02460 { 02461 PCCB NewCcb; 02462 02463 PAGED_CODE(); 02464 02465 // 02466 // Check inputs. 02467 // 02468 02469 ASSERT_IRP_CONTEXT( IrpContext ); 02470 ASSERT_FCB( Fcb ); 02471 ASSERT_OPTIONAL_LCB( Lcb ); 02472 02473 // 02474 // Allocate and initialize the structure. 02475 // 02476 02477 NewCcb = UdfAllocateCcb( IrpContext ); 02478 02479 // 02480 // Set the proper node type code and node byte size 02481 // 02482 02483 NewCcb->NodeTypeCode = UDFS_NTC_CCB; 02484 NewCcb->NodeByteSize = sizeof( CCB ); 02485 02486 // 02487 // Set the initial value for the flags and Fcb/Lcb 02488 // 02489 02490 NewCcb->Flags = Flags; 02491 NewCcb->Fcb = Fcb; 02492 NewCcb->Lcb = Lcb; 02493 02494 // 02495 // Initialize the directory enumeration context 02496 // 02497 02498 NewCcb->CurrentFileIndex = 0; 02499 NewCcb->HighestReturnableFileIndex = 0; 02500 02501 NewCcb->SearchExpression.Length = 02502 NewCcb->SearchExpression.MaximumLength = 0; 02503 NewCcb->SearchExpression.Buffer = NULL; 02504 02505 return NewCcb; 02506 }

PFCB UdfCreateFcb IN PIRP_CONTEXT  IrpContext,
IN FILE_ID  FileId,
IN NODE_TYPE_CODE  NodeTypeCode,
OUT PBOOLEAN FcbExisted  OPTIONAL
 

Definition at line 2041 of file udfs/strucsup.c.

References _FCB::ChildLcbQueue, DebugUnwind, FALSE, _FCB::FcbNonpaged, _FCB::FileId, NULL, PAGED_CODE, _FCB::ParentLcbQueue, SIZEOF_FCB_DATA, SIZEOF_FCB_INDEX, TRUE, UdfAllocateFcbData, UdfAllocateFcbIndex, UdfBugCheck, UdfCreateFcbNonPaged(), UdfFreePool(), UdfLookupFcbTable(), UDFS_NTC_FCB_DATA, UDFS_NTC_FCB_INDEX, and _FCB::Vcb.

Referenced by UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

02050 : 02051 02052 This routine is called to find the Fcb for the given FileId. We will 02053 look this up first in the Fcb table and if not found we will create 02054 an Fcb. We don't initialize it or insert it into the FcbTable in this 02055 routine. 02056 02057 This routine is called while the Vcb is locked. 02058 02059 Arguments: 02060 02061 FileId - This is the Id for the target Fcb. 02062 02063 NodeTypeCode - Node type for this Fcb if we need to create. 02064 02065 FcbExisted - If specified, we store whether the Fcb existed. 02066 02067 Return Value: 02068 02069 PFCB - The Fcb found in the table or created if needed. 02070 02071 --*/ 02072 02073 { 02074 PFCB NewFcb; 02075 BOOLEAN LocalFcbExisted; 02076 02077 PAGED_CODE(); 02078 02079 // 02080 // Use the local boolean if one was not passed in. 02081 // 02082 02083 if (!ARGUMENT_PRESENT( FcbExisted )) { 02084 02085 FcbExisted = &LocalFcbExisted; 02086 } 02087 02088 // 02089 // Maybe this is already in the table. 02090 // 02091 02092 NewFcb = UdfLookupFcbTable( IrpContext, IrpContext->Vcb, FileId ); 02093 02094 // 02095 // If not then create the Fcb is requested by our caller. 02096 // 02097 02098 if (NewFcb == NULL) { 02099 02100 // 02101 // Use a try-finally for cleanup 02102 // 02103 02104 try { 02105 02106 // 02107 // Allocate and initialize the structure depending on the 02108 // type code. 02109 // 02110 02111 switch (NodeTypeCode) { 02112 02113 case UDFS_NTC_FCB_INDEX: 02114 02115 NewFcb = UdfAllocateFcbIndex( IrpContext ); 02116 02117 RtlZeroMemory( NewFcb, SIZEOF_FCB_INDEX ); 02118 02119 NewFcb->NodeByteSize = SIZEOF_FCB_INDEX; 02120 02121 break; 02122 02123 case UDFS_NTC_FCB_DATA : 02124 02125 NewFcb = UdfAllocateFcbData( IrpContext ); 02126 02127 RtlZeroMemory( NewFcb, SIZEOF_FCB_DATA ); 02128 02129 NewFcb->NodeByteSize = SIZEOF_FCB_DATA; 02130 02131 break; 02132 02133 default: 02134 02135 UdfBugCheck( 0, 0, 0 ); 02136 } 02137 02138 // 02139 // Now do the common initialization. 02140 // 02141 02142 NewFcb->NodeTypeCode = NodeTypeCode; 02143 02144 NewFcb->Vcb = IrpContext->Vcb; 02145 NewFcb->FileId = FileId; 02146 02147 InitializeListHead( &NewFcb->ParentLcbQueue ); 02148 InitializeListHead( &NewFcb->ChildLcbQueue ); 02149 02150 // 02151 // Now create the non-paged section object. 02152 // 02153 02154 NewFcb->FcbNonpaged = UdfCreateFcbNonPaged( IrpContext ); 02155 02156 *FcbExisted = FALSE; 02157 02158 } finally { 02159 02160 DebugUnwind( "UdfCreateFcb" ); 02161 02162 if (AbnormalTermination()) { 02163 02164 UdfFreePool( &NewFcb ); 02165 } 02166 } 02167 02168 } else { 02169 02170 *FcbExisted = TRUE; 02171 } 02172 02173 return NewFcb; 02174 }

BOOLEAN UdfCreateFileLock IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PFCB  Fcb,
IN BOOLEAN  RaiseOnError
 

Definition at line 3713 of file udfs/strucsup.c.

References ASSERT, FALSE, FsRtlAllocateFileLock(), NULL, PAGED_CODE, PFILE_LOCK, TRUE, UdfLockFcb, UdfRaiseStatus(), and UdfUnlockFcb.

Referenced by UdfCommonLockControl(), UdfFastLock(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), and UdfFastUnlockSingle().

03721 : 03722 03723 This routine is called when we want to attach a file lock structure to the 03724 given Fcb. It is possible the file lock is already attached. 03725 03726 This routine is sometimes called from the fast path and sometimes in the 03727 Irp-based path. We don't want to raise in the fast path, just return FALSE. 03728 03729 Arguments: 03730 03731 Fcb - This is the Fcb to create the file lock for. 03732 03733 RaiseOnError - If TRUE, we will raise on an allocation failure. Otherwise we 03734 return FALSE on an allocation failure. 03735 03736 Return Value: 03737 03738 BOOLEAN - TRUE if the Fcb has a filelock, FALSE otherwise. 03739 03740 --*/ 03741 03742 { 03743 BOOLEAN Result = TRUE; 03744 PFILE_LOCK FileLock; 03745 03746 PAGED_CODE(); 03747 03748 // 03749 // Lock the Fcb and check if there is really any work to do. 03750 // 03751 03752 UdfLockFcb( IrpContext, Fcb ); 03753 03754 if (Fcb->FileLock != NULL) { 03755 03756 UdfUnlockFcb( IrpContext, Fcb ); 03757 return TRUE; 03758 } 03759 03760 Fcb->FileLock = FileLock = 03761 FsRtlAllocateFileLock( NULL, NULL ); 03762 03763 UdfUnlockFcb( IrpContext, Fcb ); 03764 03765 // 03766 // Return or raise as appropriate. 03767 // 03768 03769 if (FileLock == NULL) { 03770 03771 if (RaiseOnError) { 03772 03773 ASSERT( ARGUMENT_PRESENT( IrpContext )); 03774 03775 UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); 03776 } 03777 03778 Result = FALSE; 03779 } 03780 03781 return Result; 03782 }

VOID UdfCreateInternalStream IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFCB  Fcb
 

Definition at line 46 of file udfs/cachesup.c.

References ASSERT_FCB_INDEX, ASSERT_IRP_CONTEXT, _UDF_DATA::CacheManagerCallbacks, CcInitializeCacheMap(), Dbg, DebugTrace, DebugUnwind, _FILE_OBJECT::DeleteAccess, FALSE, IoCreateStreamFileObject(), NULL, ObDereferenceObject, PAGED_CODE, _FILE_OBJECT::ReadAccess, _FILE_OBJECT::SectionObjectPointer, StreamFileOpen, TRUE, UdfData, UdfDecrementReferenceCounts, UdfIncrementReferenceCounts, UdfLockFcb, UdfLockVcb, UdfRaiseStatus(), UdfSetFileObject(), UdfUnlockFcb, UdfUnlockVcb, and _FILE_OBJECT::WriteAccess.

Referenced by UdfLookupInitialDirEntry(), UdfUpdateVcbPhase0(), and UdfUpdateVcbPhase1().

00054 : 00055 00056 This function creates an internal stream file for interaction 00057 with the cache manager. The Fcb here will be for a directory 00058 stream. 00059 00060 Arguments: 00061 00062 Vcb - Vcb for this volume. 00063 00064 Fcb - Points to the Fcb for this file. It is an Index Fcb. 00065 00066 Return Value: 00067 00068 None. 00069 00070 --*/ 00071 00072 { 00073 PFILE_OBJECT StreamFile = NULL; 00074 BOOLEAN DecrementReference = FALSE; 00075 00076 PAGED_CODE(); 00077 00078 // 00079 // Check inputs. 00080 // 00081 00082 ASSERT_IRP_CONTEXT( IrpContext ); 00083 ASSERT_FCB_INDEX( Fcb ); 00084 00085 // 00086 // We may only have the Fcb shared. Lock the Fcb and do a 00087 // safe test to see if we need to really create the file object. 00088 // 00089 00090 UdfLockFcb( IrpContext, Fcb ); 00091 00092 if (Fcb->FileObject != NULL) { 00093 00094 UdfUnlockFcb( IrpContext, Fcb ); 00095 return; 00096 } 00097 00098 // 00099 // Use a try-finally to facilitate cleanup. 00100 // 00101 00102 try { 00103 00104 // 00105 // Create the internal stream. The Vpb should be pointing at our volume 00106 // device object at this point. 00107 // 00108 00109 StreamFile = IoCreateStreamFileObject( NULL, Vcb->Vpb->RealDevice ); 00110 00111 if (StreamFile == NULL) { 00112 00113 UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); 00114 } 00115 00116 // 00117 // Initialize the fields of the file object. 00118 // 00119 00120 StreamFile->ReadAccess = TRUE; 00121 StreamFile->WriteAccess = FALSE; 00122 StreamFile->DeleteAccess = FALSE; 00123 00124 StreamFile->SectionObjectPointer = &Fcb->FcbNonpaged->SegmentObject; 00125 00126 // 00127 // Set the file object type and increment the Vcb counts. 00128 // 00129 00130 UdfSetFileObject( IrpContext, 00131 StreamFile, 00132 StreamFileOpen, 00133 Fcb, 00134 NULL ); 00135 00136 // 00137 // We will reference the current Fcb twice to keep it from going 00138 // away in the error path. Otherwise if we dereference it 00139 // below in the finally clause a close could cause the Fcb to 00140 // be deallocated. 00141 // 00142 00143 UdfLockVcb( IrpContext, Vcb ); 00144 00145 DebugTrace(( +1, Dbg, 00146 "UdfCreateInternalStream, Fcb %08x Vcb %d/%d Fcb %d/%d\n", 00147 Fcb, 00148 Vcb->VcbReference, 00149 Vcb->VcbUserReference, 00150 Fcb->FcbReference, 00151 Fcb->FcbUserReference )); 00152 00153 UdfIncrementReferenceCounts( IrpContext, Fcb, 2, 0 ); 00154 UdfUnlockVcb( IrpContext, Vcb ); 00155 DecrementReference = TRUE; 00156 00157 // 00158 // Initialize the cache map for the file. 00159 // 00160 00161 CcInitializeCacheMap( StreamFile, 00162 (PCC_FILE_SIZES)&Fcb->AllocationSize, 00163 TRUE, 00164 &UdfData.CacheManagerCallbacks, 00165 Fcb ); 00166 00167 // 00168 // Go ahead and store the stream file into the Fcb. 00169 // 00170 00171 Fcb->FileObject = StreamFile; 00172 StreamFile = NULL; 00173 00174 } finally { 00175 00176 DebugUnwind( "UdfCreateInternalStream" ); 00177 00178 // 00179 // If we raised then we need to dereference the file object. 00180 // 00181 00182 if (StreamFile != NULL) { 00183 00184 ObDereferenceObject( StreamFile ); 00185 Fcb->FileObject = NULL; 00186 } 00187 00188 // 00189 // Dereference and unlock the Fcb. 00190 // 00191 00192 if (DecrementReference) { 00193 00194 UdfLockVcb( IrpContext, Vcb ); 00195 UdfDecrementReferenceCounts( IrpContext, Fcb, 1, 0 ); 00196 00197 DebugTrace(( -1, Dbg, 00198 "UdfCreateInternalStream, Vcb %d/%d Fcb %d/%d\n", 00199 Vcb->VcbReference, 00200 Vcb->VcbUserReference, 00201 Fcb->FcbReference, 00202 Fcb->FcbUserReference )); 00203 00204 UdfUnlockVcb( IrpContext, Vcb ); 00205 } 00206 00207 UdfUnlockFcb( IrpContext, Fcb ); 00208 } 00209 00210 return; 00211 }

PIRP_CONTEXT UdfCreateIrpContext IN PIRP  Irp,
IN BOOLEAN  Wait
 

Definition at line 1301 of file udfs/strucsup.c.

References ASSERT, Count, _FILE_OBJECT::DeviceObject, _IO_STACK_LOCATION::DeviceObject, ExAllocateFromNPagedLookasideList(), ExRaiseStatus(), FALSE, _IO_STACK_LOCATION::FileObject, _UDF_DATA::FileSystemDeviceObjects, _IRP_CONTEXT::Flags, IoGetCurrentIrpStackLocation, _IRP_CONTEXT::Irp, Irp, IRP_CONTEXT, IRP_CONTEXT_FLAG_FORCE_POST, IRP_CONTEXT_FLAG_WAIT, IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_CREATE, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_SHUTDOWN, IRP_MN_MOUNT_VOLUME, IRP_MN_USER_FS_REQUEST, _IRP_CONTEXT::MajorFunction, _IO_STACK_LOCATION::MajorFunction, _IRP_CONTEXT::MinorFunction, _IO_STACK_LOCATION::MinorFunction, _IRP_CONTEXT::NodeByteSize, _IRP_CONTEXT::NodeTypeCode, NULL, NUMBER_OF_FS_OBJECTS, PAGED_CODE, _IO_STACK_LOCATION::Parameters, _IRP_CONTEXT::RealDevice, SetFlag, TRUE, UdfData, UdfIrpContextLookasideList, UDFS_NTC_IRP_CONTEXT, and _IRP_CONTEXT::Vcb.

Referenced by UdfFsdDispatch().

01308 : 01309 01310 This routine is called to initialize an IrpContext for the current 01311 UDFS request. We allocate the structure and then initialize it from 01312 the given Irp. 01313 01314 Arguments: 01315 01316 Irp - Irp for this request. 01317 01318 Wait - TRUE if this request is synchronous, FALSE otherwise. 01319 01320 Return Value: 01321 01322 PIRP_CONTEXT - Allocated IrpContext. 01323 01324 --*/ 01325 01326 { 01327 PIRP_CONTEXT NewIrpContext = NULL; 01328 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 01329 BOOLEAN IsFsDo = FALSE; 01330 ULONG Count; 01331 01332 PAGED_CODE(); 01333 01334 for (Count = 0; Count < NUMBER_OF_FS_OBJECTS; Count++) { 01335 01336 if (IrpSp->DeviceObject == UdfData.FileSystemDeviceObjects[Count]) { 01337 01338 IsFsDo = TRUE; 01339 break; 01340 } 01341 } 01342 01343 // 01344 // The only operations a filesystem device object should ever receive 01345 // are create/teardown of fsdo handles and operations which do not 01346 // occur in the context of fileobjects (i.e., mount). 01347 // 01348 01349 if (IsFsDo) { 01350 01351 if (IrpSp->FileObject != NULL && 01352 IrpSp->MajorFunction != IRP_MJ_CREATE && 01353 IrpSp->MajorFunction != IRP_MJ_CLEANUP && 01354 IrpSp->MajorFunction != IRP_MJ_CLOSE) { 01355 01356 ExRaiseStatus( STATUS_INVALID_DEVICE_REQUEST ); 01357 } 01358 01359 ASSERT( IrpSp->FileObject != NULL || 01360 01361 (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && 01362 IrpSp->MinorFunction == IRP_MN_USER_FS_REQUEST && 01363 IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_INVALIDATE_VOLUMES) || 01364 01365 (IrpSp->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL && 01366 IrpSp->MinorFunction == IRP_MN_MOUNT_VOLUME ) || 01367 01368 IrpSp->MajorFunction == IRP_MJ_SHUTDOWN ); 01369 } 01370 01371 NewIrpContext = ExAllocateFromNPagedLookasideList( &UdfIrpContextLookasideList ); 01372 01373 RtlZeroMemory( NewIrpContext, sizeof( IRP_CONTEXT )); 01374 01375 // 01376 // Set the proper node type code and node byte size 01377 // 01378 01379 NewIrpContext->NodeTypeCode = UDFS_NTC_IRP_CONTEXT; 01380 NewIrpContext->NodeByteSize = sizeof( IRP_CONTEXT ); 01381 01382 // 01383 // Set the originating Irp field 01384 // 01385 01386 NewIrpContext->Irp = Irp; 01387 01388 // 01389 // Copy RealDevice for workque algorithms. We will update this in the Mount or 01390 // Verify since they have no file objects to use here. 01391 // 01392 01393 if (IrpSp->FileObject != NULL) { 01394 01395 NewIrpContext->RealDevice = IrpSp->FileObject->DeviceObject; 01396 } 01397 01398 // 01399 // This may be one of our filesystem device objects. In that case don't 01400 // initialize the Vcb field. 01401 // 01402 01403 if (!IsFsDo) { 01404 01405 NewIrpContext->Vcb = &((PVOLUME_DEVICE_OBJECT) IrpSp->DeviceObject)->Vcb; 01406 } 01407 01408 // 01409 // Major/Minor Function codes 01410 // 01411 01412 NewIrpContext->MajorFunction = IrpSp->MajorFunction; 01413 NewIrpContext->MinorFunction = IrpSp->MinorFunction; 01414 01415 // 01416 // Set the wait parameter 01417 // 01418 01419 if (Wait) { 01420 01421 SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); 01422 01423 } else { 01424 01425 SetFlag( NewIrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST ); 01426 } 01427 01428 // 01429 // return and tell the caller 01430 // 01431 01432 return NewIrpContext; 01433 }

NTSTATUS UdfCreateUserMdl IN PIRP_CONTEXT  IrpContext,
IN ULONG  BufferLength,
IN BOOLEAN  RaiseOnError
 

Definition at line 474 of file deviosup.c.

References ASSERT, ASSERT_IRP, ASSERT_IRP_CONTEXT, EXCEPTION_EXECUTE_HANDLER, FALSE, FsRtlIsNtstatusExpected(), IoAllocateMdl(), IoFreeMdl(), IoWriteAccess, MmProbeAndLockPages(), NTSTATUS(), NULL, PAGED_CODE, Status, and UdfRaiseStatus().

Referenced by UdfNonCachedRead().

00482 : 00483 00484 This routine locks the specified buffer for read access (we only write into 00485 the buffer). The file system requires this routine since it does not 00486 ask the I/O system to lock its buffers for direct I/O. This routine 00487 may only be called from the Fsd while still in the user context. 00488 00489 This routine is only called if there is not already an Mdl. 00490 00491 Arguments: 00492 00493 BufferLength - Length of user buffer. 00494 00495 RaiseOnError - Indicates if our caller wants this routine to raise on 00496 an error condition. 00497 00498 Return Value: 00499 00500 NTSTATUS - Status from this routine. Error status only returned if 00501 RaiseOnError is FALSE. 00502 00503 --*/ 00504 00505 { 00506 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; 00507 PMDL Mdl; 00508 00509 PAGED_CODE(); 00510 00511 ASSERT_IRP_CONTEXT( IrpContext ); 00512 ASSERT_IRP( IrpContext->Irp ); 00513 ASSERT( IrpContext->Irp->MdlAddress == NULL ); 00514 00515 // 00516 // Allocate the Mdl, and Raise if we fail. 00517 // 00518 00519 Mdl = IoAllocateMdl( IrpContext->Irp->UserBuffer, 00520 BufferLength, 00521 FALSE, 00522 FALSE, 00523 IrpContext->Irp ); 00524 00525 if (Mdl != NULL) { 00526 00527 // 00528 // Now probe the buffer described by the Irp. If we get an exception, 00529 // deallocate the Mdl and return the appropriate "expected" status. 00530 // 00531 00532 try { 00533 00534 MmProbeAndLockPages( Mdl, IrpContext->Irp->RequestorMode, IoWriteAccess ); 00535 00536 Status = STATUS_SUCCESS; 00537 00538 } except(EXCEPTION_EXECUTE_HANDLER) { 00539 00540 Status = GetExceptionCode(); 00541 00542 IoFreeMdl( Mdl ); 00543 IrpContext->Irp->MdlAddress = NULL; 00544 00545 if (!FsRtlIsNtstatusExpected( Status )) { 00546 00547 Status = STATUS_INVALID_USER_BUFFER; 00548 } 00549 } 00550 } 00551 00552 // 00553 // Check if we are to raise or return 00554 // 00555 00556 if (Status != STATUS_SUCCESS) { 00557 00558 if (RaiseOnError) { 00559 00560 UdfRaiseStatus( IrpContext, Status ); 00561 } 00562 } 00563 00564 // 00565 // Return the status code. 00566 // 00567 00568 return Status; 00569 }

INLINE BOOLEAN UdfCS0DstringContainsLegalCharacters IN PCHAR  Dstring,
IN ULONG  Length
 

Definition at line 1239 of file udfprocs.h.

References CHAR, Dbg, DebugTrace, FALSE, SwapCopyUchar2, TRUE, and UdfIsCharacterLegal().

Referenced by UdfUpdateDirNames().

01246 : 01247 01248 This routine inspects a CS0 dstring for illegal characters. The assumption is 01249 made that the string is legal CS0. 01250 01251 Arguments: 01252 01253 Name - a name to check 01254 01255 Return Value: 01256 01257 BOOLEAN True if legal characters are found, False otherwise. 01258 01259 --*/ 01260 01261 { 01262 ULONG Step; 01263 WCHAR Char; 01264 PCHAR Bound = Dstring + Length; 01265 01266 // 01267 // Determine how big a step we take in the string according to the 01268 // "compression" applied. 01269 // 01270 01271 if (*Dstring == 16) { 01272 01273 Step = sizeof( WCHAR ); 01274 01275 } else { 01276 01277 Step = sizeof( CHAR ); 01278 } 01279 01280 // 01281 // Advance past the compression marker and loop over the string. 01282 // 01283 01284 for (Dstring++; Dstring < Bound; Dstring += Step) { 01285 01286 // 01287 // Perform the endianess swapcopy to convert from UDF bigendian CS0 to our 01288 // little endian wide characters. 01289 // 01290 01291 SwapCopyUchar2( &Char, Dstring ); 01292 01293 if (!UdfIsCharacterLegal( Char )) { 01294 01295 DebugTrace(( 0, Dbg, "UdfCS0DstringContainsLegalCharacters, Char %04x @ %08x\n", (WCHAR) Char, Dstring )); 01296 01297 return FALSE; 01298 } 01299 } 01300 01301 return TRUE; 01302 }

INLINE USHORT UdfCS0DstringUnicodeSize PIRP_CONTEXT  IrpContext,
PCHAR  Dstring,
UCHAR  Length
 

Definition at line 1177 of file udfprocs.h.

Referenced by UdfConvertCS0DstringToUnicode(), and UdfUpdateDirNames().

01185 : 01186 01187 This routine computes the number of bytes required for the UNICODE representation 01188 of a CS0 Dstring (1/7.2.12) 01189 01190 Arguments: 01191 01192 Dstring - a dstring 01193 01194 Length - length of the dstring 01195 01196 Return Value: 01197 01198 ULONG number of bytes. 01199 01200 --*/ 01201 01202 { 01203 return (16 / *Dstring) * (Length - 1); 01204 }

TYPE_OF_OPEN UdfDecodeFileObject IN PFILE_OBJECT  FileObject,
OUT PFCB Fcb,
OUT PCCB Ccb
 

Definition at line 133 of file filobsup.c.

References ClearFlag, FlagOn, NULL, PAGED_CODE, TYPE_OF_OPEN, TYPE_OF_OPEN_MASK, and UnopenedFileObject.

Referenced by UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonLockControl(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfDismountVolume(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfIsVolumeDirty(), UdfIsVolumeMounted(), UdfLockVolume(), UdfOplockRequest(), and UdfUnlockVolume().

00141 : 00142 00143 This routine takes a file object and extracts the Fcb and Ccb (possibly NULL) 00144 and returns the type of open. 00145 00146 Arguments: 00147 00148 FileObject - Supplies the file object pointer being initialized. 00149 00150 Fcb - Address to store the Fcb contained in the file object. 00151 00152 Ccb - Address to store the Ccb contained in the file object. 00153 00154 Return Value: 00155 00156 TYPE_OF_OPEN - Indicates the type of file object. 00157 00158 --*/ 00159 00160 { 00161 TYPE_OF_OPEN TypeOfOpen; 00162 00163 PAGED_CODE(); 00164 00165 // 00166 // If this is an unopened file object then return NULL for the 00167 // Fcb/Ccb. Don't trust any other values in the file object. 00168 // 00169 00170 TypeOfOpen = (TYPE_OF_OPEN) FlagOn( (ULONG_PTR) FileObject->FsContext2, 00171 TYPE_OF_OPEN_MASK ); 00172 00173 if (TypeOfOpen == UnopenedFileObject) { 00174 00175 *Fcb = NULL; 00176 *Ccb = NULL; 00177 00178 } else { 00179 00180 // 00181 // The Fcb is pointed to by the FsContext field. The Ccb is in 00182 // FsContext2 (after clearing the low three bits). The low three 00183 // bits are the file object type. 00184 // 00185 00186 *Fcb = FileObject->FsContext; 00187 *Ccb = FileObject->FsContext2; 00188 00189 ClearFlag( (ULONG_PTR) *Ccb, TYPE_OF_OPEN_MASK ); 00190 } 00191 00192 // 00193 // Now return the type of open. 00194 // 00195 00196 return TypeOfOpen; 00197 }

VOID UdfDeleteCcb IN PIRP_CONTEXT  IrpContext,
IN PCCB  Ccb
 

Definition at line 2510 of file udfs/strucsup.c.

References ASSERT_CCB, ASSERT_IRP_CONTEXT, NULL, PAGED_CODE, UdfDeallocateCcb, and UdfFreePool().

Referenced by UdfCommonClose().

02517 : 02518 02519 This routine is called to cleanup and deallocate a Ccb structure. 02520 02521 Arguments: 02522 02523 Ccb - This is the Ccb to delete. 02524 02525 Return Value: 02526 02527 None 02528 02529 --*/ 02530 02531 { 02532 PAGED_CODE(); 02533 02534 // 02535 // Check inputs. 02536 // 02537 02538 ASSERT_IRP_CONTEXT( IrpContext ); 02539 ASSERT_CCB( Ccb ); 02540 02541 if (Ccb->SearchExpression.Buffer != NULL) { 02542 02543 UdfFreePool( &Ccb->SearchExpression.Buffer ); 02544 } 02545 02546 UdfDeallocateCcb( IrpContext, Ccb ); 02547 return; 02548 }

VOID UdfDeleteFcb IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb
 

Definition at line 2178 of file udfs/strucsup.c.

References ASSERT, ASSERT_FCB, ASSERT_IRP_CONTEXT, FsRtlFreeFileLock(), FsRtlUninitializeOplock(), _VCB::MetadataFcb, NULL, PAGED_CODE, _VCB::RootIndexFcb, UdfDeallocateFcbData, UdfDeallocateFcbIndex, UdfDeleteFcbNonpaged(), UDFS_NTC_FCB_DATA, UDFS_NTC_FCB_INDEX, UdfUninitializeFcbMcb(), UdfUninitializeVmcb(), _VCB::VatFcb, _VCB::VcbReference, _VCB::VcbUserReference, _VCB::Vmcb, and _VCB::VolumeDasdFcb.

Referenced by UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), and UdfTeardownStructures().

02185 : 02186 02187 This routine is called to cleanup and deallocate an Fcb. We know there 02188 are no references remaining. We cleanup any auxilary structures and 02189 deallocate this Fcb. 02190 02191 Arguments: 02192 02193 Fcb - This is the Fcb to deallcoate. 02194 02195 Return Value: 02196 02197 None 02198 02199 --*/ 02200 02201 { 02202 PVCB Vcb = NULL; 02203 02204 PAGED_CODE(); 02205 02206 // 02207 // Check inputs. 02208 // 02209 02210 ASSERT_IRP_CONTEXT( IrpContext ); 02211 ASSERT_FCB( Fcb ); 02212 02213 // 02214 // Sanity check the counts and Lcb lists. 02215 // 02216 02217 ASSERT( Fcb->FcbCleanup == 0 ); 02218 ASSERT( Fcb->FcbReference == 0 ); 02219 02220 ASSERT( IsListEmpty( &Fcb->ChildLcbQueue )); 02221 ASSERT( IsListEmpty( &Fcb->ParentLcbQueue )); 02222 02223 // 02224 // Start with the common structures. 02225 // 02226 02227 UdfUninitializeFcbMcb( Fcb ); 02228 02229 UdfDeleteFcbNonpaged( IrpContext, Fcb->FcbNonpaged ); 02230 02231 // 02232 // Now do the type specific structures. 02233 // 02234 02235 switch (Fcb->NodeTypeCode) { 02236 02237 case UDFS_NTC_FCB_INDEX: 02238 02239 ASSERT( Fcb->FileObject == NULL ); 02240 02241 if (Fcb == Fcb->Vcb->RootIndexFcb) { 02242 02243 Vcb = Fcb->Vcb; 02244 Vcb->RootIndexFcb = NULL; 02245 02246 } else if (Fcb == Fcb->Vcb->MetadataFcb) { 02247 02248 Vcb = Fcb->Vcb; 02249 Vcb->MetadataFcb = NULL; 02250 02251 UdfUninitializeVmcb( &Vcb->Vmcb ); 02252 02253 } else if (Fcb == Fcb->Vcb->VatFcb) { 02254 02255 Vcb = Fcb->Vcb; 02256 Vcb->VatFcb = NULL; 02257 } 02258 02259 UdfDeallocateFcbIndex( IrpContext, Fcb ); 02260 break; 02261 02262 case UDFS_NTC_FCB_DATA : 02263 02264 if (Fcb->FileLock != NULL) { 02265 02266 FsRtlFreeFileLock( Fcb->FileLock ); 02267 } 02268 02269 FsRtlUninitializeOplock( &Fcb->Oplock ); 02270 02271 if (Fcb == Fcb->Vcb->VolumeDasdFcb) { 02272 02273 Vcb = Fcb->Vcb; 02274 Vcb->VolumeDasdFcb = NULL; 02275 } 02276 02277 UdfDeallocateFcbData( IrpContext, Fcb ); 02278 break; 02279 } 02280 02281 // 02282 // Decrement the Vcb reference count if this is a system 02283 // Fcb. 02284 // 02285 02286 if (Vcb != NULL) { 02287 02288 InterlockedDecrement( &Vcb->VcbReference ); 02289 InterlockedDecrement( &Vcb->VcbUserReference ); 02290 } 02291 02292 return; 02293 }

VOID UdfDeleteInternalStream IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb
 

Definition at line 215 of file udfs/cachesup.c.

References ASSERT_FCB, ASSERT_IRP_CONTEXT, CcUninitializeCacheMap(), NULL, ObDereferenceObject, PAGED_CODE, _FILE_OBJECT::PrivateCacheMap, UdfLockFcb, and UdfUnlockFcb.

Referenced by UdfPurgeVolume(), and UdfTeardownStructures().

00222 : 00223 00224 This function creates an internal stream file for interaction 00225 with the cache manager. The Fcb here can be for either a 00226 directory stream or for a metadata stream. 00227 00228 Arguments: 00229 00230 Fcb - Points to the Fcb for this file. It is either an Index or 00231 Metadata Fcb. 00232 00233 Return Value: 00234 00235 None. 00236 00237 --*/ 00238 00239 { 00240 PFILE_OBJECT FileObject; 00241 00242 PAGED_CODE(); 00243 00244 ASSERT_IRP_CONTEXT( IrpContext ); 00245 ASSERT_FCB( Fcb ); 00246 00247 // 00248 // Lock the Fcb. 00249 // 00250 00251 UdfLockFcb( IrpContext, Fcb ); 00252 00253 // 00254 // Capture the file object. 00255 // 00256 00257 FileObject = Fcb->FileObject; 00258 Fcb->FileObject = NULL; 00259 00260 // 00261 // It is now safe to unlock the Fcb. 00262 // 00263 00264 UdfUnlockFcb( IrpContext, Fcb ); 00265 00266 // 00267 // Dereference the file object if present. 00268 // 00269 00270 if (FileObject != NULL) { 00271 00272 if (FileObject->PrivateCacheMap != NULL) { 00273 00274 CcUninitializeCacheMap( FileObject, NULL, NULL ); 00275 } 00276 00277 ObDereferenceObject( FileObject ); 00278 } 00279 00280 return; 00281 }

VOID UdfDeletePcb IN PPCB  Pcb  ) 
 

Definition at line 309 of file allocsup.c.

References ASSERT, ExFreePool(), FALSE, FsRtlUninitializeLargeMcb(), Physical, PPARTITION, UdfFreePool(), Uninitialized, and Virtual.

Referenced by UdfDeleteVcb(), UdfInitializePcb(), UdfMountVolume(), and UdfVerifyVolume().

00315 : 00316 00317 This routine deallocates a Pcb and all ancilliary structures. 00318 00319 Arguments: 00320 00321 Pcb - Pcb being deleted 00322 00323 Return Value: 00324 00325 None 00326 00327 --*/ 00328 00329 { 00330 PPARTITION Partition; 00331 00332 if (Pcb->SparingMcb) { 00333 00334 FsRtlUninitializeLargeMcb( Pcb->SparingMcb ); 00335 UdfFreePool( &Pcb->SparingMcb ); 00336 } 00337 00338 for (Partition = Pcb->Partition; 00339 Partition < &Pcb->Partition[Pcb->Partitions]; 00340 Partition++) { 00341 00342 switch (Partition->Type) { 00343 00344 case Physical: 00345 00346 UdfFreePool( &Partition->Physical.PartitionDescriptor ); 00347 UdfFreePool( &Partition->Physical.SparingMap ); 00348 00349 break; 00350 00351 case Virtual: 00352 case Uninitialized: 00353 break; 00354 00355 default: 00356 00357 ASSERT( FALSE ); 00358 break; 00359 } 00360 } 00361 00362 ExFreePool( Pcb ); 00363 }

VOID UdfDeleteVcb IN PIRP_CONTEXT  IrpContext,
IN OUT PVCB  Vcb
 

Definition at line 1210 of file udfs/strucsup.c.

References ASSERT_EXCLUSIVE_UDFDATA, ASSERT_EXCLUSIVE_VCB, ExDeleteResource, FsRtlNotifyUninitializeSync(), IoDeleteDevice(), NULL, ObDereferenceObject, PAGED_CODE, UdfDeletePcb(), and UdfFreePool().

Referenced by UdfCheckForDismount(), and UdfDismountVcb().

01217 : 01218 01219 This routine is called to delete a Vcb which failed mount or has been 01220 dismounted. The dismount code should have already removed all of the 01221 open Fcb's. We do nothing here but clean up other auxilary structures. 01222 01223 Arguments: 01224 01225 Vcb - Vcb to delete. 01226 01227 Return Value: 01228 01229 None 01230 01231 --*/ 01232 01233 { 01234 PAGED_CODE(); 01235 01236 ASSERT_EXCLUSIVE_UDFDATA; 01237 ASSERT_EXCLUSIVE_VCB( Vcb ); 01238 01239 // 01240 // If there is a Vpb then we must delete it ourselves. 01241 // 01242 01243 if (Vcb->Vpb != NULL) { 01244 01245 UdfFreePool( &Vcb->Vpb ); 01246 } 01247 01248 // 01249 // Drop the Pcb. 01250 // 01251 01252 if (Vcb->Pcb != NULL) { 01253 01254 UdfDeletePcb( Vcb->Pcb ); 01255 } 01256 01257 // 01258 // Dereference our target if we haven't already done so. 01259 // 01260 01261 if (Vcb->TargetDeviceObject != NULL) { 01262 01263 ObDereferenceObject( Vcb->TargetDeviceObject ); 01264 } 01265 01266 // 01267 // Remove this entry from the global queue. 01268 // 01269 01270 RemoveEntryList( &Vcb->VcbLinks ); 01271 01272 // 01273 // Delete the Vcb and File resources. 01274 // 01275 01276 ExDeleteResource( &Vcb->VcbResource ); 01277 ExDeleteResource( &Vcb->FileResource ); 01278 01279 // 01280 // Uninitialize the notify structures. 01281 // 01282 01283 if (Vcb->NotifySync != NULL) { 01284 01285 FsRtlNotifyUninitializeSync( &Vcb->NotifySync ); 01286 } 01287 01288 // 01289 // Now delete the volume device object. 01290 // 01291 01292 IoDeleteDevice( (PDEVICE_OBJECT) CONTAINING_RECORD( Vcb, 01293 VOLUME_DEVICE_OBJECT, 01294 Vcb )); 01295 01296 return; 01297 }

BOOLEAN UdfDismountVcb IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb
 

Definition at line 365 of file udfs/verfysup.c.

References ASSERT, ASSERT_EXCLUSIVE_UDFDATA, ASSERT_EXCLUSIVE_VCB, ClearFlag, _VPB::DeviceObject, ExAllocatePoolWithTag, FALSE, FlagOn, _VPB::Flags, IO_TYPE_VPB, IoAcquireVpbSpinLock(), IoReleaseVpbSpinLock(), NonPagedPoolMustSucceed, NULL, _VPB::RealDevice, _VPB::ReferenceCount, _VPB::Size, TAG_VPB, TRUE, _VPB::Type, UdfDeleteVcb(), UdfFreePool(), UdfFspClose(), UdfLockVcb, UdfPurgeVolume(), UdfUnlockVcb, VcbDismountInProgress, VPB, _DEVICE_OBJECT::Vpb, VPB_MOUNTED, and VPB_REMOVE_PENDING.

Referenced by UdfCheckForDismount(), and UdfMountVolume().

00372 : 00373 00374 This routine is called when all of the user references to a volume are 00375 gone. We will initiate all of the teardown any system resources. 00376 00377 If all of the references to this volume are gone at the end of this routine 00378 then we will complete the teardown of this Vcb and mark the current Vpb 00379 as not mounted. Otherwise we will allocated a new Vpb for this device 00380 and keep the current Vpb attached to the Vcb. 00381 00382 Arguments: 00383 00384 Vcb - Vcb for the volume to dismount. 00385 00386 Return Value: 00387 00388 BOOLEAN - TRUE if we didn't delete the Vcb, FALSE otherwise. 00389 00390 --*/ 00391 00392 { 00393 PVPB OldVpb; 00394 PVPB NewVpb; 00395 BOOLEAN VcbPresent = TRUE; 00396 KIRQL SavedIrql; 00397 00398 BOOLEAN FinalReference; 00399 00400 ASSERT_EXCLUSIVE_UDFDATA; 00401 ASSERT_EXCLUSIVE_VCB( Vcb ); 00402 00403 UdfLockVcb( IrpContext, Vcb ); 00404 00405 // 00406 // We should only take this path once. 00407 // 00408 00409 ASSERT( Vcb->VcbCondition != VcbDismountInProgress ); 00410 00411 // 00412 // Mark the Vcb as DismountInProgress. 00413 // 00414 00415 Vcb->VcbCondition = VcbDismountInProgress; 00416 00417 // 00418 // Remove our reference to the internal Fcb's. The Fcb's will then 00419 // be removed in the purge path below. 00420 // 00421 00422 if (Vcb->RootIndexFcb != NULL) { 00423 00424 Vcb->RootIndexFcb->FcbReference -= 1; 00425 Vcb->RootIndexFcb->FcbUserReference -= 1; 00426 } 00427 00428 if (Vcb->MetadataFcb != NULL) { 00429 00430 Vcb->MetadataFcb->FcbReference -= 1; 00431 Vcb->MetadataFcb->FcbUserReference -= 1; 00432 } 00433 00434 if (Vcb->VatFcb != NULL) { 00435 00436 Vcb->VatFcb->FcbReference -= 1; 00437 Vcb->VatFcb->FcbUserReference -= 1; 00438 } 00439 00440 if (Vcb->VolumeDasdFcb != NULL) { 00441 00442 Vcb->VolumeDasdFcb->FcbReference -= 1; 00443 Vcb->VolumeDasdFcb->FcbUserReference -= 1; 00444 } 00445 00446 UdfUnlockVcb( IrpContext, Vcb ); 00447 00448 // 00449 // Purge the volume. 00450 // 00451 00452 UdfPurgeVolume( IrpContext, Vcb, TRUE ); 00453 00454 // 00455 // Empty the delayed and async close queues. 00456 // 00457 00458 UdfFspClose( Vcb ); 00459 00460 // 00461 // Allocate a new Vpb in case we will need it. 00462 // 00463 00464 NewVpb = ExAllocatePoolWithTag( NonPagedPoolMustSucceed, sizeof( VPB ), TAG_VPB ); 00465 RtlZeroMemory( NewVpb, sizeof( VPB ) ); 00466 00467 OldVpb = Vcb->Vpb; 00468 00469 // 00470 // Remove the mount volume reference. 00471 // 00472 00473 UdfLockVcb( IrpContext, Vcb ); 00474 Vcb->VcbReference -= 1; 00475 00476 // 00477 // Acquire the Vpb spinlock to check for Vpb references. 00478 // 00479 00480 IoAcquireVpbSpinLock( &SavedIrql ); 00481 00482 // 00483 // Remember if this is the last reference on this Vcb. We incremented 00484 // the count on the Vpb earlier so we get one last crack it. If our 00485 // reference has gone to zero but the vpb reference count is greater 00486 // than zero then the Io system will be responsible for deleting the 00487 // Vpb. 00488 // 00489 00490 FinalReference = (BOOLEAN) ((Vcb->VcbReference == 0) && 00491 (OldVpb->ReferenceCount == 1)); 00492 00493 // 00494 // There is a reference count in the Vpb and in the Vcb. We have 00495 // incremented the reference count in the Vpb to make sure that 00496 // we have last crack at it. If this is a failed mount then we 00497 // want to return the Vpb to the IO system to use for the next 00498 // mount request. 00499 // 00500 00501 if (OldVpb->RealDevice->Vpb == OldVpb) { 00502 00503 // 00504 // If not the final reference then swap out the Vpb. We must 00505 // preserve the REMOVE_PENDING flag so that the device is 00506 // not remounted in the middle of a PnP remove operation. 00507 // 00508 00509 if (!FinalReference) { 00510 00511 NewVpb->Type = IO_TYPE_VPB; 00512 NewVpb->Size = sizeof( VPB ); 00513 NewVpb->RealDevice = OldVpb->RealDevice; 00514 00515 NewVpb->RealDevice->Vpb = NewVpb; 00516 00517 NewVpb->Flags = FlagOn( OldVpb->Flags, VPB_REMOVE_PENDING ); 00518 00519 NewVpb = NULL; 00520 IoReleaseVpbSpinLock( SavedIrql ); 00521 UdfUnlockVcb( IrpContext, Vcb ); 00522 00523 // 00524 // We want to leave the Vpb for the IO system. Mark it 00525 // as being not mounted. Go ahead and delete the Vcb as 00526 // well. 00527 // 00528 00529 } else { 00530 00531 // 00532 // Make sure to remove the last reference on the Vpb. 00533 // 00534 00535 OldVpb->ReferenceCount -= 1; 00536 00537 OldVpb->DeviceObject = NULL; 00538 ClearFlag( Vcb->Vpb->Flags, VPB_MOUNTED ); 00539 00540 // 00541 // Clear the Vpb flag so we know not to delete it. 00542 // 00543 00544 Vcb->Vpb = NULL; 00545 00546 IoReleaseVpbSpinLock( SavedIrql ); 00547 UdfUnlockVcb( IrpContext, Vcb ); 00548 UdfDeleteVcb( IrpContext, Vcb ); 00549 VcbPresent = FALSE; 00550 } 00551 00552 // 00553 // Someone has already swapped in a new Vpb. If this is the final reference 00554 // then the file system is responsible for deleting the Vpb. 00555 // 00556 00557 } else if (FinalReference) { 00558 00559 // 00560 // Make sure to remove the last reference on the Vpb. 00561 // 00562 00563 OldVpb->ReferenceCount -= 1; 00564 00565 IoReleaseVpbSpinLock( SavedIrql ); 00566 UdfUnlockVcb( IrpContext, Vcb ); 00567 UdfDeleteVcb( IrpContext, Vcb ); 00568 VcbPresent = FALSE; 00569 00570 // 00571 // The current Vpb is no longer the Vpb for the device (the IO system 00572 // has already allocated a new one). We leave our reference in the 00573 // Vpb and will be responsible for deleting it at a later time. 00574 // 00575 00576 } else { 00577 00578 OldVpb->DeviceObject = NULL; 00579 ClearFlag( Vcb->Vpb->Flags, VPB_MOUNTED ); 00580 00581 IoReleaseVpbSpinLock( SavedIrql ); 00582 UdfUnlockVcb( IrpContext, Vcb ); 00583 } 00584 00585 // 00586 // Deallocate the new Vpb if we don't need it. 00587 // 00588 00589 if (NewVpb != NULL) { 00590 00591 UdfFreePool( &NewVpb ); 00592 } 00593 00594 // 00595 // Let our caller know whether the Vcb is still present. 00596 // 00597 00598 return VcbPresent; 00599 }

VOID UdfDissectName IN PIRP_CONTEXT  IrpContext,
IN OUT PUNICODE_STRING  RemainingName,
OUT PUNICODE_STRING  FinalName
 

Definition at line 96 of file namesup.c.

References Add2Ptr, ASSERT_IRP_CONTEXT, L, PAGED_CODE, and USHORT.

Referenced by UdfCommonCreate(), and UdfFindPrefix().

00104 : 00105 00106 This routine is called to strip off leading components of the name strings. We search 00107 for either the end of the string or separating characters. The input remaining 00108 name strings should have neither a trailing or leading backslash. 00109 00110 Arguments: 00111 00112 RemainingName - Remaining name. 00113 00114 FinalName - Location to store next component of name. 00115 00116 Return Value: 00117 00118 None. 00119 00120 --*/ 00121 00122 { 00123 ULONG NameLength; 00124 PWCHAR NextWchar; 00125 00126 PAGED_CODE(); 00127 00128 // 00129 // Check inputs. 00130 // 00131 00132 ASSERT_IRP_CONTEXT( IrpContext ); 00133 00134 // 00135 // Find the offset of the next component separators. 00136 // 00137 00138 for (NameLength = 0, NextWchar = RemainingName->Buffer; 00139 (NameLength < RemainingName->Length) && (*NextWchar != L'\\'); 00140 NameLength += sizeof( WCHAR) , NextWchar += 1); 00141 00142 // 00143 // Adjust all the strings by this amount. 00144 // 00145 00146 FinalName->Buffer = RemainingName->Buffer; 00147 00148 FinalName->MaximumLength = FinalName->Length = (USHORT) NameLength; 00149 00150 // 00151 // If this is the last component then set the RemainingName lengths to zero. 00152 // 00153 00154 if (NameLength == RemainingName->Length) { 00155 00156 RemainingName->Length = 0; 00157 00158 // 00159 // Otherwise we adjust the string by this amount plus the separating character. 00160 // 00161 00162 } else { 00163 00164 RemainingName->MaximumLength -= (USHORT) (NameLength + sizeof( WCHAR )); 00165 RemainingName->Length -= (USHORT) (NameLength + sizeof( WCHAR )); 00166 RemainingName->Buffer = Add2Ptr( RemainingName->Buffer, 00167 NameLength + sizeof( WCHAR ), 00168 PWCHAR ); 00169 } 00170 00171 return; 00172 }

INLINE BOOLEAN UdfDomainIdentifierContained IN PREGID  RegID,
IN PSTRING  Domain,
IN USHORT  RevisionMin,
IN USHORT  RevisionMax
 

Definition at line 2027 of file udfprocs.h.

References NULL, UdfEqualEntityId(), and _UDF_SUFFIX_DOMAIN::UdfRevision.

Referenced by UdfFindVolumeDescriptors(), and UdfInitializePcb().

02033 { 02034 PUDF_SUFFIX_DOMAIN DomainSuffix = (PUDF_SUFFIX_DOMAIN) RegID->Suffix; 02035 02036 #ifdef UDF_SUPPORT_NONSTANDARD_ALLSTOR 02037 02038 // 02039 // Disable checking of the UDF revision. 02040 // 02041 // Reason: first drop of Allstor media recorded the version number as 02042 // a decimal number, not hex (102 = 0x66) 02043 // 02044 02045 return (UdfEqualEntityId( RegID, Domain, NULL )); 02046 02047 #else 02048 02049 return ((DomainSuffix->UdfRevision <= RevisionMax && DomainSuffix->UdfRevision >= RevisionMin) && 02050 UdfEqualEntityId( RegID, Domain, NULL )); 02051 #endif 02052 }

INLINE BOOLEAN UdfEqualCharspec IN PCHARSPEC  Charspec,
IN PSTRING  Identifier,
IN UCHAR  Type
 

Definition at line 2228 of file udfprocs.h.

References PCHARSPEC, and UdfEqualCountedString().

Referenced by UdfFindVolumeDescriptors().

02233 { 02234 return ((Charspec->Type == Type) && UdfEqualCountedString( Identifier, Charspec->Info)); 02235 }

INLINE BOOLEAN UdfEqualCountedString IN PSTRING  String,
IN PCHAR  Field
 

Definition at line 472 of file udfprocs.h.

References CHAR, and String.

Referenced by UdfEqualCharspec(), and UdfEqualEntityId().

00476 { 00477 return (RtlEqualMemory( (CHAR UNALIGNED *)String->Buffer, 00478 (CHAR UNALIGNED *)Field, 00479 String->Length ) != 0); 00480 }

INLINE BOOLEAN UdfEqualEntityId IN PREGID  RegID,
IN PSTRING  Id,
IN OPTIONAL PSTRING  Suffix
 

Definition at line 1988 of file udfprocs.h.

References Dbg, DebugTrace, NULL, and UdfEqualCountedString().

Referenced by UdfDomainIdentifierContained(), UdfFindVolumeDescriptors(), and UdfUdfIdentifierContained().

01993 { 01994 01995 return (UdfEqualCountedString( Id, RegID->Identifier ) && 01996 01997 #ifndef UDF_SUPPORT_NONSTANDARD_ENTITY_STRINGTERM 01998 01999 // 02000 // Allow disabling of the check that the identifier 02001 // seems to be padded with zero. 02002 // 02003 // Reason: a couple samples that are otherwise useful 02004 // padded some identifiers with junk. 02005 // 02006 02007 ((Id->Length == sizeof(RegID->Identifier) || 02008 RegID->Identifier[Id->Length] == '\0') || 02009 02010 !DebugTrace(( 0, Dbg, 02011 "UdfEqualEntityId, RegID seems to be terminated with junk!\n" ))) && 02012 #endif 02013 02014 ((Suffix == NULL) || UdfEqualCountedString( Suffix, RegID->Suffix ))); 02015 }

BOOLEAN UdfEquivalentPcb IN PIRP_CONTEXT  IrpContext,
IN PPCB  Pcb1,
IN PPCB  Pcb2
 

Definition at line 923 of file allocsup.c.

References ASSERT, ASSERT_IRP_CONTEXT, FALSE, Index, PAGED_CODE, Physical, TRUE, and Virtual.

Referenced by UdfVerifyVolume().

00931 : 00932 00933 This routine compares two completed Pcbs to see if they appear equivalent. 00934 00935 Arguments: 00936 00937 Pcb1 - Pcb being compared 00938 00939 Pcb2 - Pcb being compared 00940 00941 Return Value: 00942 00943 BOOLEAN according to whether they are equivalent (TRUE, else FALSE) 00944 00945 --*/ 00946 00947 { 00948 ULONG Index; 00949 00950 PAGED_CODE(); 00951 00952 // 00953 // Check input. 00954 // 00955 00956 ASSERT_IRP_CONTEXT( IrpContext ); 00957 00958 if (Pcb1->Partitions != Pcb2->Partitions) { 00959 00960 return FALSE; 00961 } 00962 00963 for (Index = 0; 00964 Index < Pcb1->Partitions; 00965 Index++) { 00966 00967 // 00968 // First check that the partitions are of the same type. 00969 // 00970 00971 if (Pcb1->Partition[Index].Type != Pcb2->Partition[Index].Type) { 00972 00973 return FALSE; 00974 } 00975 00976 // 00977 // Now the map content must be the same ... 00978 // 00979 00980 switch (Pcb1->Partition[Index].Type) { 00981 00982 case Physical: 00983 00984 if (Pcb1->Partition[Index].Physical.PartitionNumber != Pcb2->Partition[Index].Physical.PartitionNumber || 00985 Pcb1->Partition[Index].Physical.Length != Pcb2->Partition[Index].Physical.Length || 00986 Pcb1->Partition[Index].Physical.Start != Pcb2->Partition[Index].Physical.Start) { 00987 00988 return FALSE; 00989 } 00990 break; 00991 00992 case Virtual: 00993 00994 if (Pcb1->Partition[Index].Virtual.RelatedReference != Pcb2->Partition[Index].Virtual.RelatedReference) { 00995 00996 return FALSE; 00997 } 00998 break; 00999 01000 default: 01001 01002 ASSERT( FALSE); 01003 return FALSE; 01004 break; 01005 } 01006 } 01007 01008 // 01009 // All map elements were equivalent. 01010 // 01011 01012 return TRUE; 01013 }

LONG UdfExceptionFilter IN PIRP_CONTEXT  IrpContext,
IN PEXCEPTION_POINTERS  ExceptionPointer
 

Definition at line 448 of file udfdata.c.

References ASSERT_OPTIONAL_IRP_CONTEXT, Dbg, DebugTrace, EXCEPTION_EXECUTE_HANDLER, FALSE, FsRtlIsNtstatusExpected(), NTSTATUS(), TRUE, and UdfBugCheck.

Referenced by UdfFindFileSetDescriptor(), UdfFsdDispatch(), UdfFspDispatch(), UdfOpenObjectByFileId(), UdfPerformVerify(), and UdfProcessException().

00455 : 00456 00457 This routine is used to decide whether we will handle a raised exception 00458 status. If UDFS explicitly raised an error then this status is already 00459 in the IrpContext. We choose which is the correct status code and 00460 either indicate that we will handle the exception or bug-check the system. 00461 00462 Arguments: 00463 00464 ExceptionCode - Supplies the exception code to being checked. 00465 00466 Return Value: 00467 00468 ULONG - returns EXCEPTION_EXECUTE_HANDLER or bugchecks 00469 00470 --*/ 00471 00472 { 00473 NTSTATUS ExceptionCode; 00474 BOOLEAN TestStatus = TRUE; 00475 00476 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00477 00478 ExceptionCode = ExceptionPointer->ExceptionRecord->ExceptionCode; 00479 00480 DebugTrace(( 0, Dbg, 00481 "UdfExceptionFilter: %08x (exr %08x cxr %08x)\n", 00482 ExceptionCode, 00483 ExceptionPointer->ExceptionRecord, 00484 ExceptionPointer->ContextRecord )); 00485 00486 00487 // 00488 // If the exception is STATUS_IN_PAGE_ERROR, get the I/O error code 00489 // from the exception record. 00490 // 00491 00492 if ((ExceptionCode == STATUS_IN_PAGE_ERROR) && 00493 (ExceptionPointer->ExceptionRecord->NumberParameters >= 3)) { 00494 00495 ExceptionCode = (NTSTATUS) ExceptionPointer->ExceptionRecord->ExceptionInformation[2]; 00496 } 00497 00498 // 00499 // If there is an Irp context then check which status code to use. 00500 // 00501 00502 if (ARGUMENT_PRESENT( IrpContext )) { 00503 00504 if (IrpContext->ExceptionStatus == STATUS_SUCCESS) { 00505 00506 // 00507 // Store the real status into the IrpContext. 00508 // 00509 00510 IrpContext->ExceptionStatus = ExceptionCode; 00511 00512 } else { 00513 00514 // 00515 // No need to test the status code if we raised it ourselves. 00516 // 00517 00518 TestStatus = FALSE; 00519 } 00520 } 00521 00522 // 00523 // Bug check if this status is not supported. 00524 // 00525 00526 if (TestStatus && !FsRtlIsNtstatusExpected( ExceptionCode )) { 00527 00528 UdfBugCheck( (ULONG_PTR) ExceptionPointer->ExceptionRecord, 00529 (ULONG_PTR) ExceptionPointer->ContextRecord, 00530 (ULONG_PTR) ExceptionPointer->ExceptionRecord->ExceptionAddress ); 00531 00532 } 00533 00534 return EXCEPTION_EXECUTE_HANDLER; 00535 }

TYPE_OF_OPEN UdfFastDecodeFileObject IN PFILE_OBJECT  FileObject,
OUT PFCB Fcb
 

Definition at line 201 of file filobsup.c.

References ASSERT_FILE_OBJECT, FlagOn, PAGED_CODE, TYPE_OF_OPEN, and TYPE_OF_OPEN_MASK.

Referenced by UdfFastLock(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), and UdfFastUnlockSingle().

00208 : 00209 00210 This procedure takes a pointer to a file object, that has already been 00211 opened by Udfs and does a quick decode operation. It will only return 00212 a non null value if the file object is a user file open 00213 00214 Arguments: 00215 00216 FileObject - Supplies the file object pointer being interrogated 00217 00218 Fcb - Address to store Fcb if this is a user file object. NULL 00219 otherwise. 00220 00221 Return Value: 00222 00223 TYPE_OF_OPEN - type of open of this file object. 00224 00225 --*/ 00226 00227 { 00228 PAGED_CODE(); 00229 00230 ASSERT_FILE_OBJECT( FileObject ); 00231 00232 // 00233 // The Fcb is in the FsContext field. The type of open is in the low 00234 // bits of the Ccb. 00235 // 00236 00237 *Fcb = FileObject->FsContext; 00238 00239 return (TYPE_OF_OPEN) FlagOn( (ULONG_PTR) FileObject->FsContext2, TYPE_OF_OPEN_MASK ); 00240 }

INLINE VOID UdfFastInitializeIcbContext IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext
 

Definition at line 1872 of file udfprocs.h.

Referenced by UdfInitializeCompoundDirContext().

01876 { 01877 01878 RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 01879 }

BOOLEAN 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 972 of file udfdata.c.

References PAGED_CODE, and TRUE.

Referenced by UdfInitializeGlobalData().

00985 : 00986 00987 This routine checks if fast i/o is possible for a read/write operation 00988 00989 Arguments: 00990 00991 FileObject - Supplies the file object used in the query 00992 00993 FileOffset - Supplies the starting byte offset for the read/write operation 00994 00995 Length - Supplies the length, in bytes, of the read/write operation 00996 00997 Wait - Indicates if we can wait 00998 00999 LockKey - Supplies the lock key 01000 01001 CheckForReadOperation - Indicates if this is a check for a read or write 01002 operation 01003 01004 IoStatus - Receives the status of the operation if our return value is 01005 FastIoReturnError 01006 01007 Return Value: 01008 01009 BOOLEAN - TRUE if fast I/O is possible and FALSE if the caller needs 01010 to take the long route. 01011 01012 --*/ 01013 01014 { 01015 PAGED_CODE(); 01016 01017 return TRUE; 01018 }

BOOLEAN 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 152 of file lockctrl.c.

References ASSERT_FILE_OBJECT, FALSE, FastIoIsPossible, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlFastLock, FsRtlOplockIsFastIoPossible(), Key, NULL, PAGED_CODE, TRUE, try_leave, TYPE_OF_OPEN, UdfCreateFileLock(), UdfFastDecodeFileObject(), UdfIsFastIoPossible, UdfLockFcb, UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

00166 : 00167 00168 This is a call back routine for doing the fast lock call. 00169 00170 Arguments: 00171 00172 FileObject - Supplies the file object used in this operation 00173 00174 FileOffset - Supplies the file offset used in this operation 00175 00176 Length - Supplies the length used in this operation 00177 00178 ProcessId - Supplies the process ID used in this operation 00179 00180 Key - Supplies the key used in this operation 00181 00182 FailImmediately - Indicates if the request should fail immediately 00183 if the lock cannot be granted. 00184 00185 ExclusiveLock - Indicates if this is a request for an exclusive or 00186 shared lock 00187 00188 IoStatus - Receives the Status if this operation is successful 00189 00190 Return Value: 00191 00192 BOOLEAN - TRUE if this operation completed and FALSE if caller 00193 needs to take the long route. 00194 00195 --*/ 00196 00197 { 00198 BOOLEAN Results = FALSE; 00199 00200 PFCB Fcb; 00201 TYPE_OF_OPEN TypeOfOpen; 00202 00203 PAGED_CODE(); 00204 00205 ASSERT_FILE_OBJECT( FileObject ); 00206 00207 IoStatus->Information = 0; 00208 00209 // 00210 // Decode the type of file object we're being asked to process and 00211 // make sure that is is only a user file open. 00212 // 00213 00214 TypeOfOpen = UdfFastDecodeFileObject( FileObject, &Fcb ); 00215 00216 if (TypeOfOpen != UserFileOpen) { 00217 00218 IoStatus->Status = STATUS_INVALID_PARAMETER; 00219 return TRUE; 00220 } 00221 00222 // 00223 // Only deal with 'good' Fcb's. 00224 // 00225 00226 if (!UdfVerifyFcbOperation( NULL, Fcb )) { 00227 00228 return FALSE; 00229 } 00230 00231 FsRtlEnterFileSystem(); 00232 00233 // 00234 // Use a try-finally to facilitate cleanup. 00235 // 00236 00237 try { 00238 00239 // 00240 // We check whether we can proceed based on the state of the file oplocks. 00241 // 00242 00243 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { 00244 00245 try_leave( NOTHING ); 00246 } 00247 00248 // 00249 // If we don't have a file lock, then get one now. 00250 // 00251 00252 if ((Fcb->FileLock == NULL) && !UdfCreateFileLock( NULL, Fcb, FALSE )) { 00253 00254 try_leave( NOTHING ); 00255 } 00256 00257 // 00258 // Now call the FsRtl routine to perform the lock request. 00259 // 00260 00261 if (Results = FsRtlFastLock( Fcb->FileLock, 00262 FileObject, 00263 FileOffset, 00264 Length, 00265 ProcessId, 00266 Key, 00267 FailImmediately, 00268 ExclusiveLock, 00269 IoStatus, 00270 NULL, 00271 FALSE )) { 00272 00273 // 00274 // Set the flag indicating if Fast I/O is questionable. We 00275 // only change this flag if the current state is possible. 00276 // Retest again after synchronizing on the header. 00277 // 00278 00279 if (Fcb->IsFastIoPossible == FastIoIsPossible) { 00280 00281 UdfLockFcb( NULL, Fcb ); 00282 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00283 UdfUnlockFcb( NULL, Fcb ); 00284 } 00285 } 00286 00287 } finally { 00288 00289 FsRtlExitFileSystem(); 00290 } 00291 00292 return Results; 00293 }

BOOLEAN UdfFastQueryBasicInfo IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Wait,
IN OUT PFILE_BASIC_INFORMATION  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 496 of file fileinfo.c.

References _TIMESTAMP_BUNDLE::AccessTime, ASSERT, ASSERT_FILE_OBJECT, Buffer, _TIMESTAMP_BUNDLE::CreationTime, ExAcquireResourceShared, ExReleaseResource, FALSE, FCB_STATE_INITIALIZED, _FCB::FcbState, _FCB::FileAttributes, FlagOn, FsRtlEnterFileSystem, FsRtlExitFileSystem, _TIMESTAMP_BUNDLE::ModificationTime, NULL, PAGED_CODE, _FCB::Timestamps, TRUE, TYPE_OF_OPEN, UdfDecodeFileObject(), UdfGetExtraFileAttributes(), UdfVerifyFcbOperation(), UserDirectoryOpen, and UserFileOpen.

00506 : 00507 00508 This routine is for the fast query call for basic file information. 00509 00510 Arguments: 00511 00512 FileObject - Supplies the file object used in this operation 00513 00514 Wait - Indicates if we are allowed to wait for the information 00515 00516 Buffer - Supplies the output buffer to receive the basic information 00517 00518 IoStatus - Receives the final status of the operation 00519 00520 Return Value: 00521 00522 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller 00523 needs to take the long route. 00524 00525 --*/ 00526 00527 { 00528 BOOLEAN Result = FALSE; 00529 TYPE_OF_OPEN TypeOfOpen; 00530 00531 PFCB Fcb; 00532 PCCB Ccb; 00533 00534 PAGED_CODE(); 00535 00536 ASSERT_FILE_OBJECT( FileObject ); 00537 00538 FsRtlEnterFileSystem(); 00539 00540 // 00541 // Decode the file object to find the type of open and the data 00542 // structures. 00543 // 00544 00545 TypeOfOpen = UdfDecodeFileObject( FileObject, &Fcb, &Ccb ); 00546 00547 // 00548 // We only support this request on user file or directory objects. 00549 // 00550 00551 ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED )); 00552 00553 if (TypeOfOpen != UserFileOpen && TypeOfOpen != UserDirectoryOpen) { 00554 00555 FsRtlExitFileSystem(); 00556 return FALSE; 00557 } 00558 00559 // 00560 // Acquire the file shared to access the Fcb. 00561 // 00562 00563 if (!ExAcquireResourceShared( Fcb->Resource, Wait )) { 00564 00565 FsRtlExitFileSystem(); 00566 return FALSE; 00567 } 00568 00569 // 00570 // Use a try-finally to facilitate cleanup. 00571 // 00572 00573 try { 00574 00575 // 00576 // Only deal with 'good' Fcb's. 00577 // 00578 00579 if (UdfVerifyFcbOperation( NULL, Fcb )) { 00580 00581 // 00582 // Fill in the input buffer from the Fcb fields. 00583 // 00584 00585 Buffer->CreationTime = Fcb->Timestamps.CreationTime; 00586 Buffer->LastWriteTime = 00587 Buffer->ChangeTime = Fcb->Timestamps.ModificationTime; 00588 Buffer->LastAccessTime = Fcb->Timestamps.AccessTime; 00589 00590 Buffer->FileAttributes = Fcb->FileAttributes | UdfGetExtraFileAttributes( Ccb ); 00591 00592 // 00593 // Update the IoStatus block with the size of this data. 00594 // 00595 00596 IoStatus->Status = STATUS_SUCCESS; 00597 IoStatus->Information = sizeof( FILE_BASIC_INFORMATION ); 00598 00599 Result = TRUE; 00600 } 00601 00602 } finally { 00603 00604 ExReleaseResource( Fcb->Resource ); 00605 00606 FsRtlExitFileSystem(); 00607 } 00608 00609 return Result; 00610 }

BOOLEAN UdfFastQueryNetworkInfo IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Wait,
OUT PFILE_NETWORK_OPEN_INFORMATION  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 740 of file fileinfo.c.

References _TIMESTAMP_BUNDLE::AccessTime, ASSERT_FILE_OBJECT, Buffer, _TIMESTAMP_BUNDLE::CreationTime, ExAcquireResourceShared, ExReleaseResource, FALSE, _FCB::FileAttributes, FlagOn, FsRtlEnterFileSystem, FsRtlExitFileSystem, _TIMESTAMP_BUNDLE::ModificationTime, NULL, PAGED_CODE, _FCB::Timestamps, TRUE, TYPE_OF_OPEN, UdfDecodeFileObject(), UdfGetExtraFileAttributes(), UdfVerifyFcbOperation(), UserDirectoryOpen, and UserFileOpen.

00750 : 00751 00752 This routine is for the fast query call for network file information. 00753 00754 Arguments: 00755 00756 FileObject - Supplies the file object used in this operation 00757 00758 Wait - Indicates if we are allowed to wait for the information 00759 00760 Buffer - Supplies the output buffer to receive the basic information 00761 00762 IoStatus - Receives the final status of the operation 00763 00764 Return Value: 00765 00766 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller 00767 needs to take the long route. 00768 00769 --*/ 00770 00771 { 00772 BOOLEAN Result = FALSE; 00773 TYPE_OF_OPEN TypeOfOpen; 00774 00775 PFCB Fcb; 00776 PCCB Ccb; 00777 00778 PAGED_CODE(); 00779 00780 ASSERT_FILE_OBJECT( FileObject ); 00781 00782 FsRtlEnterFileSystem(); 00783 00784 // 00785 // Decode the file object to find the type of open and the data 00786 // structures. 00787 // 00788 00789 TypeOfOpen = UdfDecodeFileObject( FileObject, &Fcb, &Ccb ); 00790 00791 // 00792 // We only support this request on user file or directory objects. 00793 // 00794 00795 if (TypeOfOpen != UserFileOpen && TypeOfOpen != UserDirectoryOpen) { 00796 00797 FsRtlExitFileSystem(); 00798 return FALSE; 00799 } 00800 00801 // 00802 // Acquire the file shared to access the Fcb. 00803 // 00804 00805 if (!ExAcquireResourceShared( Fcb->Resource, Wait )) { 00806 00807 FsRtlExitFileSystem(); 00808 return FALSE; 00809 } 00810 00811 // 00812 // Use a try-finally to facilitate cleanup. 00813 // 00814 00815 try { 00816 00817 // 00818 // Only deal with 'good' Fcb's. 00819 // 00820 00821 if (UdfVerifyFcbOperation( NULL, Fcb )) { 00822 00823 // 00824 // Fill in the input buffer from the Fcb fields. 00825 // 00826 00827 Buffer->CreationTime = Fcb->Timestamps.CreationTime; 00828 Buffer->LastWriteTime = 00829 Buffer->ChangeTime = Fcb->Timestamps.ModificationTime; 00830 Buffer->LastAccessTime = Fcb->Timestamps.AccessTime; 00831 00832 Buffer->FileAttributes = Fcb->FileAttributes | UdfGetExtraFileAttributes( Ccb ); 00833 00834 // 00835 // Check whether this is a directory. 00836 // 00837 00838 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { 00839 00840 Buffer->AllocationSize.QuadPart = 00841 Buffer->EndOfFile.QuadPart = 0; 00842 00843 } else { 00844 00845 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; 00846 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; 00847 } 00848 00849 // 00850 // Update the IoStatus block with the size of this data. 00851 // 00852 00853 IoStatus->Status = STATUS_SUCCESS; 00854 IoStatus->Information = sizeof( FILE_NETWORK_OPEN_INFORMATION ); 00855 00856 Result = TRUE; 00857 } 00858 00859 } finally { 00860 00861 ExReleaseResource( Fcb->Resource ); 00862 00863 FsRtlExitFileSystem(); 00864 } 00865 00866 return Result; 00867 }

BOOLEAN UdfFastQueryStdInfo IN PFILE_OBJECT  FileObject,
IN BOOLEAN  Wait,
IN OUT PFILE_STANDARD_INFORMATION  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 614 of file fileinfo.c.

References ASSERT_FILE_OBJECT, Buffer, ExAcquireResourceShared, ExReleaseResource, FALSE, _FCB::FileAttributes, FlagOn, FsRtlEnterFileSystem, FsRtlExitFileSystem, _FCB::LinkCount, NULL, PAGED_CODE, TRUE, TYPE_OF_OPEN, UdfFastDecodeFileObject(), UdfVerifyFcbOperation(), UserDirectoryOpen, and UserFileOpen.

00624 : 00625 00626 This routine is for the fast query call for standard file information. 00627 00628 Arguments: 00629 00630 FileObject - Supplies the file object used in this operation 00631 00632 Wait - Indicates if we are allowed to wait for the information 00633 00634 Buffer - Supplies the output buffer to receive the basic information 00635 00636 IoStatus - Receives the final status of the operation 00637 00638 Return Value: 00639 00640 BOOLEAN - TRUE if the operation succeeded and FALSE if the caller 00641 needs to take the long route. 00642 00643 --*/ 00644 00645 { 00646 BOOLEAN Result = FALSE; 00647 TYPE_OF_OPEN TypeOfOpen; 00648 00649 PFCB Fcb; 00650 00651 PAGED_CODE(); 00652 00653 ASSERT_FILE_OBJECT( FileObject ); 00654 00655 FsRtlEnterFileSystem(); 00656 00657 // 00658 // Decode the file object to find the type of open and the data 00659 // structures. 00660 // 00661 00662 TypeOfOpen = UdfFastDecodeFileObject( FileObject, &Fcb ); 00663 00664 // 00665 // We only support this request on initialized user file or directory objects. 00666 // 00667 00668 if (TypeOfOpen != UserFileOpen && TypeOfOpen != UserDirectoryOpen) { 00669 00670 FsRtlExitFileSystem(); 00671 return FALSE; 00672 } 00673 00674 // 00675 // Acquire the file shared to access the Fcb. 00676 // 00677 00678 if (!ExAcquireResourceShared( Fcb->Resource, Wait )) { 00679 00680 FsRtlExitFileSystem(); 00681 return FALSE; 00682 } 00683 00684 // 00685 // Use a try-finally to facilitate cleanup. 00686 // 00687 00688 try { 00689 00690 // 00691 // Only deal with 'good' Fcb's. 00692 // 00693 00694 if (UdfVerifyFcbOperation( NULL, Fcb )) { 00695 00696 // 00697 // Check whether this is a directory. 00698 // 00699 00700 if (FlagOn( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY )) { 00701 00702 Buffer->AllocationSize.QuadPart = 00703 Buffer->EndOfFile.QuadPart = 0; 00704 00705 Buffer->Directory = TRUE; 00706 00707 } else { 00708 00709 Buffer->AllocationSize.QuadPart = Fcb->AllocationSize.QuadPart; 00710 Buffer->EndOfFile.QuadPart = Fcb->FileSize.QuadPart; 00711 00712 Buffer->Directory = FALSE; 00713 } 00714 00715 Buffer->NumberOfLinks = Fcb->LinkCount; 00716 Buffer->DeletePending = FALSE; 00717 00718 // 00719 // Update the IoStatus block with the size of this data. 00720 // 00721 00722 IoStatus->Status = STATUS_SUCCESS; 00723 IoStatus->Information = sizeof( FILE_STANDARD_INFORMATION ); 00724 00725 Result = TRUE; 00726 } 00727 00728 } finally { 00729 00730 ExReleaseResource( Fcb->Resource ); 00731 00732 FsRtlExitFileSystem(); 00733 } 00734 00735 return Result; 00736 }

BOOLEAN UdfFastUnlockAll IN PFILE_OBJECT  FileObject,
PEPROCESS  ProcessId,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 436 of file lockctrl.c.

References FALSE, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlFastUnlockAll(), FsRtlOplockIsFastIoPossible(), NULL, PAGED_CODE, TRUE, try_leave, TYPE_OF_OPEN, UdfCreateFileLock(), UdfFastDecodeFileObject(), UdfIsFastIoPossible, UdfLockFcb, UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

00445 : 00446 00447 This is a call back routine for doing the fast unlock all call. 00448 00449 Arguments: 00450 00451 FileObject - Supplies the file object used in this operation 00452 00453 ProcessId - Supplies the process ID used in this operation 00454 00455 Status - Receives the Status if this operation is successful 00456 00457 Return Value: 00458 00459 BOOLEAN - TRUE if this operation completed and FALSE if caller 00460 needs to take the long route. 00461 00462 --*/ 00463 00464 { 00465 BOOLEAN Results = FALSE; 00466 TYPE_OF_OPEN TypeOfOpen; 00467 PFCB Fcb; 00468 00469 PAGED_CODE(); 00470 00471 IoStatus->Information = 0; 00472 00473 // 00474 // Decode the type of file object we're being asked to process and 00475 // make sure that is is only a user file open. 00476 // 00477 00478 TypeOfOpen = UdfFastDecodeFileObject( FileObject, &Fcb ); 00479 00480 if (TypeOfOpen != UserFileOpen) { 00481 00482 IoStatus->Status = STATUS_INVALID_PARAMETER; 00483 return TRUE; 00484 } 00485 00486 // 00487 // Only deal with 'good' Fcb's. 00488 // 00489 00490 if (!UdfVerifyFcbOperation( NULL, Fcb )) { 00491 00492 return FALSE; 00493 } 00494 00495 // 00496 // If there is no lock then return immediately. 00497 // 00498 00499 if (Fcb->FileLock == NULL) { 00500 00501 IoStatus->Status = STATUS_RANGE_NOT_LOCKED; 00502 return TRUE; 00503 } 00504 00505 FsRtlEnterFileSystem(); 00506 00507 try { 00508 00509 // 00510 // We check whether we can proceed based on the state of the file oplocks. 00511 // 00512 00513 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { 00514 00515 try_leave( NOTHING ); 00516 } 00517 00518 // 00519 // If we don't have a file lock, then get one now. 00520 // 00521 00522 if ((Fcb->FileLock == NULL) && !UdfCreateFileLock( NULL, Fcb, FALSE )) { 00523 00524 try_leave( NOTHING ); 00525 } 00526 00527 // 00528 // Now call the FsRtl routine to do the actual processing of the 00529 // Lock request. The call will always succeed. 00530 // 00531 00532 Results = TRUE; 00533 IoStatus->Status = FsRtlFastUnlockAll( Fcb->FileLock, 00534 FileObject, 00535 ProcessId, 00536 NULL ); 00537 00538 00539 // 00540 // Set the flag indicating if Fast I/O is possible 00541 // 00542 00543 UdfLockFcb( IrpContext, Fcb ); 00544 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00545 UdfUnlockFcb( IrpContext, Fcb ); 00546 00547 } finally { 00548 00549 FsRtlExitFileSystem(); 00550 } 00551 00552 return Results; 00553 }

BOOLEAN UdfFastUnlockAllByKey IN PFILE_OBJECT  FileObject,
PVOID  ProcessId,
ULONG  Key,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 557 of file lockctrl.c.

References FALSE, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlFastUnlockAllByKey(), FsRtlOplockIsFastIoPossible(), Key, NULL, PAGED_CODE, TRUE, try_leave, TYPE_OF_OPEN, UdfCreateFileLock(), UdfFastDecodeFileObject(), UdfIsFastIoPossible, UdfLockFcb, UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

00567 : 00568 00569 This is a call back routine for doing the fast unlock all by key call. 00570 00571 Arguments: 00572 00573 FileObject - Supplies the file object used in this operation 00574 00575 ProcessId - Supplies the process ID used in this operation 00576 00577 Key - Supplies the key used in this operation 00578 00579 Status - Receives the Status if this operation is successful 00580 00581 Return Value: 00582 00583 BOOLEAN - TRUE if this operation completed and FALSE if caller 00584 needs to take the long route. 00585 00586 --*/ 00587 00588 { 00589 BOOLEAN Results = FALSE; 00590 TYPE_OF_OPEN TypeOfOpen; 00591 PFCB Fcb; 00592 00593 PAGED_CODE(); 00594 00595 IoStatus->Information = 0; 00596 00597 // 00598 // Decode the type of file object we're being asked to process and 00599 // make sure that is is only a user file open. 00600 // 00601 00602 TypeOfOpen = UdfFastDecodeFileObject( FileObject, &Fcb ); 00603 00604 if (TypeOfOpen != UserFileOpen) { 00605 00606 IoStatus->Status = STATUS_INVALID_PARAMETER; 00607 return TRUE; 00608 } 00609 00610 // 00611 // Only deal with 'good' Fcb's. 00612 // 00613 00614 if (!UdfVerifyFcbOperation( NULL, Fcb )) { 00615 00616 return FALSE; 00617 } 00618 00619 // 00620 // If there is no lock then return immediately. 00621 // 00622 00623 if (Fcb->FileLock == NULL) { 00624 00625 IoStatus->Status = STATUS_RANGE_NOT_LOCKED; 00626 return TRUE; 00627 } 00628 00629 FsRtlEnterFileSystem(); 00630 00631 try { 00632 00633 // 00634 // We check whether we can proceed based on the state of the file oplocks. 00635 // 00636 00637 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { 00638 00639 try_leave( NOTHING ); 00640 } 00641 00642 // 00643 // If we don't have a file lock, then get one now. 00644 // 00645 00646 if ((Fcb->FileLock == NULL) && !UdfCreateFileLock( NULL, Fcb, FALSE )) { 00647 00648 try_leave( NOTHING ); 00649 } 00650 00651 // 00652 // Now call the FsRtl routine to do the actual processing of the 00653 // Lock request. The call will always succeed. 00654 // 00655 00656 Results = TRUE; 00657 IoStatus->Status = FsRtlFastUnlockAllByKey( Fcb->FileLock, 00658 FileObject, 00659 ProcessId, 00660 Key, 00661 NULL ); 00662 00663 00664 // 00665 // Set the flag indicating if Fast I/O is possible 00666 // 00667 00668 UdfLockFcb( IrpContext, Fcb ); 00669 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00670 UdfUnlockFcb( IrpContext, Fcb ); 00671 00672 } finally { 00673 00674 FsRtlExitFileSystem(); 00675 } 00676 00677 return Results; 00678 }

BOOLEAN 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 297 of file lockctrl.c.

References FALSE, FastIoIsPossible, FsRtlAreThereCurrentFileLocks, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlFastUnlockSingle(), FsRtlOplockIsFastIoPossible(), Key, NULL, PAGED_CODE, TRUE, try_leave, TYPE_OF_OPEN, UdfCreateFileLock(), UdfFastDecodeFileObject(), UdfIsFastIoPossible, UdfLockFcb, UdfUnlockFcb, UdfVerifyFcbOperation(), and UserFileOpen.

00309 : 00310 00311 This is a call back routine for doing the fast unlock single call. 00312 00313 Arguments: 00314 00315 FileObject - Supplies the file object used in this operation 00316 00317 FileOffset - Supplies the file offset used in this operation 00318 00319 Length - Supplies the length used in this operation 00320 00321 ProcessId - Supplies the process ID used in this operation 00322 00323 Key - Supplies the key used in this operation 00324 00325 Status - Receives the Status if this operation is successful 00326 00327 Return Value: 00328 00329 BOOLEAN - TRUE if this operation completed and FALSE if caller 00330 needs to take the long route. 00331 00332 --*/ 00333 00334 { 00335 BOOLEAN Results = FALSE; 00336 TYPE_OF_OPEN TypeOfOpen; 00337 PFCB Fcb; 00338 00339 PAGED_CODE(); 00340 00341 IoStatus->Information = 0; 00342 00343 // 00344 // Decode the type of file object we're being asked to process and 00345 // make sure that is is only a user file open. 00346 // 00347 00348 TypeOfOpen = UdfFastDecodeFileObject( FileObject, &Fcb ); 00349 00350 if (TypeOfOpen != UserFileOpen) { 00351 00352 IoStatus->Status = STATUS_INVALID_PARAMETER; 00353 return TRUE; 00354 } 00355 00356 // 00357 // Only deal with 'good' Fcb's. 00358 // 00359 00360 if (!UdfVerifyFcbOperation( NULL, Fcb )) { 00361 00362 return FALSE; 00363 } 00364 00365 // 00366 // If there is no lock then return immediately. 00367 // 00368 00369 if (Fcb->FileLock == NULL) { 00370 00371 IoStatus->Status = STATUS_RANGE_NOT_LOCKED; 00372 return TRUE; 00373 } 00374 00375 FsRtlEnterFileSystem(); 00376 00377 try { 00378 00379 // 00380 // We check whether we can proceed based on the state of the file oplocks. 00381 // 00382 00383 if ((Fcb->Oplock != NULL) && !FsRtlOplockIsFastIoPossible( &Fcb->Oplock )) { 00384 00385 try_leave( NOTHING ); 00386 } 00387 00388 // 00389 // If we don't have a file lock, then get one now. 00390 // 00391 00392 if ((Fcb->FileLock == NULL) && !UdfCreateFileLock( NULL, Fcb, FALSE )) { 00393 00394 try_leave( NOTHING ); 00395 } 00396 00397 // 00398 // Now call the FsRtl routine to do the actual processing of the 00399 // Lock request. The call will always succeed. 00400 // 00401 00402 Results = TRUE; 00403 IoStatus->Status = FsRtlFastUnlockSingle( Fcb->FileLock, 00404 FileObject, 00405 FileOffset, 00406 Length, 00407 ProcessId, 00408 Key, 00409 NULL, 00410 FALSE ); 00411 00412 // 00413 // Set the flag indicating if Fast I/O is possible. We are 00414 // only concerned if there are no longer any filelocks on this 00415 // file. 00416 // 00417 00418 if (!FsRtlAreThereCurrentFileLocks( Fcb->FileLock ) && 00419 (Fcb->IsFastIoPossible != FastIoIsPossible)) { 00420 00421 UdfLockFcb( IrpContext, Fcb ); 00422 Fcb->IsFastIoPossible = UdfIsFastIoPossible( Fcb ); 00423 UdfUnlockFcb( IrpContext, Fcb ); 00424 } 00425 00426 } finally { 00427 00428 FsRtlExitFileSystem(); 00429 } 00430 00431 return Results; 00432 }

BOOLEAN UdfFindDirEntry IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PUNICODE_STRING  Name,
IN BOOLEAN  IgnoreCase,
IN BOOLEAN  ShortName,
IN PDIR_ENUM_CONTEXT  DirContext
 

Definition at line 726 of file dirsup.c.

References ASSERT_FCB_INDEX, ASSERT_IRP_CONTEXT, BYTE_COUNT_8_DOT_3, Dbg, DebugTrace, DIR_CONTEXT_FLAG_SEEN_NONCONSTANT, EqualTo, FALSE, FlagOn, FsRtlAllocatePoolWithTag, Name, NSR_FID_F_DELETED, NULL, PAGED_CODE, TAG_SHORT_FILE_NAME, TRUE, UdfFullCompareNames(), UdfGenerate8dot3Name(), UdfIs8dot3Name(), UdfLookupInitialDirEntry(), UdfLookupNextDirEntry(), UdfPagedPool, and UdfUpdateDirNames().

Referenced by UdfCommonCreate(), and UdfQueryAlternateNameInfo().

00737 : 00738 00739 This routine walks the directory specified for an entry which matches the input 00740 criteria. 00741 00742 Arguments: 00743 00744 Fcb - the directory to search 00745 00746 Name - name to search for 00747 00748 IgnoreCase - whether this search should be case-insensitive (Name will already 00749 be upcased) 00750 00751 ShortName - whether the name should be searched for according to short name rules 00752 00753 DirContext - context structure to use and return results in 00754 00755 Return Value: 00756 00757 BOOLEAN True if a matching directory entry is being returned, False otherwise. 00758 00759 --*/ 00760 00761 { 00762 PUNICODE_STRING MatchName; 00763 00764 PAGED_CODE(); 00765 00766 // 00767 // Check inputs. 00768 // 00769 00770 ASSERT_IRP_CONTEXT( IrpContext ); 00771 ASSERT_FCB_INDEX( Fcb ); 00772 00773 DebugTrace(( +1, Dbg, 00774 "UdfFindDirEntry, Fcb=%08x Name=\"%wZ\" Ignore=%u Short=%u, DC=%08x\n", 00775 Fcb, 00776 Name, 00777 IgnoreCase, 00778 ShortName, 00779 DirContext )); 00780 00781 // 00782 // Depending on the kind of search we are performing a different flavor of the found name 00783 // wil be used in the comparison. 00784 // 00785 00786 if (ShortName) { 00787 00788 MatchName = &DirContext->ShortObjectName; 00789 00790 } else { 00791 00792 MatchName = &DirContext->CaseObjectName; 00793 } 00794 00795 00796 // 00797 // Go get the first entry. 00798 // 00799 00800 UdfLookupInitialDirEntry( IrpContext, 00801 Fcb, 00802 DirContext, 00803 NULL ); 00804 00805 // 00806 // Now loop looking for a good match. 00807 // 00808 00809 do { 00810 00811 // 00812 // If it is deleted, we obviously aren't interested in it. 00813 // 00814 00815 if (FlagOn( DirContext->Fid->Flags, NSR_FID_F_DELETED )) { 00816 00817 continue; 00818 } 00819 00820 UdfUpdateDirNames( IrpContext, 00821 DirContext, 00822 IgnoreCase ); 00823 00824 00825 // 00826 // If this is a constant entry, just keep going. 00827 // 00828 00829 if (!FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_SEEN_NONCONSTANT )) { 00830 00831 continue; 00832 } 00833 00834 DebugTrace(( 0, Dbg, 00835 "\"%wZ\" (pure \"%wZ\") @ +%08x\n", 00836 &DirContext->ObjectName, 00837 &DirContext->PureObjectName, 00838 DirContext->ViewOffset )); 00839 00840 // 00841 // If we are searching for generated shortnames, a small subset of the names 00842 // in the directory are actually candidates for a match. Go get the name. 00843 // 00844 00845 if (ShortName) { 00846 00847 // 00848 // Now, only if this Fid's name is non 8.3 is it neccesary to work with it. 00849 // 00850 00851 if (!UdfIs8dot3Name( IrpContext, DirContext->ObjectName )) { 00852 00853 // 00854 // Allocate the shortname if it isn't already done. 00855 // 00856 00857 if (DirContext->ShortObjectName.Buffer == NULL) { 00858 00859 DirContext->ShortObjectName.Buffer = FsRtlAllocatePoolWithTag( UdfPagedPool, 00860 BYTE_COUNT_8_DOT_3, 00861 TAG_SHORT_FILE_NAME ); 00862 DirContext->ShortObjectName.MaximumLength = BYTE_COUNT_8_DOT_3; 00863 } 00864 00865 UdfGenerate8dot3Name( IrpContext, 00866 &DirContext->PureObjectName, 00867 &DirContext->ShortObjectName ); 00868 00869 DebugTrace(( 0, Dbg, 00870 "built shortname \"%wZ\"\n", &DirContext->ShortObjectName )); 00871 00872 } else { 00873 00874 // 00875 // As an 8.3 name already, this name will not have caused us to have to generate 00876 // a short name, so it can't be the case that the caller is looking for it. 00877 // 00878 00879 continue; 00880 } 00881 } 00882 00883 if (UdfFullCompareNames( IrpContext, 00884 MatchName, 00885 Name ) == EqualTo) { 00886 00887 // 00888 // Got a match, so give it up. 00889 // 00890 00891 DebugTrace(( 0, Dbg, "HIT\n" )); 00892 DebugTrace(( -1, Dbg, "UdfFindDirEntry -> TRUE\n" )); 00893 00894 return TRUE; 00895 } 00896 00897 } while ( UdfLookupNextDirEntry( IrpContext, 00898 Fcb, 00899 DirContext )); 00900 00901 // 00902 // No match was found. 00903 // 00904 00905 DebugTrace(( -1, Dbg, "UdfFindDirEntry -> FALSE\n" )); 00906 00907 return FALSE; 00908 }

ULONG UdfFindInParseTable IN PPARSE_KEYVALUE  ParseTable,
IN PCHAR  Id,
IN ULONG  MaxIdLen
 

Definition at line 2552 of file udfs/strucsup.c.

References NULL, PAGED_CODE, and PPARSE_KEYVALUE.

Referenced by UdfRecognizeVolume().

02560 : 02561 02562 This routine walks a table of string key/value information for a match of the 02563 input Id. MaxIdLen can be set to get a prefix match. 02564 02565 Arguments: 02566 02567 Table - This is the table being searched. 02568 02569 Id - Key value. 02570 02571 MaxIdLen - Maximum possible length of Id. 02572 02573 Return Value: 02574 02575 Value of matching entry, or the terminating (NULL) entry's value. 02576 02577 --*/ 02578 02579 { 02580 PAGED_CODE(); 02581 02582 while (ParseTable->Key != NULL) { 02583 02584 if (RtlEqualMemory(ParseTable->Key, Id, MaxIdLen)) { 02585 02586 break; 02587 } 02588 02589 ParseTable++; 02590 } 02591 02592 return ParseTable->Value; 02593 }

PLCB UdfFindPrefix IN PIRP_CONTEXT  IrpContext,
IN OUT PFCB CurrentFcb,
IN OUT PUNICODE_STRING  RemainingName,
IN BOOLEAN  IgnoreCase
 

Definition at line 324 of file prefxsup.c.

References ASSERT, ASSERT_EXCLUSIVE_FCB, ASSERT_FCB, ASSERT_IRP_CONTEXT, FALSE, FlagOn, IRP_CONTEXT_FLAG_WAIT, NULL, PAGED_CODE, SafeNodeType, TRUE, UdfAcquireFcbExclusive, UdfDissectName(), UdfFindNameLink(), UdfLockVcb, UdfRaiseStatus(), UdfReleaseFcb, UDFS_NTC_FCB_INDEX, and UdfUnlockVcb.

Referenced by UdfCommonCreate().

00333 : 00334 00335 This routine begins from the given CurrentFcb and walks through all of 00336 components of the name looking for the longest match in the prefix 00337 splay trees. The search is relative to the starting Fcb so the 00338 full name may not begin with a '\'. On return this routine will 00339 update Current Fcb with the lowest point it has travelled in the 00340 tree. It will also hold only that resource on return and it must 00341 hold that resource. 00342 00343 Arguments: 00344 00345 CurrentFcb - Address to store the lowest Fcb we find on this search. 00346 On return we will have acquired this Fcb. On entry this is the 00347 Fcb to examine. 00348 00349 RemainingName - Supplies a buffer to store the exact case of the name being 00350 searched for. Initially will contain the upcase name based on the 00351 IgnoreCase flag. 00352 00353 IgnoreCase - Indicates if we are doing a case-insensitive compare. 00354 00355 Return Value: 00356 00357 The Lcb used to find the current Fcb, NULL if we didn't find any prefix 00358 Fcbs. 00359 00360 --*/ 00361 00362 { 00363 UNICODE_STRING LocalRemainingName; 00364 UNICODE_STRING FinalName; 00365 00366 PLCB NameLink; 00367 PLCB CurrentLcb = NULL; 00368 00369 PAGED_CODE(); 00370 00371 // 00372 // Check inputs. 00373 // 00374 00375 ASSERT_IRP_CONTEXT( IrpContext ); 00376 ASSERT_FCB( *CurrentFcb ); 00377 ASSERT_EXCLUSIVE_FCB( *CurrentFcb ); 00378 00379 // 00380 // Make a local copy of the input strings. 00381 // 00382 00383 LocalRemainingName = *RemainingName; 00384 00385 // 00386 // Loop until we find the longest matching prefix. 00387 // 00388 00389 while (TRUE) { 00390 00391 // 00392 // If there are no characters left or we are not at an IndexFcb then 00393 // return immediately. 00394 // 00395 00396 if ((LocalRemainingName.Length == 0) || 00397 (SafeNodeType( *CurrentFcb ) != UDFS_NTC_FCB_INDEX)) { 00398 00399 return CurrentLcb; 00400 } 00401 00402 // 00403 // Split off the next component from the name. 00404 // 00405 00406 UdfDissectName( IrpContext, 00407 &LocalRemainingName, 00408 &FinalName ); 00409 00410 // 00411 // Check if this name is in the splay tree for this Scb. 00412 // 00413 00414 if (IgnoreCase) { 00415 00416 NameLink = UdfFindNameLink( IrpContext, 00417 &(*CurrentFcb)->IgnoreCaseRoot, 00418 &FinalName ); 00419 00420 } else { 00421 00422 NameLink = UdfFindNameLink( IrpContext, 00423 &(*CurrentFcb)->ExactCaseRoot, 00424 &FinalName ); 00425 } 00426 00427 // 00428 // If we didn't find a match then exit. 00429 // 00430 00431 if (NameLink == NULL) { 00432 00433 break; 00434 } 00435 00436 CurrentLcb = NameLink; 00437 00438 // 00439 // If this is a case-insensitive match then copy the exact case of the name into 00440 // the input buffer. 00441 // 00442 00443 if (IgnoreCase) { 00444 00445 RtlCopyMemory( FinalName.Buffer, 00446 NameLink->FileName.Buffer, 00447 NameLink->FileName.Length ); 00448 } 00449 00450 // 00451 // Update the caller's remaining name string to reflect the fact that we found 00452 // a match. 00453 // 00454 00455 *RemainingName = LocalRemainingName; 00456 00457 // 00458 // Move down to the next component in the tree. Acquire without waiting. 00459 // If this fails then lock the Fcb to reference this Fcb and then drop 00460 // the parent and acquire the child. 00461 // 00462 00463 ASSERT( NameLink->ParentFcb == *CurrentFcb ); 00464 00465 if (!UdfAcquireFcbExclusive( IrpContext, NameLink->ChildFcb, TRUE )) { 00466 00467 // 00468 // If we can't wait then raise CANT_WAIT. 00469 // 00470 00471 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00472 00473 UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT ); 00474 } 00475 00476 UdfLockVcb( IrpContext, IrpContext->Vcb ); 00477 NameLink->ChildFcb->FcbReference += 1; 00478 NameLink->Reference += 1; 00479 UdfUnlockVcb( IrpContext, IrpContext->Vcb ); 00480 00481 UdfReleaseFcb( IrpContext, *CurrentFcb ); 00482 UdfAcquireFcbExclusive( IrpContext, NameLink->ChildFcb, FALSE ); 00483 00484 UdfLockVcb( IrpContext, IrpContext->Vcb ); 00485 NameLink->ChildFcb->FcbReference -= 1; 00486 NameLink->Reference -= 1; 00487 UdfUnlockVcb( IrpContext, IrpContext->Vcb ); 00488 00489 } else { 00490 00491 UdfReleaseFcb( IrpContext, *CurrentFcb ); 00492 } 00493 00494 *CurrentFcb = NameLink->ChildFcb; 00495 } 00496 00497 return CurrentLcb; 00498 }

INLINE VOID UdfFreePool IN PVOID *  Pool  ) 
 

Definition at line 453 of file udfprocs.h.

References ExFreePool(), and NULL.

Referenced by UdfCleanupDirContext(), UdfCompletePcb(), UdfCreateFcb(), UdfDeleteCcb(), UdfDeletePcb(), UdfDeleteVcb(), UdfDetermineVolumeBounding(), UdfDismountVcb(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfFinishBuffers(), UdfInitializeEnumeration(), UdfInsertPrefix(), UdfLoadSparingTables(), UdfLookupDirEntryPostProcessing(), UdfLookupNextDirEntry(), UdfMountVolume(), UdfRecognizeVolume(), UdfUpdateDirNames(), and UdfVerifyVolume().

00456 { 00457 if (*Pool != NULL) { 00458 00459 ExFreePool(*Pool); 00460 *Pool = NULL; 00461 } 00462 }

NTSTATUS UdfFsdDispatch IN PVOLUME_DEVICE_OBJECT  VolumeDeviceObject,
IN PIRP  Irp
 

Definition at line 218 of file udfdata.c.

References ASSERT, ASSERT_OPTIONAL_IRP, CanFsdWait, FALSE, FlagOn, _IRP_CONTEXT::Flags, FsRtlEnterFileSystem, FsRtlExitFileSystem, IoGetCurrentIrpStackLocation, IoGetTopLevelIrp(), Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_CREATE, IRP_MJ_DEVICE_CONTROL, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_LOCK_CONTROL, IRP_MJ_PNP, IRP_MJ_QUERY_INFORMATION, IRP_MJ_QUERY_VOLUME_INFORMATION, IRP_MJ_READ, IRP_MJ_SET_INFORMATION, IRP_MN_COMPLETE, _IRP_CONTEXT::MajorFunction, _IRP_CONTEXT::MinorFunction, NTSTATUS(), NULL, SafeNodeType, SetFlag, Status, THREAD_CONTEXT, ThreadContext, _IRP_CONTEXT::TopLevel, TRUE, UdfCleanupIrpContext(), UdfCommonCleanup(), UdfCommonClose(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteMdl(), UdfCompleteRequest(), UdfCreateIrpContext(), UdfExceptionFilter(), UdfProcessException(), UDFS_NTC_IRP_CONTEXT, and UdfSetThreadContext().

00225 : 00226 00227 This is the driver entry to all of the Fsd dispatch points. 00228 00229 Conceptually the Io routine will call this routine on all requests 00230 to the file system. We case on the type of request and invoke the 00231 correct handler for this type of request. There is an exception filter 00232 to catch any exceptions in the UDFS code as well as the UDFS process 00233 exception routine. 00234 00235 This routine allocates and initializes the IrpContext for this request as 00236 well as updating the top-level thread context as necessary. We may loop 00237 in this routine if we need to retry the request for any reason. The 00238 status code STATUS_CANT_WAIT is used to indicate this. Suppose the disk 00239 in the drive has changed. An Fsd request will proceed normally until it 00240 recognizes this condition. STATUS_VERIFY_REQUIRED is raised at that point 00241 and the exception code will handle the verify and either return 00242 STATUS_CANT_WAIT or STATUS_PENDING depending on whether the request was 00243 posted. 00244 00245 Arguments: 00246 00247 VolumeDeviceObject - Supplies the volume device object for this request 00248 00249 Irp - Supplies the Irp being processed 00250 00251 Return Value: 00252 00253 NTSTATUS - The FSD status for the IRP 00254 00255 --*/ 00256 00257 { 00258 THREAD_CONTEXT ThreadContext; 00259 PIRP_CONTEXT IrpContext = NULL; 00260 BOOLEAN Wait; 00261 00262 #ifdef UDF_SANITY 00263 PVOID PreviousTopLevel; 00264 #endif 00265 00266 NTSTATUS Status; 00267 00268 KIRQL SaveIrql = KeGetCurrentIrql(); 00269 00270 ASSERT_OPTIONAL_IRP( Irp ); 00271 00272 FsRtlEnterFileSystem(); 00273 00274 #ifdef UDF_SANITY 00275 PreviousTopLevel = IoGetTopLevelIrp(); 00276 #endif 00277 00278 // 00279 // Loop until this request has been completed or posted. 00280 // 00281 00282 do { 00283 00284 // 00285 // Use a try-except to handle the exception cases. 00286 // 00287 00288 try { 00289 00290 // 00291 // If the IrpContext is NULL then this is the first pass through 00292 // this loop. 00293 // 00294 00295 if (IrpContext == NULL) { 00296 00297 // 00298 // Decide if this request is waitable an allocate the IrpContext. 00299 // If the file object in the stack location is NULL then this 00300 // is a mount which is always waitable. Otherwise we look at 00301 // the file object flags. 00302 // 00303 00304 if (IoGetCurrentIrpStackLocation( Irp )->FileObject == NULL) { 00305 00306 Wait = TRUE; 00307 00308 } else { 00309 00310 Wait = CanFsdWait( Irp ); 00311 } 00312 00313 IrpContext = UdfCreateIrpContext( Irp, Wait ); 00314 00315 // 00316 // Update the thread context information. 00317 // 00318 00319 UdfSetThreadContext( IrpContext, &ThreadContext ); 00320 00321 #ifdef UDF_SANITY 00322 ASSERT( !UdfTestTopLevel || 00323 SafeNodeType( IrpContext->TopLevel ) == UDFS_NTC_IRP_CONTEXT ); 00324 #endif 00325 00326 // 00327 // Otherwise cleanup the IrpContext for the retry. 00328 // 00329 00330 } else { 00331 00332 // 00333 // Set the MORE_PROCESSING flag to make sure the IrpContext 00334 // isn't inadvertently deleted here. Then cleanup the 00335 // IrpContext to perform the retry. 00336 // 00337 00338 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00339 UdfCleanupIrpContext( IrpContext, FALSE ); 00340 } 00341 00342 // 00343 // Case on the major irp code. 00344 // 00345 00346 switch (IrpContext->MajorFunction) { 00347 00348 case IRP_MJ_CLEANUP : 00349 00350 Status = UdfCommonCleanup( IrpContext, Irp ); 00351 break; 00352 00353 case IRP_MJ_CLOSE : 00354 00355 Status = UdfCommonClose( IrpContext, Irp ); 00356 break; 00357 00358 case IRP_MJ_CREATE : 00359 00360 Status = UdfCommonCreate( IrpContext, Irp ); 00361 break; 00362 00363 case IRP_MJ_DEVICE_CONTROL : 00364 00365 Status = UdfCommonDevControl( IrpContext, Irp ); 00366 break; 00367 00368 case IRP_MJ_DIRECTORY_CONTROL : 00369 00370 Status = UdfCommonDirControl( IrpContext, Irp ); 00371 break; 00372 00373 case IRP_MJ_FILE_SYSTEM_CONTROL : 00374 00375 Status = UdfCommonFsControl( IrpContext, Irp ); 00376 break; 00377 00378 case IRP_MJ_LOCK_CONTROL : 00379 00380 Status = UdfCommonLockControl( IrpContext, Irp ); 00381 break; 00382 00383 case IRP_MJ_PNP : 00384 00385 Status = UdfCommonPnp( IrpContext, Irp ); 00386 break; 00387 00388 case IRP_MJ_QUERY_INFORMATION : 00389 00390 Status = UdfCommonQueryInfo( IrpContext, Irp ); 00391 break; 00392 00393 case IRP_MJ_QUERY_VOLUME_INFORMATION : 00394 00395 Status = UdfCommonQueryVolInfo( IrpContext, Irp ); 00396 break; 00397 00398 case IRP_MJ_READ : 00399 00400 // 00401 // If this is an Mdl complete request, don't go through 00402 // common read. 00403 // 00404 00405 if (FlagOn( IrpContext->MinorFunction, IRP_MN_COMPLETE )) { 00406 00407 Status = UdfCompleteMdl( IrpContext, Irp ); 00408 00409 } else { 00410 00411 Status = UdfCommonRead( IrpContext, Irp ); 00412 } 00413 00414 break; 00415 00416 case IRP_MJ_SET_INFORMATION : 00417 00418 Status = UdfCommonSetInfo( IrpContext, Irp ); 00419 break; 00420 00421 default : 00422 00423 Status = STATUS_INVALID_DEVICE_REQUEST; 00424 UdfCompleteRequest( IrpContext, Irp, Status ); 00425 } 00426 00427 } except( UdfExceptionFilter( IrpContext, GetExceptionInformation() )) { 00428 00429 Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() ); 00430 } 00431 00432 } while (Status == STATUS_CANT_WAIT); 00433 00434 #ifdef UDF_SANITY 00435 ASSERT( !UdfTestTopLevel || 00436 (PreviousTopLevel == IoGetTopLevelIrp()) ); 00437 #endif 00438 00439 FsRtlExitFileSystem(); 00440 00441 ASSERT( SaveIrql == KeGetCurrentIrql( )); 00442 00443 return Status; 00444 }

NTSTATUS UdfFsdPostRequest IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 61 of file workque.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, Irp, PAGED_CODE, UdfAddToWorkque(), and UdfPrePostIrp().

Referenced by UdfCommonRead(), UdfPerformVerify(), and UdfProcessException().

00068 : 00069 00070 This routine enqueues the request packet specified by IrpContext to the 00071 work queue associated with the FileSystemDeviceObject. This is a FSD 00072 routine. 00073 00074 Arguments: 00075 00076 IrpContext - Pointer to the IrpContext to be queued to the Fsp. 00077 00078 Irp - I/O Request Packet. 00079 00080 Return Value: 00081 00082 STATUS_PENDING 00083 00084 --*/ 00085 00086 { 00087 PAGED_CODE(); 00088 00089 ASSERT_IRP_CONTEXT( IrpContext ); 00090 ASSERT_IRP( Irp ); 00091 00092 // 00093 // Posting is a three step operation. First lock down any buffers 00094 // in the Irp. Next cleanup the IrpContext for the post and finally 00095 // add this to a workque. 00096 // 00097 00098 UdfPrePostIrp( IrpContext, Irp ); 00099 00100 UdfAddToWorkque( IrpContext, Irp ); 00101 00102 // 00103 // And return to our caller 00104 // 00105 00106 return STATUS_PENDING; 00107 }

VOID UdfFspClose IN PVCB Vcb  OPTIONAL  ) 
 

Definition at line 99 of file close.c.

References ASSERT_OPTIONAL_VCB, ClearFlag, Dbg, DebugTrace, _IRP_CONTEXT::ExceptionStatus, FALSE, _FCB::FcbReference, _FCB::FcbUserReference, _IRP_CONTEXT::Flags, FsRtlEnterFileSystem, FsRtlExitFileSystem, _IRP_CONTEXT::Irp, IRP_CONTEXT, IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, IRP_CONTEXT_FSP_FLAGS, _UDF_DATA::MinDelayedCloseCount, NULL, PAGED_CODE, PIRP_CONTEXT_LITE, SafeNodeType, SetFlag, THREAD_CONTEXT, ThreadContext, UdfAcquireUdfData, UdfAcquireVcbShared, UdfCheckForDismount(), UdfCommonClosePrivate(), UdfCompleteRequest(), UdfData, UdfFreeIrpContextLite, UdfInitializeStackIrpContext(), UdfReleaseUdfData, UdfReleaseVcb, UdfRemoveClose(), UDFS_NTC_IRP_CONTEXT, UdfSetThreadContext(), _FCB::Vcb, _VCB::VcbCleanup, _VCB::VcbCondition, VcbMounted, VcbMountInProgress, _VCB::VcbReference, and _VCB::VcbUserReference.

Referenced by UdfCheckForDismount(), UdfCompleteFcbOpen(), UdfDismountVcb(), UdfInitializeGlobalData(), UdfLockVolumeInternal(), and UdfPurgeVolume().

00105 : 00106 00107 This routine is called to process the close queues in the UdfData. If the 00108 Vcb is passed then we want to remove all of the closes for this Vcb. 00109 Otherwise we will do as many of the delayed closes as we need to do. 00110 00111 Arguments: 00112 00113 Vcb - If specified then we are looking for all of the closes for the 00114 given Vcb. 00115 00116 Return Value: 00117 00118 None 00119 00120 --*/ 00121 00122 { 00123 PIRP_CONTEXT IrpContext; 00124 IRP_CONTEXT StackIrpContext; 00125 00126 THREAD_CONTEXT ThreadContext; 00127 00128 PFCB Fcb; 00129 ULONG UserReference; 00130 00131 ULONG VcbHoldCount = 0; 00132 PVCB CurrentVcb = NULL; 00133 00134 BOOLEAN ReleaseUdfData = FALSE; 00135 00136 PAGED_CODE(); 00137 00138 // 00139 // Check input. 00140 // 00141 00142 ASSERT_OPTIONAL_VCB( Vcb ); 00143 00144 FsRtlEnterFileSystem(); 00145 00146 // 00147 // Continue processing until there are no more closes to process. 00148 // 00149 00150 while (IrpContext = UdfRemoveClose( Vcb )) { 00151 00152 // 00153 // If we don't have an IrpContext then use the one on the stack. 00154 // Initialize it for this request. 00155 // 00156 00157 if (SafeNodeType( IrpContext ) != UDFS_NTC_IRP_CONTEXT ) { 00158 00159 // 00160 // Update the local values from the IrpContextLite. 00161 // 00162 00163 Fcb = ((PIRP_CONTEXT_LITE) IrpContext)->Fcb; 00164 UserReference = ((PIRP_CONTEXT_LITE) IrpContext)->UserReference; 00165 00166 // 00167 // Update the stack irp context with the values from the 00168 // IrpContextLite. 00169 // 00170 00171 UdfInitializeStackIrpContext( &StackIrpContext, 00172 (PIRP_CONTEXT_LITE) IrpContext ); 00173 00174 // 00175 // Free the IrpContextLite. 00176 // 00177 00178 UdfFreeIrpContextLite( (PIRP_CONTEXT_LITE) IrpContext ); 00179 00180 // 00181 // Remember we have the IrpContext from the stack. 00182 // 00183 00184 IrpContext = &StackIrpContext; 00185 00186 // 00187 // Otherwise cleanup the existing IrpContext. 00188 // 00189 00190 } else { 00191 00192 // 00193 // Remember the Fcb and user reference count. 00194 // 00195 00196 Fcb = (PFCB) IrpContext->Irp; 00197 IrpContext->Irp = NULL; 00198 00199 UserReference = (ULONG) IrpContext->ExceptionStatus; 00200 IrpContext->ExceptionStatus = STATUS_SUCCESS; 00201 } 00202 00203 // 00204 // We have an IrpContext. Now we need to set the top level thread 00205 // context. 00206 // 00207 00208 SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); 00209 00210 // 00211 // If we were given a Vcb then there is a request on top of this. 00212 // 00213 00214 if (ARGUMENT_PRESENT( Vcb )) { 00215 00216 ClearFlag( IrpContext->Flags, 00217 IRP_CONTEXT_FLAG_TOP_LEVEL | IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS ); 00218 } 00219 00220 UdfSetThreadContext( IrpContext, &ThreadContext ); 00221 00222 // 00223 // If we have hit the maximum number of requests to process without 00224 // releasing the Vcb then release the Vcb now. If we are holding 00225 // a different Vcb to this one then release the previous Vcb. 00226 // 00227 // In either case acquire the current Vcb. 00228 // 00229 // We use the MinDelayedCloseCount from the UdfData since it is 00230 // a convenient value based on the system size. Only thing we are trying 00231 // to do here is prevent this routine starving other threads which 00232 // may need this Vcb exclusively. 00233 // 00234 00235 ReleaseUdfData = !ARGUMENT_PRESENT( Vcb ) && 00236 (Fcb->Vcb->VcbCondition != VcbMounted) && 00237 (Fcb->Vcb->VcbCondition != VcbMountInProgress) && 00238 (Fcb->Vcb->VcbCleanup == 0); 00239 00240 if (ReleaseUdfData || 00241 (VcbHoldCount > UdfData.MinDelayedCloseCount) || 00242 (Fcb->Vcb != CurrentVcb)) { 00243 00244 if (CurrentVcb != NULL) { 00245 00246 UdfReleaseVcb( IrpContext, CurrentVcb ); 00247 } 00248 00249 if (ReleaseUdfData) { 00250 00251 UdfAcquireUdfData( IrpContext ); 00252 } 00253 00254 CurrentVcb = Fcb->Vcb; 00255 UdfAcquireVcbShared( IrpContext, CurrentVcb, FALSE ); 00256 00257 VcbHoldCount = 0; 00258 00259 } else { 00260 00261 VcbHoldCount += 1; 00262 } 00263 00264 DebugTrace(( +1, Dbg, 00265 "UdfFspClose, Fcb %08x %4s Vcb %d/%d Fcb %d/%d\n", 00266 Fcb, 00267 ( UserReference? "USER" : "SYS" ), 00268 CurrentVcb->VcbReference, 00269 CurrentVcb->VcbUserReference, 00270 Fcb->FcbReference, 00271 Fcb->FcbUserReference )); 00272 00273 // 00274 // Call our worker routine to perform the close operation. 00275 // 00276 00277 UdfCommonClosePrivate( IrpContext, CurrentVcb, Fcb, UserReference, FALSE ); 00278 00279 // 00280 // If the reference count on this Vcb is below our residual reference 00281 // then check if we should dismount the volume. 00282 // 00283 00284 if (ReleaseUdfData) { 00285 00286 UdfReleaseVcb( IrpContext, CurrentVcb ); 00287 UdfCheckForDismount( IrpContext, CurrentVcb, FALSE ); 00288 00289 CurrentVcb = NULL; 00290 00291 UdfReleaseUdfData( IrpContext ); 00292 ReleaseUdfData = FALSE; 00293 } 00294 00295 // 00296 // Complete the current request to cleanup the IrpContext. 00297 // 00298 00299 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00300 00301 DebugTrace(( -1, Dbg, "UdfFspClose -> VOID\n" )); 00302 } 00303 00304 // 00305 // Release any Vcb we may still hold. 00306 // 00307 00308 if (CurrentVcb != NULL) { 00309 00310 UdfReleaseVcb( IrpContext, CurrentVcb ); 00311 } 00312 00313 FsRtlExitFileSystem(); 00314 return; 00315 }

VOID UdfFspDispatch IN PIRP_CONTEXT  IrpContext  ) 
 

Definition at line 38 of file fspdisp.c.

References ASSERT, _IO_STACK_LOCATION::DeviceObject, FALSE, _IO_STACK_LOCATION::FileObject, FsRtlEnterFileSystem, FsRtlExitFileSystem, IoGetCurrentIrpStackLocation, _IRP::IoStatus, Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FSP_FLAGS, IRP_MJ_CLEANUP, IRP_MJ_CLOSE, IRP_MJ_CREATE, IRP_MJ_DEVICE_CONTROL, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_LOCK_CONTROL, IRP_MJ_PNP, IRP_MJ_QUERY_INFORMATION, IRP_MJ_QUERY_VOLUME_INFORMATION, IRP_MJ_READ, IRP_MJ_SET_INFORMATION, KeAcquireSpinLock, KeReleaseSpinLock(), NTSTATUS(), NULL, _VOLUME_DEVICE_OBJECT::OverflowQueue, _VOLUME_DEVICE_OBJECT::OverflowQueueCount, _VOLUME_DEVICE_OBJECT::OverflowQueueSpinLock, _VOLUME_DEVICE_OBJECT::PostedRequestCount, SetFlag, Status, ThreadContext, TRUE, UdfCleanupIrpContext(), UdfCommonCleanup(), UdfCommonCreate(), UdfCommonDevControl(), UdfCommonDirControl(), UdfCommonFsControl(), UdfCommonLockControl(), UdfCommonPnp(), UdfCommonQueryInfo(), UdfCommonQueryVolInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfCompleteRequest(), UdfExceptionFilter(), UdfProcessException(), and UdfSetThreadContext().

Referenced by UdfAddToWorkque().

00044 : 00045 00046 This is the main FSP thread routine that is executed to receive 00047 and dispatch IRP requests. Each FSP thread begins its execution here. 00048 There is one thread created at system initialization time and subsequent 00049 threads created as needed. 00050 00051 Arguments: 00052 00053 IrpContext - IrpContext for a request to process. 00054 00055 Return Value: 00056 00057 None 00058 00059 --*/ 00060 00061 { 00062 THREAD_CONTEXT ThreadContext; 00063 NTSTATUS Status; 00064 00065 PIRP Irp = IrpContext->Irp; 00066 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00067 00068 PVOLUME_DEVICE_OBJECT VolDo = NULL; 00069 00070 // 00071 // If this request has an associated volume device object, remember it. 00072 // 00073 00074 if (IrpSp->FileObject != NULL) { 00075 00076 VolDo = CONTAINING_RECORD( IrpSp->DeviceObject, 00077 VOLUME_DEVICE_OBJECT, 00078 DeviceObject ); 00079 } 00080 00081 // 00082 // Now case on the function code. For each major function code, 00083 // either call the appropriate worker routine. This routine that 00084 // we call is responsible for completing the IRP, and not us. 00085 // That way the routine can complete the IRP and then continue 00086 // post processing as required. For example, a read can be 00087 // satisfied right away and then read can be done. 00088 // 00089 // We'll do all of the work within an exception handler that 00090 // will be invoked if ever some underlying operation gets into 00091 // trouble. 00092 // 00093 00094 while (TRUE) { 00095 00096 // 00097 // Set all the flags indicating we are in the Fsp. 00098 // 00099 00100 SetFlag( IrpContext->Flags, IRP_CONTEXT_FSP_FLAGS ); 00101 00102 FsRtlEnterFileSystem(); 00103 00104 UdfSetThreadContext( IrpContext, &ThreadContext ); 00105 00106 while (TRUE) { 00107 00108 try { 00109 00110 // 00111 // Reinitialize for the next try at completing this 00112 // request. 00113 // 00114 00115 Status = 00116 IrpContext->ExceptionStatus = STATUS_SUCCESS; 00117 00118 // 00119 // Initialize the Io status field in the Irp. 00120 // 00121 00122 Irp->IoStatus.Status = STATUS_SUCCESS; 00123 Irp->IoStatus.Information = 0; 00124 00125 // 00126 // Case on the major irp code. 00127 // 00128 00129 switch (IrpContext->MajorFunction) { 00130 00131 case IRP_MJ_CLEANUP : 00132 00133 Status = UdfCommonCleanup( IrpContext, Irp ); 00134 break; 00135 00136 case IRP_MJ_CLOSE : 00137 00138 // 00139 // Closes should never be posted. 00140 // 00141 00142 ASSERT( FALSE ); 00143 break; 00144 00145 case IRP_MJ_CREATE : 00146 00147 Status = UdfCommonCreate( IrpContext, Irp ); 00148 break; 00149 00150 case IRP_MJ_DEVICE_CONTROL : 00151 00152 Status = UdfCommonDevControl( IrpContext, Irp ); 00153 break; 00154 00155 case IRP_MJ_DIRECTORY_CONTROL : 00156 00157 Status = UdfCommonDirControl( IrpContext, Irp ); 00158 break; 00159 00160 case IRP_MJ_FILE_SYSTEM_CONTROL : 00161 00162 Status = UdfCommonFsControl( IrpContext, Irp ); 00163 break; 00164 00165 case IRP_MJ_LOCK_CONTROL : 00166 00167 Status = UdfCommonLockControl( IrpContext, Irp ); 00168 break; 00169 00170 case IRP_MJ_PNP : 00171 00172 ASSERT( FALSE ); 00173 Status = UdfCommonPnp( IrpContext, Irp ); 00174 break; 00175 00176 case IRP_MJ_QUERY_INFORMATION : 00177 00178 Status = UdfCommonQueryInfo( IrpContext, Irp ); 00179 break; 00180 00181 case IRP_MJ_QUERY_VOLUME_INFORMATION : 00182 00183 Status = UdfCommonQueryVolInfo( IrpContext, Irp ); 00184 break; 00185 00186 case IRP_MJ_READ : 00187 00188 Status = UdfCommonRead( IrpContext, Irp ); 00189 break; 00190 00191 case IRP_MJ_SET_INFORMATION : 00192 00193 Status = UdfCommonSetInfo( IrpContext, Irp ); 00194 break; 00195 00196 default : 00197 00198 Status = STATUS_INVALID_DEVICE_REQUEST; 00199 UdfCompleteRequest( IrpContext, Irp, Status ); 00200 } 00201 00202 } except( UdfExceptionFilter( IrpContext, GetExceptionInformation() )) { 00203 00204 Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() ); 00205 } 00206 00207 // 00208 // Break out of the loop if we didn't get CANT_WAIT. 00209 // 00210 00211 if (Status != STATUS_CANT_WAIT) { break; } 00212 00213 // 00214 // We are retrying this request. Cleanup the IrpContext for the retry. 00215 // 00216 00217 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00218 UdfCleanupIrpContext( IrpContext, FALSE ); 00219 } 00220 00221 FsRtlExitFileSystem(); 00222 00223 // 00224 // If there are any entries on this volume's overflow queue, service 00225 // them. 00226 // 00227 00228 if (VolDo != NULL) { 00229 00230 KIRQL SavedIrql; 00231 PVOID Entry = NULL; 00232 00233 // 00234 // We have a volume device object so see if there is any work 00235 // left to do in its overflow queue. 00236 // 00237 00238 KeAcquireSpinLock( &VolDo->OverflowQueueSpinLock, &SavedIrql ); 00239 00240 if (VolDo->OverflowQueueCount > 0) { 00241 00242 // 00243 // There is overflow work to do in this volume so we'll 00244 // decrement the Overflow count, dequeue the IRP, and release 00245 // the Event 00246 // 00247 00248 VolDo->OverflowQueueCount -= 1; 00249 00250 Entry = RemoveHeadList( &VolDo->OverflowQueue ); 00251 } 00252 00253 KeReleaseSpinLock( &VolDo->OverflowQueueSpinLock, SavedIrql ); 00254 00255 // 00256 // There wasn't an entry, break out of the loop and return to 00257 // the Ex Worker thread. 00258 // 00259 00260 if (Entry == NULL) { break; } 00261 00262 // 00263 // Extract the IrpContext , Irp, set wait to TRUE, and loop. 00264 // 00265 00266 IrpContext = CONTAINING_RECORD( Entry, 00267 IRP_CONTEXT, 00268 WorkQueueItem.List ); 00269 00270 Irp = IrpContext->Irp; 00271 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00272 00273 continue; 00274 } 00275 00276 break; 00277 } 00278 00279 // 00280 // Decrement the PostedRequestCount if there was a volume device object. 00281 // 00282 00283 if (VolDo) { 00284 00285 InterlockedDecrement( &VolDo->PostedRequestCount ); 00286 } 00287 00288 return; 00289 }

FSRTL_COMPARISON_RESULT UdfFullCompareNames IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  NameA,
IN PUNICODE_STRING  NameB
 

Definition at line 1274 of file namesup.c.

References ASSERT_IRP_CONTEXT, EqualTo, FSRTL_COMPARISON_RESULT, GreaterThan, LessThan, and PAGED_CODE.

Referenced by UdfFindDirEntry(), UdfFindNameLink(), UdfInitializeEnumeration(), and UdfInsertNameLink().

01282 : 01283 01284 This function compares two names as fast as possible. Note that since 01285 this comparison is case sensitive we can do a direct memory comparison. 01286 01287 Arguments: 01288 01289 NameA & NameB - The names to compare. 01290 01291 Return Value: 01292 01293 COMPARISON - returns 01294 01295 LessThan if NameA < NameB lexicalgraphically, 01296 GreaterThan if NameA > NameB lexicalgraphically, 01297 EqualTo if NameA is equal to NameB 01298 01299 --*/ 01300 01301 { 01302 ULONG i; 01303 ULONG MinLength = NameA->Length; 01304 FSRTL_COMPARISON_RESULT Result = LessThan; 01305 01306 PAGED_CODE(); 01307 01308 // 01309 // Check inputs. 01310 // 01311 01312 ASSERT_IRP_CONTEXT( IrpContext ); 01313 01314 // 01315 // Figure out the minimum of the two lengths 01316 // 01317 01318 if (NameA->Length > NameB->Length) { 01319 01320 MinLength = NameB->Length; 01321 Result = GreaterThan; 01322 01323 } else if (NameA->Length == NameB->Length) { 01324 01325 Result = EqualTo; 01326 } 01327 01328 // 01329 // Loop through looking at all of the characters in both strings 01330 // testing for equalilty, less than, and greater than 01331 // 01332 01333 i = (ULONG) RtlCompareMemory( NameA->Buffer, NameB->Buffer, MinLength ); 01334 01335 if (i < MinLength) { 01336 01337 // 01338 // We know the offset of the first character which is different. 01339 // 01340 01341 return ((NameA->Buffer[ i / 2 ] < NameB->Buffer[ i / 2 ]) ? 01342 LessThan : 01343 GreaterThan); 01344 } 01345 01346 // 01347 // The names match up to the length of the shorter string. 01348 // The shorter string lexically appears first. 01349 // 01350 01351 return Result; 01352 }

VOID UdfGenerate8dot3Name IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  FileName,
OUT PUNICODE_STRING  ShortFileName
 

Definition at line 389 of file namesup.c.

References ASSERT, CRC_MARK, DOS_CRC_LEN, DOS_EXT_LEN, DOS_NAME_LEN, FALSE, FileName, ILLEGAL_CHAR_MARK, INT16, IsDeviceName, IsFileNameCharLegal, NativeDosCharLength(), PERIOD, SPACE, TRUE, UdfComputeCrc16Uni(), UdfCrcChar, UdfUpcaseName(), UINT16, UNICODE_CHAR, UnicodeToUpper, and USHORT.

Referenced by UdfEnumerateIndex(), UdfFindDirEntry(), UdfQueryAlternateNameInfo(), and UdfQueryDirectory().

00397 : 00398 00399 This routine is called to generate a short name from the given long name. We will 00400 generate a short name from the given long name. 00401 00402 The short form is to convert all runs of illegal characters to "_" and tack 00403 on a base41 representation of the CRC of the original name. The algorithm is 00404 nearly directly lifted from the UDF (2.01 proposed!) standard, so apologies for the 00405 style clash. 00406 00407 Arguments: 00408 00409 FileName - String of bytes containing the name. 00410 00411 ShortFileName - Pointer to the string to store the short name into. 00412 00413 Return Value: 00414 00415 None. 00416 00417 --*/ 00418 00419 { 00420 INT16 index; 00421 INT16 targetIndex; 00422 INT16 crcIndex; 00423 INT16 extLen; 00424 INT16 nameLen; 00425 INT16 charLen; 00426 INT16 overlayBytes; 00427 INT16 bytesLeft; 00428 UNICODE_CHAR current; 00429 BOOLEAN needsCRC; 00430 UNICODE_CHAR ext[DOS_EXT_LEN]; 00431 00432 // 00433 // So as to lift as directly as possible from the standard, chunk things around. 00434 // 00435 00436 PWCHAR dosName = ShortFileName->Buffer; 00437 PWCHAR udfName = FileName->Buffer; 00438 LONG udfNameLen = FileName->Length / sizeof(WCHAR); 00439 00440 needsCRC = FALSE; 00441 00442 /* Start at the end of the UDF file name and scan for a period */ 00443 /* ('.'). This will be where the DOS extension starts (if */ 00444 /* any). */ 00445 index = udfNameLen; 00446 while (index-- > 0) { 00447 if (udfName[index] == PERIOD) 00448 break; 00449 } 00450 00451 if (index < 0) { 00452 /* There name was scanned to the beginning of the buffer */ 00453 /* and no extension was found. */ 00454 extLen = 0; 00455 nameLen = udfNameLen; 00456 } 00457 else { 00458 /* A DOS extension was found, process it first. */ 00459 extLen = udfNameLen - index - 1; 00460 nameLen = index; 00461 targetIndex = 0; 00462 bytesLeft = DOS_EXT_LEN; 00463 00464 while (++index < udfNameLen && bytesLeft > 0) { 00465 /* Get the current character and convert it to upper */ 00466 /* case. */ 00467 current = UnicodeToUpper(udfName[index]); 00468 if (current == SPACE) { 00469 /* If a space is found, a CRC must be appended to */ 00470 /* the mangled file name. */ 00471 needsCRC = TRUE; 00472 } 00473 else { 00474 /* Determine if this is a valid file name char and */ 00475 /* calculate its corresponding BCS character byte */ 00476 /* length (zero if the char is not legal or */ 00477 /* undisplayable on this system). */ 00478 charLen = (IsFileNameCharLegal(current)) ? 00479 NativeDosCharLength(current) : 0; 00480 00481 /* If the char is larger than the available space */ 00482 /* in the buffer, pretend it is undisplayable. */ 00483 if (charLen > bytesLeft) 00484 charLen = 0; 00485 00486 if (charLen == 0) { 00487 /* Undisplayable or illegal characters are */ 00488 /* substituted with an underscore ("_"), and */ 00489 /* required a CRC code appended to the mangled */ 00490 /* file name. */ 00491 needsCRC = TRUE; 00492 charLen = 1; 00493 current = ILLEGAL_CHAR_MARK; 00494 00495 /* Skip over any following undiplayable or */ 00496 /* illegal chars. */ 00497 while (index + 1 < udfNameLen && 00498 (!IsFileNameCharLegal(udfName[index + 1]) || 00499 NativeDosCharLength(udfName[index + 1]) == 0)) 00500 index++; 00501 } 00502 00503 /* Assign the resulting char to the next index in */ 00504 /* the extension buffer and determine how many BCS */ 00505 /* bytes are left. */ 00506 ext[targetIndex++] = current; 00507 bytesLeft -= charLen; 00508 } 00509 } 00510 00511 /* Save the number of Unicode characters in the extension */ 00512 extLen = targetIndex; 00513 00514 /* If the extension was too large, or it was zero length */ 00515 /* (i.e. the name ended in a period), a CRC code must be */ 00516 /* appended to the mangled name. */ 00517 if (index < udfNameLen || extLen == 0) 00518 needsCRC = TRUE; 00519 } 00520 00521 /* Now process the actual file name. */ 00522 index = 0; 00523 targetIndex = 0; 00524 crcIndex = 0; 00525 overlayBytes = -1; 00526 bytesLeft = DOS_NAME_LEN; 00527 while (index < nameLen && bytesLeft > 0) { 00528 /* Get the current character and convert it to upper case. */ 00529 current = UnicodeToUpper(udfName[index]); 00530 if (current == SPACE || current == PERIOD) { 00531 /* Spaces and periods are just skipped, a CRC code */ 00532 /* must be added to the mangled file name. */ 00533 needsCRC = TRUE; 00534 } 00535 else { 00536 /* Determine if this is a valid file name char and */ 00537 /* calculate its corresponding BCS character byte */ 00538 /* length (zero if the char is not legal or */ 00539 /* undisplayable on this system). */ 00540 charLen = (IsFileNameCharLegal(current)) ? 00541 NativeDosCharLength(current) : 0; 00542 00543 /* If the char is larger than the available space in */ 00544 /* the buffer, pretend it is undisplayable. */ 00545 if (charLen > bytesLeft) 00546 charLen = 0; 00547 00548 if (charLen == 0) { 00549 /* Undisplayable or illegal characters are */ 00550 /* substituted with an underscore ("_"), and */ 00551 /* required a CRC code appended to the mangled */ 00552 /* file name. */ 00553 needsCRC = TRUE; 00554 charLen = 1; 00555 current = ILLEGAL_CHAR_MARK; 00556 00557 /* Skip over any following undiplayable or illegal */ 00558 /* chars. */ 00559 while (index + 1 < nameLen && 00560 (!IsFileNameCharLegal(udfName[index + 1]) || 00561 NativeDosCharLength(udfName[index + 1]) == 0)) 00562 index++; 00563 00564 /* Terminate loop if at the end of the file name. */ 00565 if (index >= nameLen) 00566 break; 00567 } 00568 00569 /* Assign the resulting char to the next index in the */ 00570 /* file name buffer and determine how many BCS bytes */ 00571 /* are left. */ 00572 dosName[targetIndex++] = current; 00573 bytesLeft -= charLen; 00574 00575 /* This figures out where the CRC code needs to start */ 00576 /* in the file name buffer. */ 00577 if (bytesLeft >= DOS_CRC_LEN) { 00578 /* If there is enough space left, just tack it */ 00579 /* onto the end. */ 00580 crcIndex = targetIndex; 00581 } 00582 else { 00583 /* If there is not enough space left, the CRC */ 00584 /* must overlay a character already in the file */ 00585 /* name buffer. Once this condition has been */ 00586 /* met, the value will not change. */ 00587 if (overlayBytes < 0) { 00588 /* Determine the index and save the length of */ 00589 /* the BCS character that is overlayed. It */ 00590 /* is possible that the CRC might overlay */ 00591 /* half of a two-byte BCS character depending */ 00592 /* upon how the character boundaries line up. */ 00593 overlayBytes = (bytesLeft + charLen > DOS_CRC_LEN) 00594 ? 1 : 0; 00595 crcIndex = targetIndex - 1; 00596 } 00597 } 00598 } 00599 00600 /* Advance to the next character. */ 00601 index++; 00602 } 00603 00604 /* If the scan did not reach the end of the file name, or the */ 00605 /* length of the file name is zero, a CRC code is needed. */ 00606 if (index < nameLen || index == 0) 00607 needsCRC = TRUE; 00608 00609 /* If the name has illegal characters or and extension, it */ 00610 /* is not a DOS device name. */ 00611 if (needsCRC == FALSE && extLen == 0) { 00612 /* If this is the name of a DOS device, a CRC code should */ 00613 /* be appended to the file name. */ 00614 if (IsDeviceName(udfName, udfNameLen)) 00615 needsCRC = TRUE; 00616 } 00617 00618 /* Append the CRC code to the file name, if needed. */ 00619 if (needsCRC) { 00620 /* Get the CRC value for the original Unicode string */ 00621 UINT16 udfCRCValue; 00622 UINT16 modulus; 00623 00624 // 00625 // In UDF 2.00, the sample code changed to take the CRC 00626 // from the UNICODE expansion of the CS0 as opposed to 00627 // the CS0 itself. In UDF 2.01, the wording of the spec 00628 // will actually match this. 00629 // 00630 // Additionally, the checksum changes to be byte-order 00631 // independent. 00632 // 00633 00634 udfCRCValue = UdfComputeCrc16Uni(udfName, udfNameLen); 00635 00636 /* Determine the character index where the CRC should */ 00637 /* begin. */ 00638 targetIndex = crcIndex; 00639 00640 /* If the character being overlayed is a two-byte BCS */ 00641 /* character, replace the first byte with an underscore. */ 00642 if (overlayBytes > 0) 00643 dosName[targetIndex++] = ILLEGAL_CHAR_MARK; 00644 00645 // 00646 // UDF 2.01 changes to a base 41 encoding. UDF 1.50 and 00647 // UDF 2.00 exchanged the # delimeter with the high 4bits 00648 // of the CRC. 00649 // 00650 00651 dosName[targetIndex++] = CRC_MARK; 00652 00653 dosName[targetIndex++] = 00654 UdfCrcChar[udfCRCValue / (41 * 41)]; 00655 udfCRCValue %= (41 * 41); 00656 00657 dosName[targetIndex++] = 00658 UdfCrcChar[udfCRCValue / 41]; 00659 udfCRCValue %= 41; 00660 00661 dosName[targetIndex++] = 00662 UdfCrcChar[udfCRCValue]; 00663 } 00664 00665 /* Append the extension, if any. */ 00666 if (extLen > 0) { 00667 /* Tack on a period and each successive byte in the */ 00668 /* extension buffer. */ 00669 dosName[targetIndex++] = PERIOD; 00670 for (index = 0; index < extLen; index++) 00671 dosName[targetIndex++] = ext[index]; 00672 } 00673 00674 ASSERT( (targetIndex * sizeof(WCHAR)) <= ShortFileName->MaximumLength ); 00675 00676 ShortFileName->Length = (USHORT) (targetIndex * sizeof(WCHAR)); 00677 00678 // 00679 // Now we upcase the whole name at once. 00680 // 00681 00682 UdfUpcaseName( IrpContext, 00683 ShortFileName, 00684 ShortFileName ); 00685 }

PFCB UdfGetNextFcb IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PVOID *  RestartKey
 

Definition at line 1997 of file udfs/strucsup.c.

References NULL, PAGED_CODE, PFCB_TABLE_ELEMENT, and RtlEnumerateGenericTableWithoutSplaying().

Referenced by UdfPurgeVolume().

02005 : 02006 02007 This routine will enumerate through all of the Fcb's in the Fcb table. 02008 02009 Arguments: 02010 02011 Vcb - Vcb for this volume. 02012 02013 RestartKey - This value is used by the table package to maintain 02014 its position in the enumeration. It is initialized to NULL 02015 for the first search. 02016 02017 Return Value: 02018 02019 PFCB - A pointer to the next fcb or NULL if the enumeration is 02020 completed 02021 02022 --*/ 02023 02024 { 02025 PFCB Fcb; 02026 02027 PAGED_CODE(); 02028 02029 Fcb = (PFCB) RtlEnumerateGenericTableWithoutSplaying( &Vcb->FcbTable, RestartKey ); 02030 02031 if (Fcb != NULL) { 02032 02033 Fcb = ((PFCB_TABLE_ELEMENT)(Fcb))->Fcb; 02034 } 02035 02036 return Fcb; 02037 }

ULONG UdfHighBit ULONG  Word  ) 
 

Definition at line 1239 of file udfdata.c.

References Offset.

Referenced by UdfInitializeVcb(), and UdfMountVolume().

01245 : 01246 01247 This routine discovers the highest set bit of the input word. It is 01248 equivalent to the integer logarithim base 2. 01249 01250 Arguments: 01251 01252 Word - word to check 01253 01254 Return Value: 01255 01256 Bit offset of highest set bit. If no bit is set, return is zero. 01257 01258 --*/ 01259 01260 { 01261 ULONG Offset = 31; 01262 ULONG Mask = (ULONG)(1 << 31); 01263 01264 if (Word == 0) { 01265 01266 return 0; 01267 } 01268 01269 while ((Word & Mask) == 0) { 01270 01271 Offset--; 01272 Mask >>= 1; 01273 } 01274 01275 return Offset; 01276 }

INLINE BOOLEAN UdfIllegalFcbAccess IN PIRP_CONTEXT  IrpContext,
IN TYPE_OF_OPEN  TypeOfOpen,
IN ACCESS_MASK  DesiredAccess
 

Definition at line 675 of file udfprocs.h.

References BooleanFlagOn, and UserVolumeOpen.

Referenced by UdfOpenExistingFcb(), UdfOpenObjectByFileId(), and UdfOpenObjectFromDirContext().

00683 : 00684 00685 This routine simply asserts that the access is legal for a readonly filesystem. 00686 00687 Arguments: 00688 00689 TypeOfOpen - type of open for the Fcb in question. 00690 00691 DesiredAccess - mask of access the caller is trying for. 00692 00693 Return Value: 00694 00695 BOOLEAN True if illegal access, false otherwise. 00696 00697 --*/ 00698 00699 { 00700 return BooleanFlagOn( DesiredAccess, 00701 (TypeOfOpen != UserVolumeOpen ? 00702 (FILE_WRITE_ATTRIBUTES | 00703 FILE_WRITE_DATA | 00704 FILE_WRITE_EA | 00705 FILE_ADD_FILE | 00706 FILE_ADD_SUBDIRECTORY | 00707 FILE_APPEND_DATA) : 0) | 00708 FILE_DELETE_CHILD | 00709 DELETE | 00710 WRITE_DAC ); 00711 }

VOID UdfInitializeAllocations IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PICB_SEARCH_CONTEXT  IcbContext
 

Definition at line 3388 of file udfs/strucsup.c.

References _ALLOC_ENUM_CONTEXT::Alloc, ALLOC_ENUM_CONTEXT, ICBFILE::AllocLength, _ALLOC_ENUM_CONTEXT::AllocType, ASSERT, ASSERT_FCB, ASSERT_IRP_CONTEXT, BlockOffset, BlockSize, Dbg, DebugTrace, ICBFILE::Destag, ICBFILE::EALength, FALSE, FCB_STATE_EMBEDDED_DATA, FsRtlAddLargeMcbEntry(), ICBTAG_F_ALLOC_IMMEDIATE, DESTAG::Lbn, NSRLENGTH::Length, SHORTAD::Length, LlSectorsFromBytes, NSRLENGTH_TYPE_RECORDED, NSRLENGTH_TYPE_UNRECORDED, PAD_GENERIC, PAGED_CODE, SectorAlign, SectorsFromBytes, SetFlag, SHORTAD::Start, TRUE, NSRLENGTH::Type, UdfGetNextAllocation(), UdfGetPartitionOfCurrentAllocation(), UdfInitializeAllocationContext(), UdfInitializeFcbMcb(), UdfLookupMetaVsnOfExtent(), UdfLookupPsnOfExtent(), UdfRaiseStatus(), UdfUninitializeFcbMcb(), and USHORT.

Referenced by UdfInitializeFcbFromIcbContext(), and UdfUpdateVcbPhase0().

03396 : 03397 03398 This routine fills in the data retrieval information for an Fcb. 03399 03400 Arguments: 03401 03402 Fcb - Fcb to add retrieval information to. 03403 03404 IcbContext - Elaborated ICB search context corresponding to this Fcb. 03405 03406 Return Value: 03407 03408 None. 03409 03410 --*/ 03411 03412 { 03413 PICBFILE Icb = IcbContext->Active.View; 03414 PAD_GENERIC GenericAd; 03415 03416 ALLOC_ENUM_CONTEXT AllocContext; 03417 03418 LONGLONG RunningOffset; 03419 ULONG Psn; 03420 USHORT Partition; 03421 03422 PVCB Vcb = Fcb->Vcb; 03423 03424 BOOLEAN Result; 03425 BOOLEAN InFileTail = FALSE; 03426 03427 PAGED_CODE(); 03428 03429 // 03430 // Check inputs 03431 // 03432 03433 ASSERT_IRP_CONTEXT( IrpContext ); 03434 ASSERT_FCB( Fcb ); 03435 03436 // 03437 // Immediately return for objects with zero information space. Note that 03438 // passing this test does not indicate that the file has any recorded space. 03439 // 03440 03441 if (Fcb->FileSize.QuadPart == 0) { 03442 03443 return; 03444 } 03445 03446 UdfInitializeAllocationContext( IrpContext, 03447 &AllocContext, 03448 IcbContext ); 03449 03450 // 03451 // Handle the case of embedded data. 03452 // 03453 03454 if (AllocContext.AllocType == ICBTAG_F_ALLOC_IMMEDIATE) { 03455 03456 // 03457 // Teardown any existing mcb. 03458 // 03459 03460 UdfUninitializeFcbMcb( Fcb ); 03461 03462 // 03463 // Establish a single block mapping to the Icb itself and mark the Fcb as 03464 // having embedded data. Mapping will occur through the Metadata stream. 03465 // Note that by virtue of having an Icb here we know it has already had 03466 // a mapping established in the Metadata stream, so just retrieve that. 03467 // 03468 03469 SetFlag( Fcb->FcbState, FCB_STATE_EMBEDDED_DATA ); 03470 03471 Fcb->EmbeddedVsn = UdfLookupMetaVsnOfExtent( IrpContext, 03472 Vcb, 03473 IcbContext->Active.Partition, 03474 Icb->Destag.Lbn, 03475 BlockSize( Vcb ), 03476 FALSE ); 03477 03478 // 03479 // Note the offset of the data in the Icb. 03480 // 03481 03482 Fcb->EmbeddedOffset = FIELD_OFFSET( ICBFILE, EAs ) + Icb->EALength; 03483 03484 // 03485 // Check that the information length agrees. 03486 // 03487 03488 if (Icb->AllocLength != Fcb->FileSize.LowPart) { 03489 03490 DebugTrace(( 0, Dbg, "UdfInitializeAllocations, embedded alloc %08x != filesize %08x\n", 03491 Icb->AllocLength, 03492 Fcb->FileSize.LowPart )); 03493 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 03494 } 03495 03496 return; 03497 } 03498 03499 // 03500 // Now initialize the mapping structure for this Fcb. 03501 // 03502 03503 UdfInitializeFcbMcb( Fcb ); 03504 03505 // 03506 // Now walk the chain of allocation descriptors for the object, adding them into the 03507 // mapping. 03508 // 03509 03510 RunningOffset = 0; 03511 03512 do { 03513 03514 // 03515 // Do file tail consistency checking (4/12.1). We will have a file body 03516 // which is exactly the size of the information length, and a run of allocated 03517 // but unrecorded space following. 03518 // 03519 03520 if (Fcb->FileSize.QuadPart == RunningOffset) { 03521 03522 InFileTail = TRUE; 03523 } 03524 03525 // 03526 // It is impermissible for an interior body extent of an object to not be 03527 // an integral multiple of a logical block in size (note that the last 03528 // will tend to be). Also check that the body didn't overshoot the information 03529 // length and that the tail descriptor type is correct. 03530 // 03531 03532 GenericAd = AllocContext.Alloc; 03533 03534 if ((!InFileTail && (BlockOffset( Vcb, RunningOffset ) || 03535 Fcb->FileSize.QuadPart < RunningOffset)) || 03536 (InFileTail && GenericAd->Length.Type != NSRLENGTH_TYPE_UNRECORDED)) { 03537 03538 DebugTrace(( 0, Dbg, "UdfInitializeAllocations, InFileTail == %u, bad alloc\n", 03539 InFileTail )); 03540 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 03541 } 03542 03543 // 03544 // In the file tail we'll just slum along an be a nitpick. Technically, as a 03545 // readonly implementation I don't have to care at all about what is here. 03546 // 03547 03548 if (InFileTail) { 03549 03550 continue; 03551 } 03552 03553 // 03554 // Based on the descriptor type, pull it apart and add the mapping. 03555 // 03556 03557 if (GenericAd->Length.Type == NSRLENGTH_TYPE_RECORDED) { 03558 03559 // 03560 // Grab the Psn this extent starts at and add the allocation. 03561 // 03562 03563 Psn = UdfLookupPsnOfExtent( IrpContext, 03564 Vcb, 03565 UdfGetPartitionOfCurrentAllocation( &AllocContext ), 03566 GenericAd->Start, 03567 GenericAd->Length.Length ); 03568 03569 Result = FsRtlAddLargeMcbEntry( &Fcb->Mcb, 03570 LlSectorsFromBytes( Vcb, RunningOffset ), 03571 Psn, 03572 SectorsFromBytes( Vcb, SectorAlign( Vcb, GenericAd->Length.Length ) )); 03573 03574 ASSERT( Result ); 03575 } 03576 03577 RunningOffset += GenericAd->Length.Length; 03578 03579 } while ( UdfGetNextAllocation( IrpContext, &AllocContext )); 03580 03581 // 03582 // We must have had body allocation descriptors for the entire file 03583 // information length. 03584 // 03585 03586 if (Fcb->FileSize.QuadPart != RunningOffset) { 03587 03588 DebugTrace(( 0, Dbg, "UdfInitializeAllocations, total descriptors != filesize\n" )); 03589 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 03590 } 03591 }

VOID UdfInitializeCrc16 ULONG  Polynomial  ) 
 

Definition at line 1083 of file udfdata.c.

References FsRtlAllocatePoolWithTag, n, PUSHORT, TAG_CRC_TABLE, UdfCrcTable, UdfPagedPool, and USHORT.

Referenced by UdfInitializeGlobalData().

01089 : 01090 01091 This routine generates the 16bit CRC Table to be used in CRC calculation. 01092 01093 Arguments: 01094 01095 Polynomial - Starting seed for the generation 01096 01097 Return Value: 01098 01099 None 01100 01101 --*/ 01102 01103 { 01104 ULONG n, i, Crc; 01105 01106 // 01107 // All CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories 01108 // and Ned W. Rhodes of Software Systems Group. It has been published in 01109 // "Design and Validation of Computer Protocols", Prentice Hall, Englewood 01110 // Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4. 01111 // 01112 // Copyright is held by AT&T. 01113 // 01114 // AT&T gives permission for the free use of the source code. 01115 // 01116 01117 UdfCrcTable = (PUSHORT) FsRtlAllocatePoolWithTag( UdfPagedPool, 01118 256 * sizeof(USHORT), 01119 TAG_CRC_TABLE ); 01120 01121 for (n = 0; n < 256; n++) { 01122 01123 Crc = n << 8; 01124 01125 for (i = 0; i < 8; i++) { 01126 01127 if(Crc & 0x8000) { 01128 01129 Crc = (Crc << 1) ^ Polynomial; 01130 01131 } else { 01132 01133 Crc <<= 1; 01134 } 01135 01136 Crc &= 0xffff; 01137 } 01138 01139 UdfCrcTable[n] = (USHORT) Crc; 01140 } 01141 }

VOID UdfInitializeDirContext IN PIRP_CONTEXT  IrpContext,
IN PDIR_ENUM_CONTEXT  DirContext
 

Definition at line 60 of file dirsup.c.

References ASSERT_IRP_CONTEXT.

Referenced by UdfCommonCreate(), UdfInitializeCompoundDirContext(), UdfInitializeEnumeration(), and UdfQueryAlternateNameInfo().

00067 : 00068 00069 This routine initializes a directory enumeartion context. 00070 00071 Call this exactly once in the lifetime of a context. 00072 00073 Arguments: 00074 00075 DirContext - a context to initialize 00076 00077 Return Value: 00078 00079 None. 00080 00081 --*/ 00082 00083 { 00084 // 00085 // Check inputs. 00086 // 00087 00088 ASSERT_IRP_CONTEXT( IrpContext ); 00089 00090 // 00091 // Provide defaults for fields, nothing too special. 00092 // 00093 00094 RtlZeroMemory( DirContext, sizeof(DIR_ENUM_CONTEXT) ); 00095 }

VOID UdfInitializeFcbFromIcbContext IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PICB_SEARCH_CONTEXT  IcbContext
 

Definition at line 2297 of file udfs/strucsup.c.

References ICBFILE::AllocLength, ASSERT, ASSERT_FCB, ASSERT_IRP_CONTEXT, BlockSize, ICBFILE::Destag, DESTAG_ID_NSR_FILE, EA_SEARCH_CONTEXT, ICBFILE::EALength, FCB_STATE_IN_FCB_TABLE, FCB_STATE_INITIALIZED, ICBTAG::FileType, ICBFILE::Icbtag, ICBTAG_FILE_T_DIRECTORY, ICBTAG_FILE_T_FILE, DESTAG::Ident, ICBFILE::InfoLength, ICBFILE::LinkCount, LlBlockAlign, LongOffset, PAGED_CODE, SetFlag, UdfInitializeAllocations(), UdfInsertFcbTable, UdfLockFcb, UdfRaiseStatus(), UDFS_NTC_FCB_DATA, UDFS_NTC_FCB_INDEX, UdfUnlockFcb, and UdfUpdateTimestampsFromIcbContext().

Referenced by UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), and UdfUpdateVcbPhase1().

02305 : 02306 02307 This routine is called to initialize an Fcb from a direct ICB. It should 02308 only be called once in the lifetime of an Fcb and will fill in the Mcb 02309 from the chained allocation descriptors of the ICB. 02310 02311 Arguments: 02312 02313 Fcb - The Fcb being initialized 02314 02315 IcbOontext - An search context containing the active direct ICB for the object 02316 02317 Return Value: 02318 02319 None. 02320 02321 --*/ 02322 02323 { 02324 EA_SEARCH_CONTEXT EaContext; 02325 PICBFILE Icb; 02326 02327 PVCB Vcb; 02328 02329 PAGED_CODE(); 02330 02331 // 02332 // Check inputs 02333 // 02334 02335 ASSERT_IRP_CONTEXT( IrpContext ); 02336 ASSERT_FCB( Fcb ); 02337 02338 // 02339 // Directly reference for convenience 02340 // 02341 02342 Icb = IcbContext->Active.View; 02343 Vcb = Fcb->Vcb; 02344 02345 ASSERT( IcbContext->IcbType == DESTAG_ID_NSR_FILE && Icb->Destag.Ident == DESTAG_ID_NSR_FILE ); 02346 02347 // 02348 // Check that the full indicated size of the direct entry is sane and 02349 // that the length of the EA segment is correctly aligned. A direct 02350 // entry is less than a single logical block in size. 02351 // 02352 02353 if (LongOffset( Icb->EALength ) || 02354 FIELD_OFFSET( ICBFILE, EAs ) + Icb->EALength + Icb->AllocLength > BlockSize( IcbContext->Vcb )) { 02355 02356 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 02357 } 02358 02359 UdfLockFcb( IrpContext, Fcb ); 02360 02361 // 02362 // Try-finally for cleanup. 02363 // 02364 02365 try { 02366 02367 // 02368 // Verify that the types mesh and set state flags. 02369 // 02370 02371 if (Fcb->NodeTypeCode == UDFS_NTC_FCB_INDEX && Icb->Icbtag.FileType == ICBTAG_FILE_T_DIRECTORY) { 02372 02373 SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_DIRECTORY ); 02374 02375 } else if (!(Fcb->NodeTypeCode == UDFS_NTC_FCB_DATA && Icb->Icbtag.FileType == ICBTAG_FILE_T_FILE)) { 02376 02377 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 02378 } 02379 02380 SetFlag( Fcb->FileAttributes, FILE_ATTRIBUTE_READONLY ); 02381 02382 // 02383 // Initialize the common header in the Fcb. 02384 // 02385 02386 Fcb->Resource = &Fcb->Vcb->FileResource; 02387 02388 // 02389 // Size and lookup all allocations for this object. 02390 // 02391 02392 Fcb->AllocationSize.QuadPart = LlBlockAlign( Vcb, Icb->InfoLength ); 02393 02394 Fcb->FileSize.QuadPart = 02395 Fcb->ValidDataLength.QuadPart = Icb->InfoLength; 02396 02397 UdfInitializeAllocations( IrpContext, 02398 Fcb, 02399 IcbContext ); 02400 02401 // 02402 // Lift all of the timestamps for this guy. 02403 // 02404 02405 UdfUpdateTimestampsFromIcbContext( IrpContext, 02406 IcbContext, 02407 &Fcb->Timestamps ); 02408 02409 // 02410 // Pick up the link count. 02411 // 02412 02413 Fcb->LinkCount = Icb->LinkCount; 02414 02415 // 02416 // Link into the Fcb table. Someone else is responsible for the name linkage, which is 02417 // all that remains. We also note that the Fcb is fully initialized at this point. 02418 // 02419 02420 UdfInsertFcbTable( IrpContext, Fcb ); 02421 SetFlag( Fcb->FcbState, FCB_STATE_IN_FCB_TABLE | FCB_STATE_INITIALIZED ); 02422 02423 } finally { 02424 02425 UdfUnlockFcb( IrpContext, Fcb ); 02426 } 02427 02428 return; 02429 }

VOID UdfInitializeIcbContext IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext,
IN PVCB  Vcb,
IN USHORT  IcbType,
IN USHORT  Partition,
IN ULONG  Lbn,
IN ULONG  Length
 

Definition at line 3060 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT, PAGED_CODE, and UdfMapMetadataView().

Referenced by UdfLookupFileEntryInEnumeration().

03072 : 03073 03074 This routine is called to initialize a context to search an Icb hierarchy. 03075 03076 Arguments: 03077 03078 Vcb - Vcb for the volume. 03079 03080 IcbType - Type of direct entry we expect to find (DESTAG_ID...) 03081 03082 Partition - partition of the hierarchy. 03083 03084 Lbn - lbn of the hierarchy. 03085 03086 Length - length of the root extent of the hierarchy. 03087 03088 Return Value: 03089 03090 None. 03091 03092 --*/ 03093 03094 { 03095 PAGED_CODE(); 03096 03097 // 03098 // Check input parameters. 03099 // 03100 03101 ASSERT_IRP_CONTEXT( IrpContext ); 03102 03103 RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 03104 03105 IcbContext->Vcb = Vcb; 03106 IcbContext->IcbType = IcbType; 03107 03108 // 03109 // Map the first extent into the current slot. 03110 // 03111 03112 UdfMapMetadataView( IrpContext, 03113 &IcbContext->Current, 03114 Vcb, 03115 Partition, 03116 Lbn, 03117 Length ); 03118 return; 03119 03120 }

VOID UdfInitializeIcbContextFromFcb IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext,
IN PFCB  Fcb
 

Definition at line 2951 of file udfs/strucsup.c.

References ASSERT_FCB, ASSERT_IRP_CONTEXT, BlockSize, ICBFILE::Destag, DESTAG_ID_NSR_FILE, DESTAG_ID_NSR_ICBIND, DESTAG_ID_NSR_ICBTRM, DESTAG_ID_NSR_PINTEG, DESTAG_ID_NSR_UASE, FALSE, ICBFILE::Icbtag, DESTAG::Ident, ICBTAG::MaxEntries, PAGED_CODE, UdfGetFidLbn, UdfGetFidPartition, UdfMapMetadataView(), UdfRaiseStatus(), and UdfVerifyDescriptor().

Referenced by UdfLookupFileEntryInEnumeration(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), and UdfUpdateVcbPhase1().

02959 : 02960 02961 This routine is called to initialize a context to search the Icb hierarchy 02962 associated with an Fcb. 02963 02964 Arguments: 02965 02966 Fcb - Fcb associated with the hierarchy to search. 02967 02968 Return Value: 02969 02970 None. 02971 02972 --*/ 02973 02974 { 02975 PAGED_CODE(); 02976 02977 // 02978 // Check input parameters. 02979 // 02980 02981 ASSERT_IRP_CONTEXT( IrpContext ); 02982 ASSERT_FCB( Fcb ); 02983 02984 RtlZeroMemory( IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 02985 02986 IcbContext->Vcb = Fcb->Vcb; 02987 IcbContext->IcbType = DESTAG_ID_NSR_FILE; 02988 02989 // 02990 // It is possible that we don't have an idea what the length of the root extent is. 02991 // This will commonly happen in the OpenById case. 02992 // 02993 02994 if (Fcb->RootExtentLength == 0) { 02995 02996 PICBFILE Icb; 02997 02998 // 02999 // We have to lift the first entry from this (possibly bogus!) extent 03000 // and find out how many entries can be recorded, then unmap/remap the view 03001 // to try to get the extent. 03002 // 03003 03004 UdfMapMetadataView( IrpContext, 03005 &IcbContext->Current, 03006 IcbContext->Vcb, 03007 UdfGetFidPartition( Fcb->FileId ), 03008 UdfGetFidLbn( Fcb->FileId ), 03009 BlockSize( IcbContext->Vcb )); 03010 03011 Icb = IcbContext->Current.View; 03012 03013 // 03014 // We can only accomplish the guess if we have a descriptor which contains an ICB 03015 // Tag, which contains a field that can tell us what we need to know. 03016 // 03017 03018 if (Icb->Destag.Ident == DESTAG_ID_NSR_ICBIND || 03019 Icb->Destag.Ident == DESTAG_ID_NSR_ICBTRM || 03020 Icb->Destag.Ident == DESTAG_ID_NSR_FILE || 03021 Icb->Destag.Ident == DESTAG_ID_NSR_UASE || 03022 Icb->Destag.Ident == DESTAG_ID_NSR_PINTEG) { 03023 03024 UdfVerifyDescriptor( IrpContext, 03025 &Icb->Destag, 03026 Icb->Destag.Ident, 03027 BlockSize( IcbContext->Vcb ), 03028 UdfGetFidLbn( Fcb->FileId ), 03029 FALSE ); 03030 } else { 03031 03032 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 03033 } 03034 03035 // 03036 // Now the MaxEntries (4/14.6.4) field of the Icb Tag should tell us how big the extent 03037 // should be. The tail of this could be unrecorded. We could even have landed in the middle 03038 // of an extent. This is only a guess. For whatever reason we are having to guess this 03039 // information, any results are expected to be coming with few guarantees. 03040 // 03041 03042 Fcb->RootExtentLength = Icb->Icbtag.MaxEntries * BlockSize( IcbContext->Vcb ); 03043 } 03044 03045 // 03046 // Map the first extent into the current slot. 03047 // 03048 03049 UdfMapMetadataView( IrpContext, 03050 &IcbContext->Current, 03051 IcbContext->Vcb, 03052 UdfGetFidPartition( Fcb->FileId ), 03053 UdfGetFidLbn( Fcb->FileId ), 03054 Fcb->RootExtentLength ); 03055 return; 03056 }

VOID UdfInitializeLcbFromDirContext IN PIRP_CONTEXT  IrpContext,
IN PLCB  Lcb,
IN PDIR_ENUM_CONTEXT  DirContext
 

Definition at line 503 of file prefxsup.c.

References ASSERT, ASSERT_IRP_CONTEXT, ASSERT_LCB, FlagOn, NSR_FID_F_HIDDEN, NULL, PAGED_CODE, PDIR_ENUM_CONTEXT, and SetFlag.

Referenced by UdfOpenObjectFromDirContext().

00511 : 00512 00513 This routine performs common initialization of Lcbs from found directory 00514 entries. 00515 00516 Arguments: 00517 00518 Lcb - the Lcb to initialize. 00519 00520 DirContext - the directory enumeration context, enumerated to the FID associated 00521 with this Lcb. 00522 00523 Return Value: 00524 00525 None. 00526 00527 --*/ 00528 00529 { 00530 PAGED_CODE(); 00531 00532 // 00533 // Check inputs. 00534 // 00535 00536 ASSERT_IRP_CONTEXT( IrpContext ); 00537 ASSERT_LCB( Lcb ); 00538 00539 ASSERT( DirContext->Fid != NULL ); 00540 00541 // 00542 // This is falling down trivial now. Simply update the hidden flag in the Lcb. 00543 // 00544 00545 if (FlagOn( DirContext->Fid->Flags, NSR_FID_F_HIDDEN )) { 00546 00547 SetFlag( Lcb->FileAttributes, FILE_ATTRIBUTE_HIDDEN ); 00548 } 00549 }

NTSTATUS UdfInitializePcb IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN OUT PPCB Pcb,
IN PNSR_LVOL  LVD
 

Definition at line 367 of file allocsup.c.

References Add2Ptr, ASSERT_OPTIONAL_PCB, Dbg, DebugTrace, FALSE, FlagOn, FsRtlAllocatePoolWithTag, ISONsrLvolSize, _PARTMAP_UDF_GENERIC::Length, NTSTATUS(), NULL, PAGED_CODE, PagedPool, _PARTMAP_UDF_GENERIC::PartID, _PARTMAP_SPARABLE::Partition, _PARTMAP_VIRTUAL::Partition, PARTMAP_PHYSICAL::Partition, PARTITION, _tagPARTITION::PartitionNumber, PARTMAP_SPARABLE, PARTMAP_TYPE_PHYSICAL, PARTMAP_TYPE_PROXY, PCB_FLAG_PHYSICAL_PARTITION, PCB_FLAG_SPARABLE_PARTITION, PCB_FLAG_VIRTUAL_PARTITION, Physical, PNSR_LVOL, PPARTMAP_PHYSICAL, PPARTMAP_SPARABLE, PPARTMAP_UDF_GENERIC, PPARTMAP_VIRTUAL, SetFlag, Status, TAG_NSR_FSD, TRUE, _PARTMAP_UDF_GENERIC::Type, UDF_VERSION_150, UDF_VERSION_RECOGNIZED, UdfCreatePcb(), UdfDeletePcb(), UdfDomainIdentifierContained(), UdfSparablePartitionDomainIdentifier, UdfVirtualPartitionDomainIdentifier, USHORT, Virtual, _PARTMAP_SPARABLE::VolSetSeq, and PARTMAP_PHYSICAL::VolSetSeq.

Referenced by UdfFindVolumeDescriptors().

00376 : 00377 00378 This routine walks through the partition map of a Logical Volume Descriptor 00379 and builds an intializing Pcb from it. The Pcb will be ready to be used 00380 in searching for the partition descriptors of a volume. 00381 00382 Arguments: 00383 00384 Vcb - The volume this Pcb will pertain to 00385 00386 Pcb - Caller's pointer to the Pcb 00387 00388 LVD - The Logical Volume Descriptor being used 00389 00390 Return Value: 00391 00392 STATUS_SUCCESS if the partition map is good and the Pcb is built 00393 00394 STATUS_DISK_CORRUPT_ERROR if corrupt maps are found 00395 00396 STATUS_UNRECOGNIZED_VOLUME if noncompliant maps are found 00397 00398 --*/ 00399 00400 { 00401 PPARTMAP_UDF_GENERIC Map; 00402 PPARTITION Partition; 00403 00404 BOOLEAN Found; 00405 00406 PAGED_CODE(); 00407 00408 // 00409 // Check the input parameters 00410 // 00411 00412 ASSERT_OPTIONAL_PCB( *Pcb ); 00413 00414 DebugTrace(( +1, Dbg, 00415 "UdfInitializePcb, Lvd %08x\n", 00416 LVD )); 00417 00418 // 00419 // Delete a pre-existing (partially initialized from a failed 00420 // crawl of a VDS) Pcb. 00421 // 00422 00423 if (*Pcb != NULL) { 00424 00425 UdfDeletePcb( *Pcb ); 00426 *Pcb = NULL; 00427 } 00428 00429 *Pcb = UdfCreatePcb( LVD->MapTableCount ); 00430 00431 // 00432 // Walk the table of partition maps intializing the Pcb for the descriptor 00433 // initialization pass. 00434 // 00435 00436 for (Map = (PPARTMAP_UDF_GENERIC) LVD->MapTable, 00437 Partition = (*Pcb)->Partition; 00438 00439 Partition < &(*Pcb)->Partition[(*Pcb)->Partitions]; 00440 00441 Map = Add2Ptr( Map, Map->Length, PPARTMAP_UDF_GENERIC ), 00442 Partition++) { 00443 00444 // 00445 // Now check that this LVD can actually contain this map entry. First check that 00446 // the descriptor can contain the first few fields, then check that it can hold 00447 // all of the bytes claimed by the descriptor. 00448 // 00449 00450 if (Add2Ptr( Map, sizeof( PARTMAP_GENERIC ), PCHAR ) > Add2Ptr( LVD, ISONsrLvolSize( LVD ), PCHAR ) || 00451 Add2Ptr( Map, Map->Length, PCHAR ) > Add2Ptr( LVD, ISONsrLvolSize( LVD ), PCHAR )) { 00452 00453 DebugTrace(( 0, Dbg, 00454 "UdfInitializePcb, map at +%04x beyond Lvd size %04x\n", 00455 (PCHAR) Map - (PCHAR) LVD, 00456 ISONsrLvolSize( LVD ))); 00457 00458 DebugTrace(( -1, Dbg, 00459 "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" )); 00460 00461 return STATUS_DISK_CORRUPT_ERROR; 00462 } 00463 00464 // 00465 // Now load up this map entry. 00466 // 00467 00468 switch (Map->Type) { 00469 00470 case PARTMAP_TYPE_PHYSICAL: 00471 00472 { 00473 PPARTMAP_PHYSICAL MapPhysical = (PPARTMAP_PHYSICAL) Map; 00474 00475 // 00476 // Type 1 - Physical Partition 00477 // 00478 00479 DebugTrace(( 0, Dbg, 00480 "UdfInitializePcb, map reference %02x is Physical (Partition # %08x)\n", 00481 (Partition - (*Pcb)->Partition)/sizeof(PARTITION), 00482 MapPhysical->Partition )); 00483 00484 // 00485 // It must be the case that the volume the partition is on is the first 00486 // one since we only do single disc UDF. This will have already been 00487 // checked by the caller. 00488 // 00489 00490 if (MapPhysical->VolSetSeq > 1) { 00491 00492 DebugTrace(( 0, Dbg, 00493 "UdfInitializePcb, ... but physical partition resides on volume set volume # %08x (> 1)!\n", 00494 MapPhysical->VolSetSeq )); 00495 00496 DebugTrace(( -1, Dbg, 00497 "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" )); 00498 00499 return STATUS_DISK_CORRUPT_ERROR; 00500 } 00501 00502 SetFlag( (*Pcb)->Flags, PCB_FLAG_PHYSICAL_PARTITION ); 00503 Partition->Type = Physical; 00504 Partition->Physical.PartitionNumber = MapPhysical->Partition; 00505 } 00506 00507 break; 00508 00509 case PARTMAP_TYPE_PROXY: 00510 00511 // 00512 // Type 2 - a Proxy Partition, something not explicitly physical. 00513 // 00514 00515 DebugTrace(( 0, Dbg, 00516 "UdfInitializePcb, map reference %02x is a proxy\n", 00517 (Partition - (*Pcb)->Partition)/sizeof(PARTITION))); 00518 00519 // 00520 // Handle the various types of proxy partitions we recognize 00521 // 00522 00523 if (UdfDomainIdentifierContained( &Map->PartID, 00524 &UdfVirtualPartitionDomainIdentifier, 00525 UDF_VERSION_150, 00526 UDF_VERSION_RECOGNIZED )) { 00527 00528 { 00529 PPARTMAP_VIRTUAL MapVirtual = (PPARTMAP_VIRTUAL) Map; 00530 00531 // 00532 // Only one of these guys can exist, since there can be only one VAT per media surface. 00533 // 00534 00535 if (FlagOn( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION )) { 00536 00537 DebugTrace(( 0, Dbg, 00538 "UdfInitializePcb, ... but this is a second virtual partition!?!!\n" )); 00539 00540 DebugTrace(( -1, Dbg, 00541 "UdfInitializePcb -> STATUS_UNCRECOGNIZED_VOLUME\n" )); 00542 00543 return STATUS_UNRECOGNIZED_VOLUME; 00544 } 00545 00546 DebugTrace(( 0, Dbg, 00547 "UdfInitializePcb, ... Virtual (Partition # %08x)\n", 00548 MapVirtual->Partition )); 00549 00550 SetFlag( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION ); 00551 Partition->Type = Virtual; 00552 00553 // 00554 // We will convert the partition number to a partition reference 00555 // before returning. 00556 // 00557 00558 Partition->Virtual.RelatedReference = MapVirtual->Partition; 00559 } 00560 00561 } else if (UdfDomainIdentifierContained( &Map->PartID, 00562 &UdfSparablePartitionDomainIdentifier, 00563 UDF_VERSION_150, 00564 UDF_VERSION_RECOGNIZED )) { 00565 00566 { 00567 NTSTATUS Status; 00568 PPARTMAP_SPARABLE MapSparable = (PPARTMAP_SPARABLE) Map; 00569 00570 // 00571 // It must be the case that the volume the partition is on is the first 00572 // one since we only do single disc UDF. This will have already been 00573 // checked by the caller. 00574 // 00575 00576 if (MapSparable->VolSetSeq > 1) { 00577 00578 DebugTrace(( 0, Dbg, 00579 "UdfInitializePcb, ... but sparable partition resides on volume set volume # %08x (> 1)!\n", 00580 MapSparable->VolSetSeq )); 00581 00582 DebugTrace(( -1, Dbg, 00583 "UdfInitializePcb -> STATUS_DISK_CORRUPT_ERROR\n" )); 00584 00585 return STATUS_DISK_CORRUPT_ERROR; 00586 } 00587 00588 DebugTrace(( 0, Dbg, 00589 "UdfInitializePcb, ... Sparable (Partition # %08x)\n", 00590 MapSparable->Partition )); 00591 00592 // 00593 // We pretend that sparable partitions are basically the same as 00594 // physical partitions. Since we are not r/w (and will never be 00595 // on media that requires host-based sparing in any case), this 00596 // is a good simplification. 00597 // 00598 00599 SetFlag( (*Pcb)->Flags, PCB_FLAG_SPARABLE_PARTITION ); 00600 Partition->Type = Physical; 00601 Partition->Physical.PartitionNumber = MapSparable->Partition; 00602 00603 // 00604 // Save this map for use when the partition descriptor is found. 00605 // We can't load the sparing table at this time because we have 00606 // to turn the Lbn->Psn mapping into a Psn->Psn mapping. UDF 00607 // believes that the way sparing will be used in concert with 00608 // the Lbn->Psn mapping engine (like UdfLookupPsnOfExtent). 00609 // 00610 // Unfortunately, this would be a bit painful at this time. 00611 // The users of UdfLookupPsnOfExtent would need to iterate 00612 // over a new interface (not so bad) but the Vmcb package 00613 // would need to be turned inside out so that it didn't do 00614 // the page-filling alignment of blocks in the metadata 00615 // stream - instead, UdfLookupMetaVsnOfExtent would need to 00616 // do this itself. I choose to lay the sparing engine into 00617 // the read path and raw sector read engine instead. 00618 // 00619 00620 Partition->Physical.SparingMap = FsRtlAllocatePoolWithTag( PagedPool, 00621 sizeof(PARTMAP_SPARABLE), 00622 TAG_NSR_FSD); 00623 RtlCopyMemory( Partition->Physical.SparingMap, 00624 MapSparable, 00625 sizeof(PARTMAP_SPARABLE)); 00626 } 00627 00628 } else { 00629 00630 DebugTrace(( 0, Dbg, 00631 "UdfInitializePcb, ... but we don't recognize this proxy!\n" )); 00632 00633 DebugTrace(( -1, Dbg, 00634 "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" )); 00635 00636 return STATUS_UNRECOGNIZED_VOLUME; 00637 } 00638 00639 break; 00640 00641 default: 00642 00643 DebugTrace(( 0, Dbg, 00644 "UdfInitializePcb, map reference %02x is of unknown type %02x\n", 00645 Map->Type )); 00646 00647 DebugTrace(( -1, Dbg, 00648 "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" )); 00649 00650 return STATUS_UNRECOGNIZED_VOLUME; 00651 break; 00652 } 00653 } 00654 00655 if (!FlagOn( (*Pcb)->Flags, PCB_FLAG_PHYSICAL_PARTITION | PCB_FLAG_SPARABLE_PARTITION )) { 00656 00657 DebugTrace(( 0, Dbg, 00658 "UdfInitializePcb, no physical partition seen on this logical volume!\n" )); 00659 00660 DebugTrace(( -1, Dbg, 00661 "UdfInitializePcb -> STATUS_UNRECOGNIZED_VOLUME\n" )); 00662 00663 return STATUS_UNRECOGNIZED_VOLUME; 00664 } 00665 00666 if (FlagOn( (*Pcb)->Flags, PCB_FLAG_VIRTUAL_PARTITION )) { 00667 00668 PPARTITION Host; 00669 00670 // 00671 // Confirm the validity of any type 2 virtual maps on this volume 00672 // and convert partition numbers to partition references that will 00673 // immediately index an element of the Pcb. 00674 // 00675 00676 for (Partition = (*Pcb)->Partition; 00677 Partition < &(*Pcb)->Partition[(*Pcb)->Partitions]; 00678 Partition++) { 00679 00680 if (Partition->Type == Virtual) { 00681 00682 // 00683 // Go find the partition this thing is talking about 00684 // 00685 00686 Found = FALSE; 00687 00688 for (Host = (*Pcb)->Partition; 00689 Host < &(*Pcb)->Partition[(*Pcb)->Partitions]; 00690 Host++) { 00691 00692 if (Host->Type == Physical && 00693 Host->Physical.PartitionNumber == 00694 Partition->Virtual.RelatedReference) { 00695 00696 Partition->Virtual.RelatedReference = 00697 (USHORT)(Host - (*Pcb)->Partition)/sizeof(PARTITION); 00698 Found = TRUE; 00699 break; 00700 } 00701 } 00702 00703 // 00704 // Failure to find a physical partition for this virtual guy 00705 // is not a good sign. 00706 // 00707 00708 if (!Found) { 00709 00710 return STATUS_DISK_CORRUPT_ERROR; 00711 } 00712 } 00713 } 00714 } 00715 00716 DebugTrace(( -1, Dbg, 00717 "UdfInitializePcb -> STATUS_SUCCESS\n" )); 00718 00719 return STATUS_SUCCESS; 00720 }

VOID UdfInitializeStackIrpContext OUT PIRP_CONTEXT  IrpContext,
IN PIRP_CONTEXT_LITE  IrpContextLite
 

Definition at line 1528 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT_LITE, IRP_CONTEXT, IRP_CONTEXT_FLAG_ON_STACK, IRP_CONTEXT_FLAG_WAIT, IRP_MJ_CLOSE, PAGED_CODE, PIRP_CONTEXT_LITE, SetFlag, and UDFS_NTC_IRP_CONTEXT.

Referenced by UdfFspClose().

01535 : 01536 01537 This routine is called to initialize an IrpContext for the current 01538 UDFS request. The IrpContext is on the stack and we need to initialize 01539 it for the current request. The request is a close operation. 01540 01541 Arguments: 01542 01543 IrpContext - IrpContext to initialize. 01544 01545 IrpContextLite - Structure containing the details of this request. 01546 01547 Return Value: 01548 01549 None 01550 01551 --*/ 01552 01553 { 01554 PAGED_CODE(); 01555 01556 ASSERT_IRP_CONTEXT_LITE( IrpContextLite ); 01557 01558 // 01559 // Zero and then initialize the structure. 01560 // 01561 01562 RtlZeroMemory( IrpContext, sizeof( IRP_CONTEXT )); 01563 01564 // 01565 // Set the proper node type code and node byte size 01566 // 01567 01568 IrpContext->NodeTypeCode = UDFS_NTC_IRP_CONTEXT; 01569 IrpContext->NodeByteSize = sizeof( IRP_CONTEXT ); 01570 01571 // 01572 // Note that this is from the stack. 01573 // 01574 01575 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ON_STACK ); 01576 01577 // 01578 // Copy RealDevice for workque algorithms. 01579 // 01580 01581 IrpContext->RealDevice = IrpContextLite->RealDevice; 01582 01583 // 01584 // The Vcb is found in the Fcb. 01585 // 01586 01587 IrpContext->Vcb = IrpContextLite->Fcb->Vcb; 01588 01589 // 01590 // Major/Minor Function codes 01591 // 01592 01593 IrpContext->MajorFunction = IRP_MJ_CLOSE; 01594 01595 // 01596 // Set the wait parameter 01597 // 01598 01599 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); 01600 01601 return; 01602 }

BOOLEAN UdfInitializeVcb IN PIRP_CONTEXT  IrpContext,
IN OUT PVCB  Vcb,
IN PDEVICE_OBJECT  TargetDeviceObject,
IN PVPB  Vpb,
IN PDISK_GEOMETRY  DiskGeometry,
IN ULONG  MediaChangeCount
 

Definition at line 331 of file udfs/strucsup.c.

References ExInitializeFastMutex, ExInitializeResource, FlagOn, FsRtlNotifyInitializeSync(), NULL, ObReferenceObject, PAGED_CODE, RtlInitializeGenericTable(), SetFlag, TRUE, UdfAllocateTable(), UdfData, UdfDeallocateTable(), UdfFcbTableCompare(), UdfHighBit(), UDFS_BASE_RESIDUAL_REFERENCE, UDFS_BASE_RESIDUAL_USER_REFERENCE, UDFS_NTC_VCB, VCB, VCB_STATE_REMOVABLE_MEDIA, VcbMountInProgress, and _UDF_DATA::VcbQueue.

Referenced by UdfMountVolume().

00342 : 00343 00344 This routine initializes and inserts a new Vcb record into the in-memory 00345 data structure. The Vcb record "hangs" off the end of the Volume device 00346 object and must be allocated by our caller. 00347 00348 Arguments: 00349 00350 Vcb - Supplies the address of the Vcb record being initialized. 00351 00352 TargetDeviceObject - Supplies the address of the target device object to 00353 associate with the Vcb record. 00354 00355 Vpb - Supplies the address of the Vpb to associate with the Vcb record. 00356 00357 MediaChangeCount - Initial media change count of the target device 00358 00359 Return Value: 00360 00361 Boolean TRUE if the volume looks reasonable to continue mounting, FALSE 00362 otherwise. This routine can raise on allocation failure. 00363 00364 --*/ 00365 00366 { 00367 PAGED_CODE(); 00368 00369 // 00370 // We start by first zeroing out all of the VCB, this will guarantee 00371 // that any stale data is wiped clean. 00372 // 00373 00374 RtlZeroMemory( Vcb, sizeof( VCB )); 00375 00376 // 00377 // Set the proper node type code and node byte size. 00378 // 00379 00380 Vcb->NodeTypeCode = UDFS_NTC_VCB; 00381 Vcb->NodeByteSize = sizeof( VCB ); 00382 00383 // 00384 // Initialize the DirNotify structures. Do this first so there is 00385 // no cleanup if it raises. Nothing else below will fail with 00386 // a raise. 00387 // 00388 00389 InitializeListHead( &Vcb->DirNotifyList ); 00390 FsRtlNotifyInitializeSync( &Vcb->NotifySync ); 00391 00392 // 00393 // Initialize the resource variable for the Vcb and files. 00394 // 00395 00396 ExInitializeResource( &Vcb->VcbResource ); 00397 ExInitializeResource( &Vcb->FileResource ); 00398 ExInitializeFastMutex( &Vcb->VcbMutex ); 00399 00400 // 00401 // Insert this Vcb record on the UdfData.VcbQueue. 00402 // 00403 00404 InsertHeadList( &UdfData.VcbQueue, &Vcb->VcbLinks ); 00405 00406 // 00407 // Set the Target Device Object and Vpb fields, referencing the 00408 // target device. 00409 // 00410 00411 ObReferenceObject( TargetDeviceObject ); 00412 Vcb->TargetDeviceObject = TargetDeviceObject; 00413 Vcb->Vpb = Vpb; 00414 00415 // 00416 // Set the removable media flag based on the real device's 00417 // characteristics 00418 // 00419 00420 if (FlagOn( Vpb->RealDevice->Characteristics, FILE_REMOVABLE_MEDIA )) { 00421 00422 SetFlag( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ); 00423 } 00424 00425 // 00426 // Initialize the generic Fcb Table. 00427 // 00428 00429 RtlInitializeGenericTable( &Vcb->FcbTable, 00430 (PRTL_GENERIC_COMPARE_ROUTINE) UdfFcbTableCompare, 00431 (PRTL_GENERIC_ALLOCATE_ROUTINE) UdfAllocateTable, 00432 (PRTL_GENERIC_FREE_ROUTINE) UdfDeallocateTable, 00433 NULL ); 00434 00435 // 00436 // Show that we have a mount in progress. 00437 // 00438 00439 Vcb->VcbCondition = VcbMountInProgress; 00440 00441 // 00442 // Refererence the Vcb for two reasons. The first is a reference 00443 // that prevents the Vcb from going away on the last close unless 00444 // dismount has already occurred. The second is to make sure 00445 // we don't go into the dismount path on any error during mount 00446 // until we get to the Mount cleanup. 00447 // 00448 00449 Vcb->VcbResidualReference = UDFS_BASE_RESIDUAL_REFERENCE; 00450 Vcb->VcbResidualUserReference = UDFS_BASE_RESIDUAL_USER_REFERENCE; 00451 00452 Vcb->VcbReference = 1 + Vcb->VcbResidualReference; 00453 00454 // 00455 // Set the sector size. 00456 // 00457 00458 Vcb->SectorSize = DiskGeometry->BytesPerSector; 00459 00460 // 00461 // Set the sector shift amount. 00462 // 00463 00464 Vcb->SectorShift = UdfHighBit( DiskGeometry->BytesPerSector ); 00465 00466 // 00467 // Set the media change count on the device 00468 // 00469 00470 Vcb->MediaChangeCount = MediaChangeCount; 00471 00472 return TRUE; 00473 }

VOID UdfInitializeVmcb IN PVMCB  Vmcb,
IN POOL_TYPE  PoolType,
IN ULONG  MaximumLbn,
IN ULONG  LbSize
 

Definition at line 219 of file vmcbsup.c.

References Dbg, DebugTrace, DebugUnwind, FALSE, FsRtlInitializeMcb(), FsRtlUninitializeMcb(), KeInitializeMutex(), PAGED_CODE, RtlInitializeGenericTable(), SectorSize, and TRUE.

Referenced by UdfUpdateVcbPhase0().

00228 : 00229 00230 This routine initializes a new Vmcb Structure. The caller must 00231 supply the memory for the structure. This must precede all other calls 00232 that set/query the volume file mapping. 00233 00234 If pool is not available this routine will raise a status value 00235 indicating insufficient resources. 00236 00237 Arguments: 00238 00239 Vmcb - Supplies a pointer to the volume file structure to initialize. 00240 00241 PoolType - Supplies the pool type to use when allocating additional 00242 internal structures. 00243 00244 MaximumLbn - Supplies the maximum Lbn value that is valid for this 00245 volume. 00246 00247 LbSize - Size of a sector on this volume 00248 00249 Return Value: 00250 00251 None 00252 00253 --*/ 00254 00255 { 00256 BOOLEAN VbnInitialized; 00257 BOOLEAN LbnInitialized; 00258 00259 PAGED_CODE(); 00260 00261 DebugTrace(( +1, Dbg, "UdfInitializeVmcb, Vmcb = %08x\n", Vmcb )); 00262 00263 VbnInitialized = FALSE; 00264 LbnInitialized = FALSE; 00265 00266 try { 00267 00268 // 00269 // Initialize the fields in the vmcb structure 00270 // 00271 00272 KeInitializeMutex( &Vmcb->Mutex, 0 ); 00273 00274 FsRtlInitializeMcb( &Vmcb->VbnIndexed, PoolType ); 00275 VbnInitialized = TRUE; 00276 00277 FsRtlInitializeMcb( &Vmcb->LbnIndexed, PoolType ); 00278 LbnInitialized = TRUE; 00279 00280 Vmcb->MaximumLbn = MaximumLbn; 00281 00282 Vmcb->SectorSize = SectorSize; 00283 00284 #if VMCB_WRITE_SUPPORT 00285 00286 // 00287 // For the dirty table we store in the table context field the pool 00288 // type to use for allocating additional structures 00289 // 00290 00291 RtlInitializeGenericTable( &Vmcb->DirtyTable, 00292 PbCompareDirtyVmcb, 00293 PbAllocateDirtyVmcb, 00294 PbDeallocateDirtyVmcb, 00295 (PVOID)PoolType ); 00296 00297 #endif // VMCB_WRITE_SUPPORT 00298 00299 } finally { 00300 00301 // 00302 // If this is an abnormal termination then check if we need to 00303 // uninitialize the mcb structures 00304 // 00305 00306 if (AbnormalTermination()) { 00307 00308 if (VbnInitialized) { FsRtlUninitializeMcb( &Vmcb->VbnIndexed ); } 00309 if (LbnInitialized) { FsRtlUninitializeMcb( &Vmcb->LbnIndexed ); } 00310 } 00311 00312 DebugUnwind("UdfInitializeVmcb"); 00313 DebugTrace(( -1, Dbg, "UdfInitializeVmcb -> VOID\n" )); 00314 } 00315 00316 // 00317 // And return to our caller 00318 // 00319 00320 return; 00321 }

PLCB UdfInsertPrefix IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PUNICODE_STRING  Name,
IN BOOLEAN  ShortNameMatch,
IN BOOLEAN  IgnoreCase,
IN PFCB  ParentFcb
 

Definition at line 64 of file prefxsup.c.

References Add2Ptr, ASSERT_EXCLUSIVE_FCB, ASSERT_FCB, ASSERT_FCB_INDEX, ASSERT_IRP_CONTEXT, _LCB::ChildFcb, _LCB::ChildFcbLinks, ExAllocateFromPagedLookasideList(), _LCB::FileAttributes, _LCB::FileName, _LCB::Flags, FsRtlAllocatePoolWithTag, LCB_FLAG_IGNORE_CASE, LCB_FLAG_POOL_ALLOCATED, LCB_FLAG_SHORT_NAME, Name, _LCB::NodeByteSize, _LCB::NodeTypeCode, NULL, PAGED_CODE, _LCB::ParentFcb, _LCB::ParentFcbLinks, _LCB::Reference, SafeNodeType, SetFlag, SIZEOF_LOOKASIDE_LCB, TAG_LCB, UdfFindNameLink(), UdfFreePool(), UdfInsertNameLink(), UdfLcbLookasideList, UdfPagedPool, UdfRaiseStatus(), UDFS_NTC_FCB_INDEX, and UDFS_NTC_LCB.

Referenced by UdfOpenObjectFromDirContext().

00075 : 00076 00077 This routine inserts an Lcb linking the two Fcbs together. 00078 00079 Arguments: 00080 00081 Fcb - This is the Fcb whose name is being inserted into the tree. 00082 00083 Name - This is the name for the component. 00084 00085 ShortNameMatch - Indicates whether this name was found on an explicit 8.3 search 00086 00087 IgnoreCase - Indicates if we should insert into the case-insensitive tree. 00088 00089 ParentFcb - This is the ParentFcb. The prefix tree is attached to this. 00090 00091 Return Value: 00092 00093 PLCB - the Lcb inserted. 00094 00095 --*/ 00096 00097 { 00098 PLCB Lcb; 00099 PRTL_SPLAY_LINKS *TreeRoot; 00100 PLIST_ENTRY ListLinks; 00101 ULONG Flags; 00102 00103 PWCHAR NameBuffer; 00104 00105 PAGED_CODE(); 00106 00107 // 00108 // Check inputs. 00109 // 00110 00111 ASSERT_IRP_CONTEXT( IrpContext ); 00112 ASSERT_FCB( Fcb ); 00113 00114 ASSERT_EXCLUSIVE_FCB( Fcb ); 00115 ASSERT_EXCLUSIVE_FCB( ParentFcb ); 00116 ASSERT_FCB_INDEX( ParentFcb ); 00117 00118 // 00119 // It must be the case that an index Fcb is only referenced by a single index. Now 00120 // we walk the child's Lcb queue to insure that if any prefixes have already been 00121 // inserted, they all refer to the index Fcb we are linking to. This is the only way 00122 // we can detect directory cross-linkage. 00123 // 00124 00125 if (SafeNodeType( Fcb ) == UDFS_NTC_FCB_INDEX) { 00126 00127 for (ListLinks = Fcb->ParentLcbQueue.Flink; 00128 ListLinks != &Fcb->ParentLcbQueue; 00129 ListLinks = ListLinks->Flink) { 00130 00131 Lcb = CONTAINING_RECORD( ListLinks, LCB, ChildFcbLinks ); 00132 00133 if (Lcb->ParentFcb != ParentFcb) { 00134 00135 UdfRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); 00136 } 00137 } 00138 } 00139 00140 // 00141 // Capture the separate cases. 00142 // 00143 00144 if (IgnoreCase) { 00145 00146 TreeRoot = &ParentFcb->IgnoreCaseRoot; 00147 Flags = LCB_FLAG_IGNORE_CASE; 00148 00149 } else { 00150 00151 TreeRoot = &ParentFcb->ExactCaseRoot; 00152 Flags = 0; 00153 } 00154 00155 if (ShortNameMatch) { 00156 00157 SetFlag( Flags, LCB_FLAG_SHORT_NAME ); 00158 } 00159 00160 // 00161 // Allocate space for the Lcb. 00162 // 00163 00164 if ( sizeof( LCB ) + Name->Length > SIZEOF_LOOKASIDE_LCB ) { 00165 00166 Lcb = FsRtlAllocatePoolWithTag( UdfPagedPool, 00167 sizeof( LCB ) + Name->Length, 00168 TAG_LCB ); 00169 00170 SetFlag( Flags, LCB_FLAG_POOL_ALLOCATED ); 00171 00172 } else { 00173 00174 Lcb = ExAllocateFromPagedLookasideList( &UdfLcbLookasideList ); 00175 } 00176 00177 // 00178 // Set the type and size. 00179 // 00180 00181 Lcb->NodeTypeCode = UDFS_NTC_LCB; 00182 Lcb->NodeByteSize = sizeof( LCB ) + Name->Length; 00183 00184 // 00185 // Initialize the name-based file attributes. 00186 // 00187 00188 Lcb->FileAttributes = 0; 00189 00190 // 00191 // Set up the filename in the Lcb. 00192 // 00193 00194 Lcb->FileName.Length = 00195 Lcb->FileName.MaximumLength = Name->Length; 00196 00197 Lcb->FileName.Buffer = Add2Ptr( Lcb, sizeof( LCB ), PWCHAR ); 00198 00199 RtlCopyMemory( Lcb->FileName.Buffer, 00200 Name->Buffer, 00201 Name->Length ); 00202 00203 // 00204 // Insert the Lcb into the prefix tree. 00205 // 00206 00207 Lcb->Flags = Flags; 00208 00209 if (!UdfInsertNameLink( IrpContext, 00210 TreeRoot, 00211 Lcb )) { 00212 00213 // 00214 // This will very rarely occur. 00215 // 00216 00217 UdfFreePool( &Lcb ); 00218 00219 Lcb = UdfFindNameLink( IrpContext, 00220 TreeRoot, 00221 Name ); 00222 00223 if (Lcb == NULL) { 00224 00225 // 00226 // Even worse. 00227 // 00228 00229 UdfRaiseStatus( IrpContext, STATUS_DRIVER_INTERNAL_ERROR ); 00230 } 00231 00232 return Lcb; 00233 } 00234 00235 // 00236 // Link the Fcbs together through the Lcb. 00237 // 00238 00239 Lcb->ParentFcb = ParentFcb; 00240 Lcb->ChildFcb = Fcb; 00241 00242 InsertHeadList( &ParentFcb->ChildLcbQueue, &Lcb->ParentFcbLinks ); 00243 InsertHeadList( &Fcb->ParentLcbQueue, &Lcb->ChildFcbLinks ); 00244 00245 // 00246 // Initialize the reference count. 00247 // 00248 00249 Lcb->Reference = 0; 00250 00251 return Lcb; 00252 }

BOOLEAN UdfIs8dot3Name IN PIRP_CONTEXT  IrpContext,
IN UNICODE_STRING  FileName
 

Definition at line 176 of file namesup.c.

References ASSERT, ASSERT_IRP_CONTEXT, BYTE_COUNT_8_DOT_3, CHAR, Count, FALSE, FileName, FsRtlIsFatDbcsLegal(), L, NT_SUCCESS, PAGED_CODE, RtlUnicodeStringToCountedOemString(), and TRUE.

Referenced by UdfEnumerateIndex(), UdfFindDirEntry(), UdfQueryAlternateNameInfo(), and UdfQueryDirectory().

00183 : 00184 00185 This routine checks if the name follows the 8.3 name conventions. We check for 00186 the name length and whether the characters are valid. 00187 00188 Arguments: 00189 00190 FileName - String of bytes containing the name. 00191 00192 Return Value: 00193 00194 BOOLEAN - TRUE if this name is a legal 8.3 name, FALSE otherwise. 00195 00196 --*/ 00197 00198 { 00199 CHAR DbcsNameBuffer[ BYTE_COUNT_8_DOT_3 ]; 00200 STRING DbcsName; 00201 00202 PWCHAR NextWchar; 00203 ULONG Count; 00204 00205 ULONG DotCount = 0; 00206 BOOLEAN LastCharDot = FALSE; 00207 00208 PAGED_CODE(); 00209 00210 // 00211 // Check inputs. 00212 // 00213 00214 ASSERT_IRP_CONTEXT( IrpContext ); 00215 00216 // 00217 // The length must be less than 24 bytes. 00218 // 00219 00220 ASSERT( FileName.Length != 0 ); 00221 if (FileName.Length > BYTE_COUNT_8_DOT_3) { 00222 00223 return FALSE; 00224 } 00225 00226 // 00227 // Walk though and check for a space character. 00228 // 00229 00230 NextWchar = FileName.Buffer; 00231 Count = 0; 00232 00233 do { 00234 00235 // 00236 // No spaces allowed. 00237 // 00238 00239 if (*NextWchar == L' ') { return FALSE; } 00240 00241 if (*NextWchar == L'.') { 00242 00243 // 00244 // Not an 8.3 name if more than 1 dot or more than 8 characters 00245 // remaining. (It is legal for the dot to be in the ninth 00246 // position) 00247 // 00248 00249 if ((DotCount > 0) || 00250 (Count > 8 * sizeof( WCHAR ))) { 00251 00252 return FALSE; 00253 } 00254 00255 DotCount += 1; 00256 LastCharDot = TRUE; 00257 00258 } else { 00259 00260 LastCharDot = FALSE; 00261 } 00262 00263 Count += 2; 00264 NextWchar += 1; 00265 00266 } while (Count < FileName.Length); 00267 00268 // 00269 // We can't have a period at the end of the name. 00270 // 00271 00272 if (LastCharDot) { 00273 00274 return FALSE; 00275 } 00276 00277 // 00278 // Create an Oem name to use to check for a valid short name. 00279 // 00280 00281 DbcsName.MaximumLength = BYTE_COUNT_8_DOT_3; 00282 DbcsName.Buffer = DbcsNameBuffer; 00283 00284 if (!NT_SUCCESS( RtlUnicodeStringToCountedOemString( &DbcsName, 00285 &FileName, 00286 FALSE ))) { 00287 00288 return FALSE; 00289 } 00290 00291 // 00292 // We have now initialized the Oem string. Call the FsRtl package to check for a 00293 // valid FAT name. 00294 // 00295 00296 return FsRtlIsFatDbcsLegal( DbcsName, FALSE, FALSE, FALSE ); 00297 }

INLINE BOOLEAN UdfIsCharacterLegal IN WCHAR  Character  ) 
 

Definition at line 1208 of file udfprocs.h.

References FALSE, FsRtlIsAnsiCharacterLegalHpfs, and TRUE.

Referenced by UdfCS0DstringContainsLegalCharacters().

01214 : 01215 01216 This routine checks that a given UNICODE character is legal. 01217 01218 Arguments: 01219 01220 Character - a character to check 01221 01222 Return Value: 01223 01224 BOOLEAN True if a legal character, False otherwise. 01225 01226 --*/ 01227 01228 { 01229 if (Character < 0xff && !FsRtlIsAnsiCharacterLegalHpfs( Character, FALSE )) { 01230 01231 return FALSE; 01232 } 01233 01234 return TRUE; 01235 }

BOOLEAN UdfIsNameInExpression IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  CurrentName,
IN PUNICODE_STRING  SearchExpression,
IN BOOLEAN  Wild
 

Definition at line 1203 of file namesup.c.

References ASSERT_IRP_CONTEXT, FALSE, FsRtlIsNameInExpression(), NULL, PAGED_CODE, and TRUE.

Referenced by UdfEnumerateIndex().

01212 : 01213 01214 This routine will compare two Unicode strings. We assume that if this 01215 is to be a case-insensitive search then they are already upcased. 01216 01217 Arguments: 01218 01219 CurrentName - Filename from the disk. 01220 01221 SearchExpression - Filename expression to use for match. 01222 01223 Wild - True if wildcards are present in SearchExpression. 01224 01225 Return Value: 01226 01227 BOOLEAN - TRUE if the expressions match, FALSE otherwise. 01228 01229 --*/ 01230 01231 { 01232 BOOLEAN Match = TRUE; 01233 01234 PAGED_CODE(); 01235 01236 // 01237 // Check inputs. 01238 // 01239 01240 ASSERT_IRP_CONTEXT( IrpContext ); 01241 01242 // 01243 // If there are wildcards in the expression then we call the 01244 // appropriate FsRtlRoutine. 01245 // 01246 01247 if (Wild) { 01248 01249 Match = FsRtlIsNameInExpression( SearchExpression, 01250 CurrentName, 01251 FALSE, 01252 NULL ); 01253 01254 // 01255 // Otherwise do a direct memory comparison for the name string. 01256 // 01257 01258 } else { 01259 01260 if ((CurrentName->Length != SearchExpression->Length) || 01261 (!RtlEqualMemory( CurrentName->Buffer, 01262 SearchExpression->Buffer, 01263 CurrentName->Length ))) { 01264 01265 Match = FALSE; 01266 } 01267 } 01268 01269 return Match; 01270 }

NTSTATUS UdfLockVolumeInternal IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_OBJECT FileObject  OPTIONAL
 

Definition at line 621 of file udfs/fsctrl.c.

References ASSERT_EXCLUSIVE_VCB, CcWaitForCurrentLazyWriterActivity(), FALSE, FlagOn, IRP_CONTEXT_FLAG_WAIT, NT_SUCCESS, NTSTATUS(), PAGED_CODE, SetFlag, Status, UdfAcquireVcbExclusive, UdfFspClose(), UdfPurgeVolume(), UdfReleaseVcb, and VCB_STATE_LOCKED.

Referenced by UdfLockVolume(), and UdfPnpQueryRemove().

00629 : 00630 00631 This routine performs the actual lock volume operation. It will be called 00632 by anyone wishing to try to protect the volume for a long duration. PNP 00633 operations are such a user. 00634 00635 The volume must be held exclusive by the caller. 00636 00637 Arguments: 00638 00639 Vcb - The volume being locked. 00640 00641 FileObject - File corresponding to the handle locking the volume. If this 00642 is not specified, a system lock is assumed. 00643 00644 Return Value: 00645 00646 NTSTATUS - The return status for the operation 00647 00648 --*/ 00649 00650 { 00651 NTSTATUS Status; 00652 NTSTATUS FinalStatus = (FileObject? STATUS_ACCESS_DENIED: STATUS_DEVICE_BUSY); 00653 ULONG RemainingUserReferences = (FileObject? 1: 0); 00654 00655 PAGED_CODE(); 00656 00657 ASSERT_EXCLUSIVE_VCB( Vcb ); 00658 00659 // 00660 // If the volume is already locked then complete with success if this file 00661 // object has the volume locked, fail otherwise. 00662 // 00663 00664 if (FlagOn( Vcb->VcbState, VCB_STATE_LOCKED )) { 00665 00666 if (FileObject && Vcb->VolumeLockFileObject == FileObject) { 00667 00668 FinalStatus = STATUS_SUCCESS; 00669 } 00670 00671 } else if (Vcb->VcbCleanup == RemainingUserReferences) { 00672 00673 // 00674 // The cleanup count for the volume only reflects the fileobject that 00675 // will lock the volume. Otherwise, we must fail the request. 00676 // 00677 // Since the only cleanup is for the provided fileobject, we will try 00678 // to get rid of all of the other user references. If there is only one 00679 // remaining after the purge then we can allow the volume to be locked. 00680 // 00681 00682 UdfPurgeVolume( IrpContext, Vcb, FALSE ); 00683 00684 // 00685 // Now back out of our synchronization and wait for the lazy writer 00686 // to finish off any lazy closes that could have been outstanding. 00687 // 00688 // Since we purged, we know that the lazy writer will issue all 00689 // possible lazy closes in the next tick - if we hadn't, an otherwise 00690 // unopened file with a large amount of dirty data could have hung 00691 // around for a while as the data trickled out to the disk. 00692 // 00693 // This is even more important now since we send notification to 00694 // alert other folks that this style of check is about to happen so 00695 // that they can close their handles. We don't want to enter a fast 00696 // race with the lazy writer tearing down his references to the file. 00697 // 00698 00699 UdfReleaseVcb( IrpContext, Vcb ); 00700 00701 Status = CcWaitForCurrentLazyWriterActivity(); 00702 00703 // 00704 // This is intentional. If we were able to get the Vcb before, just 00705 // wait for it and take advantage of knowing that it is OK to leave 00706 // the flag up. 00707 // 00708 00709 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); 00710 UdfAcquireVcbExclusive( IrpContext, Vcb, FALSE ); 00711 00712 if (!NT_SUCCESS( Status )) { 00713 00714 return Status; 00715 } 00716 00717 UdfFspClose( Vcb ); 00718 00719 if (Vcb->VcbUserReference == Vcb->VcbResidualUserReference + RemainingUserReferences) { 00720 00721 SetFlag( Vcb->VcbState, VCB_STATE_LOCKED ); 00722 Vcb->VolumeLockFileObject = FileObject; 00723 FinalStatus = STATUS_SUCCESS; 00724 } 00725 } 00726 00727 return FinalStatus; 00728 }

VOID UdfLookupActiveIcb IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext
 

Definition at line 3124 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT, NULL, PAGED_CODE, UDF_ICB_RECURSION_LIMIT, UdfLookupActiveIcbInExtent(), UdfRaiseStatus(), and UdfUnpinView.

Referenced by UdfLookupFileEntryInEnumeration(), UdfOpenObjectByFileId(), UdfOpenObjectFromDirContext(), and UdfUpdateVcbPhase1().

03131 : 03132 03133 This routine is called to cause the active Icb for an Icb hierarchy to be mapped. 03134 A context initialized by UdfInitializeIcbContext() is required. 03135 03136 Arguments: 03137 03138 IcbContext - Context which has been initialized to point into an Icb hierarchy. 03139 03140 Return Value: 03141 03142 None. 03143 03144 Raised status if the Icb hierarchy is invalid. 03145 03146 --*/ 03147 03148 { 03149 PAGED_CODE(); 03150 03151 // 03152 // Check input parameters. 03153 // 03154 03155 ASSERT_IRP_CONTEXT( IrpContext ); 03156 03157 // 03158 // Travel the Icb hierarchy. Due to the design of ISO 13346, it is convenient to 03159 // recursively descend the hierarchy. Place a limit on this recursion which will 03160 // allow traversal of most reasonable hierarchies (this will tail recurse off of 03161 // the end of extents). 03162 // 03163 03164 UdfLookupActiveIcbInExtent( IrpContext, 03165 IcbContext, 03166 UDF_ICB_RECURSION_LIMIT ); 03167 03168 // 03169 // We must have found an active ICB. Drop the last mapped part of the enumeration 03170 // at this point. 03171 // 03172 03173 UdfUnpinView( IrpContext, &IcbContext->Current ); 03174 03175 if (IcbContext->Active.View == NULL) { 03176 03177 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 03178 } 03179 }

BOOLEAN UdfLookupAllocation IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN LONGLONG  FileOffset,
OUT PLONGLONG  DiskOffset,
OUT PULONG  ByteCount
 

Definition at line 69 of file allocsup.c.

References ASSERT, ASSERT_FCB, ASSERT_IRP_CONTEXT, BytesFromSectors, Dbg, DebugTrace, FALSE, FCB_STATE_EMBEDDED_DATA, FCB_STATE_MCB_INITIALIZED, FCB_STATE_VMCB_MAPPING, FlagOn, FsRtlLookupLargeMcbEntry(), LlBytesFromSectors, LlSectorsFromBytes, NULL, PAGED_CODE, _VCB::Pcb, PFCB, SectorOffset, SectorsFromBytes, _PCB::SparingMcb, TRUE, UdfMethod2NextRunoutInSectors, UdfMethod2TransformByteOffset, UdfVmcbVbnToLbn(), VCB_STATE_METHOD_2_FIXUP, _VCB::VcbState, and _VCB::Vmcb.

Referenced by UdfPrepareBuffers().

00079 : 00080 00081 This routine looks through the mapping information for the file 00082 to find the logical diskoffset and number of bytes at that offset. 00083 00084 This routine assumes we are looking up a valid range in the file. If 00085 a mapping does not exist, 00086 00087 Arguments: 00088 00089 Fcb - Fcb representing this stream. 00090 00091 FileOffset - Lookup the allocation beginning at this point. 00092 00093 DiskOffset - Address to store the logical disk offset. 00094 00095 ByteCount - Address to store the number of contiguous bytes beginning 00096 at DiskOffset above. 00097 00098 Return Value: 00099 00100 BOOLEAN - whether the extent is unrecorded data 00101 00102 --*/ 00103 00104 { 00105 PVCB Vcb; 00106 00107 BOOLEAN Recorded = TRUE; 00108 00109 BOOLEAN Result; 00110 00111 LARGE_INTEGER LocalPsn; 00112 LARGE_INTEGER LocalSectorCount; 00113 00114 PAGED_CODE(); 00115 00116 // 00117 // Check inputs 00118 // 00119 00120 ASSERT_IRP_CONTEXT( IrpContext ); 00121 ASSERT_FCB( Fcb ); 00122 00123 // 00124 // We will never be looking up the allocations of embedded objects. 00125 // 00126 00127 ASSERT( !FlagOn( Fcb->FcbState, FCB_STATE_EMBEDDED_DATA )); 00128 00129 Vcb = Fcb->Vcb; 00130 00131 LocalPsn.QuadPart = LocalSectorCount.QuadPart = 0; 00132 00133 // 00134 // Lookup the entry containing this file offset. 00135 // 00136 00137 if (FlagOn( Fcb->FcbState, FCB_STATE_VMCB_MAPPING )) { 00138 00139 // 00140 // Map this offset into the metadata stream. 00141 // 00142 00143 ASSERT( SectorOffset( Vcb, FileOffset ) == 0 ); 00144 00145 Result = UdfVmcbVbnToLbn( &Vcb->Vmcb, 00146 SectorsFromBytes( Vcb, FileOffset ), 00147 &LocalPsn.LowPart, 00148 &LocalSectorCount.LowPart ); 00149 00150 ASSERT( Result ); 00151 00152 } else { 00153 00154 // 00155 // Map this offset in a regular stream. 00156 // 00157 00158 ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_MCB_INITIALIZED )); 00159 00160 Result = FsRtlLookupLargeMcbEntry( &Fcb->Mcb, 00161 LlSectorsFromBytes( Vcb, FileOffset ), 00162 &LocalPsn.QuadPart, 00163 &LocalSectorCount.QuadPart, 00164 NULL, 00165 NULL, 00166 NULL ); 00167 } 00168 00169 // 00170 // If within the Mcb then we use the data out of this entry and are nearly done. 00171 // 00172 00173 if (Result) { 00174 00175 if ( LocalPsn.QuadPart == -1 ) { 00176 00177 // 00178 // Regular files can have holey allocations which represent unrecorded extents. For 00179 // such extents which are sandwiched in between recorded extents of the file, the Mcb 00180 // package tells us that it found a valid mapping but that it doesn't correspond to 00181 // any extents on the media yet. In this case, simply fake the disk offset. The 00182 // returned sector count is accurate. 00183 // 00184 00185 *DiskOffset = 0; 00186 00187 Recorded = FALSE; 00188 00189 } else { 00190 00191 // 00192 // Now mimic the effects of physical sector sparing. This may shrink the size of the 00193 // returned run if sparing interrupted the extent on disc. 00194 // 00195 00196 ASSERT( LocalPsn.HighPart == 0 ); 00197 00198 if (Vcb->Pcb->SparingMcb) { 00199 00200 LONGLONG SparingPsn; 00201 LONGLONG SparingSectorCount; 00202 00203 if (FsRtlLookupLargeMcbEntry( Vcb->Pcb->SparingMcb, 00204 LocalPsn.LowPart, 00205 &SparingPsn, 00206 &SparingSectorCount, 00207 NULL, 00208 NULL, 00209 NULL )) { 00210 00211 // 00212 // Only emit noise if we will really change anything as a result 00213 // of the sparing table. 00214 // 00215 00216 if (SparingPsn != -1 || 00217 SparingSectorCount < LocalSectorCount.QuadPart) { 00218 00219 DebugTrace(( 0, Dbg, "UdfLookupAllocation, spared [%x, +%x) onto [%x, +%x)\n", 00220 LocalPsn.LowPart, 00221 LocalSectorCount.LowPart, 00222 (ULONG) SparingPsn, 00223 (ULONG) SparingSectorCount )); 00224 } 00225 00226 // 00227 // If we did not land in a hole, map the sector. 00228 // 00229 00230 if (SparingPsn != -1) { 00231 00232 LocalPsn.QuadPart = SparingPsn; 00233 } 00234 00235 // 00236 // The returned sector count now reduces the previous sector count. 00237 // If we landed in a hole, this indicates that the trailing edge of 00238 // the extent is spared, if not this indicates that the leading 00239 // edge is spared. 00240 // 00241 00242 if (SparingSectorCount < LocalSectorCount.QuadPart) { 00243 00244 LocalSectorCount.QuadPart = SparingSectorCount; 00245 } 00246 } 00247 } 00248 00249 *DiskOffset = LlBytesFromSectors( Vcb, LocalPsn.QuadPart ) + SectorOffset( Vcb, FileOffset ); 00250 00251 // 00252 // Now we can apply method 2 fixups, which will again interrupt the size of the extent. 00253 // 00254 00255 if (FlagOn( Vcb->VcbState, VCB_STATE_METHOD_2_FIXUP )) { 00256 00257 LARGE_INTEGER SectorsToRunout; 00258 00259 SectorsToRunout.QuadPart= UdfMethod2NextRunoutInSectors( Vcb, *DiskOffset ); 00260 00261 if (SectorsToRunout.QuadPart < LocalSectorCount.QuadPart) { 00262 00263 LocalSectorCount.QuadPart = SectorsToRunout.QuadPart; 00264 } 00265 00266 *DiskOffset = UdfMethod2TransformByteOffset( Vcb, *DiskOffset ); 00267 } 00268 } 00269 00270 } else { 00271 00272 // 00273 // We know that prior to this call the system has restricted IO to points within the 00274 // the file data. Since we failed to find a mapping this is an unrecorded extent at 00275 // the end of the file, so just conjure up a proper representation. 00276 // 00277 00278 ASSERT( FileOffset < Fcb->FileSize.QuadPart ); 00279 00280 *DiskOffset = 0; 00281 00282 LocalSectorCount.QuadPart = LlSectorsFromBytes( Vcb, Fcb->FileSize.QuadPart ) - 00283 LlSectorsFromBytes( Vcb, FileOffset ) + 00284 1; 00285 00286 Recorded = FALSE; 00287 } 00288 00289 // 00290 // Restrict to MAXULONG bytes of allocation 00291 // 00292 00293 if (LocalSectorCount.QuadPart > SectorsFromBytes( Vcb, MAXULONG )) { 00294 00295 *ByteCount = MAXULONG; 00296 00297 } else { 00298 00299 *ByteCount = BytesFromSectors( Vcb, LocalSectorCount.LowPart ); 00300 } 00301 00302 *ByteCount -= SectorOffset( Vcb, FileOffset ); 00303 00304 return Recorded; 00305 }

PFCB UdfLookupFcbTable IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN FILE_ID  FileId
 

Definition at line 1949 of file udfs/strucsup.c.

References _FCB_TABLE_ELEMENT::Fcb, FILE_ID, Key, NULL, PAGED_CODE, PFCB_TABLE_ELEMENT, and RtlLookupElementGenericTable().

Referenced by UdfCreateFcb().

01957 : 01958 01959 This routine will look through the Fcb table looking for a matching 01960 entry. 01961 01962 Arguments: 01963 01964 Vcb - Vcb for this volume. 01965 01966 FileId - This is the key value to use for the search. 01967 01968 Return Value: 01969 01970 PFCB - A pointer to the matching entry or NULL otherwise. 01971 01972 --*/ 01973 01974 { 01975 FCB_TABLE_ELEMENT Key; 01976 PFCB_TABLE_ELEMENT Hit; 01977 PFCB ReturnFcb = NULL; 01978 01979 PAGED_CODE(); 01980 01981 Key.FileId = FileId; 01982 01983 Hit = (PFCB_TABLE_ELEMENT) RtlLookupElementGenericTable( &Vcb->FcbTable, &Key ); 01984 01985 if (Hit != NULL) { 01986 01987 ReturnFcb = Hit->Fcb; 01988 } 01989 01990 return ReturnFcb; 01991 01992 UNREFERENCED_PARAMETER( IrpContext ); 01993 }

BOOLEAN UdfLookupInitialDirEntry IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PDIR_ENUM_CONTEXT  DirContext,
IN PLONGLONG InitialOffset  OPTIONAL
 

Definition at line 165 of file dirsup.c.

References Add2Ptr, ASSERT_FCB_INDEX, ASSERT_IRP_CONTEXT, CcMapData(), DIR_CONTEXT_FLAG_SEEN_NONCONSTANT, DIR_CONTEXT_FLAG_SEEN_PARENT, GenericOffset, GenericTruncate, NULL, PAGED_CODE, TRUE, UdfCreateInternalStream(), UdfLookupDirEntryPostProcessing(), UdfUnpinData, and VACB_MAPPING_GRANULARITY.

Referenced by UdfFindDirEntry(), UdfLookupInitialFileIndex(), and UdfLookupNextFileIndex().

00174 : 00175 00176 This routine begins the enumeration of a directory by setting the context 00177 at the first avaliable directory entry. 00178 00179 Arguments: 00180 00181 Fcb - the directory being enumerated. 00182 00183 DirContext - a corresponding context for the enumeration. 00184 00185 InitialOffset - an optional starting byte offset to base the enumeration. 00186 00187 Return Value: 00188 00189 If InitialOffset is unspecified, TRUE will always be returned. Failure will result 00190 in a raised status indicating corruption. 00191 00192 If InitialOffset is specified, TRUE will be returned if a valid entry is found at this 00193 offset, FALSE otherwise. 00194 00195 --*/ 00196 00197 { 00198 BOOLEAN Result; 00199 00200 PAGED_CODE(); 00201 00202 // 00203 // Check inputs. 00204 // 00205 00206 ASSERT_IRP_CONTEXT( IrpContext ); 00207 ASSERT_FCB_INDEX( Fcb ); 00208 00209 // 00210 // Create the internal stream if it isn't already in place. 00211 // 00212 00213 if (Fcb->FileObject == NULL) { 00214 00215 UdfCreateInternalStream( IrpContext, Fcb->Vcb, Fcb ); 00216 } 00217 00218 // 00219 // Reset the flags. 00220 // 00221 00222 DirContext->Flags = 0; 00223 00224 if (InitialOffset) { 00225 00226 // 00227 // If we are beginning in the middle of the stream, adjust the sanity check flags. 00228 // 00229 00230 if (*InitialOffset != 0) { 00231 00232 DirContext->Flags = DIR_CONTEXT_FLAG_SEEN_NONCONSTANT | DIR_CONTEXT_FLAG_SEEN_PARENT; 00233 } 00234 00235 // 00236 // Now set up the range we will map. This is constrained by the size of a cache view. 00237 // 00238 00239 DirContext->BaseOffset.QuadPart = GenericTruncate( *InitialOffset, VACB_MAPPING_GRANULARITY ); 00240 DirContext->ViewOffset = (ULONG) GenericOffset( *InitialOffset, VACB_MAPPING_GRANULARITY ); 00241 00242 } else { 00243 00244 // 00245 // Map at the beginning. 00246 // 00247 00248 DirContext->BaseOffset.QuadPart = 0; 00249 DirContext->ViewOffset = 0; 00250 } 00251 00252 // 00253 // Contain the view length by the size of the stream and map. 00254 // 00255 00256 DirContext->ViewLength = VACB_MAPPING_GRANULARITY; 00257 00258 if (DirContext->BaseOffset.QuadPart + DirContext->ViewLength > Fcb->FileSize.QuadPart) { 00259 00260 DirContext->ViewLength = (ULONG) (Fcb->FileSize.QuadPart - DirContext->BaseOffset.QuadPart); 00261 } 00262 00263 UdfUnpinData( IrpContext, &DirContext->Bcb ); 00264 00265 CcMapData( Fcb->FileObject, 00266 &DirContext->BaseOffset, 00267 DirContext->ViewLength, 00268 TRUE, 00269 &DirContext->Bcb, 00270 &DirContext->View ); 00271 00272 DirContext->Fid = Add2Ptr( DirContext->View, DirContext->ViewOffset, PNSR_FID ); 00273 00274 // 00275 // The state of the context is now valid. Tail off into our common post-processor 00276 // to finish the work. 00277 // 00278 00279 return UdfLookupDirEntryPostProcessing( IrpContext, 00280 Fcb, 00281 DirContext, 00282 (BOOLEAN) (InitialOffset != NULL)); 00283 }

ULONG UdfLookupMetaVsnOfExtent IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN USHORT  Reference,
IN ULONG  Lbn,
IN ULONG  Len,
IN BOOLEAN  ExactEnd
 

Definition at line 1177 of file allocsup.c.

References ASSERT_IRP_CONTEXT, ASSERT_VCB, BlockOffset, BlocksFromBytes, BlocksFromSectors, CcSetFileSizes(), FALSE, LlBytesFromSectors, NULL, PCC_FILE_SIZES, SectorsFromBytes, TRUE, try_leave, UdfAddVmcbMapping(), UdfLockFcb, UdfLookupPsnOfExtent(), UdfRaiseStatus(), UdfRemoveVmcbMapping(), UdfUnlockFcb, and UdfVmcbLbnToVbn().

Referenced by UdfInitializeAllocations(), UdfMapMetadataView(), and UdfUpdateVcbPhase0().

01188 : 01189 01190 This routine maps the input logical block extent on a given partition to 01191 a starting virtual block in the metadata stream. If a mapping does not 01192 exist, one will be created and the metadata stream extended. 01193 01194 Arguments: 01195 01196 Vcb - Vcb of logical volume 01197 01198 Reference - Partition reference to use in the mapping 01199 01200 Lbn - Logical block number 01201 01202 Len - Length of extent in bytes 01203 01204 ExactEnd - Indicates the extension policy if these blocks are not mapped. 01205 01206 Return Value: 01207 01208 ULONG virtual sector number 01209 01210 Raised status if the Lbn extent is split across multiple Vbn extents. 01211 01212 --*/ 01213 01214 { 01215 ULONG Vsn; 01216 ULONG Psn; 01217 ULONG SectorCount; 01218 01219 BOOLEAN Result; 01220 01221 BOOLEAN UnwindExtension = FALSE; 01222 LONGLONG UnwindAllocationSize; 01223 01224 PFCB Fcb = NULL; 01225 01226 // 01227 // Check inputs 01228 // 01229 01230 ASSERT_IRP_CONTEXT( IrpContext ); 01231 ASSERT_VCB( Vcb ); 01232 01233 // 01234 // The extent must be an integral number of logical blocks in length. 01235 // 01236 01237 if (Len == 0 || BlockOffset( Vcb, Len )) { 01238 01239 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 01240 } 01241 01242 01243 // 01244 // Get the physical mapping of the extent. The Mcb package operates on ULONG/ULONG 01245 // keys and values so we must render our 48bit address into 32. We can do this since 01246 // this is a single surface implementation, and it is guaranteed that a surface cannot 01247 // contain more than MAXULONG physical sectors. 01248 // 01249 01250 Psn = UdfLookupPsnOfExtent( IrpContext, 01251 Vcb, 01252 Reference, 01253 Lbn, 01254 Len ); 01255 01256 // 01257 // Use try-finally for cleanup 01258 // 01259 01260 try { 01261 01262 // 01263 // We must safely establish a mapping and extend the metadata stream so that cached 01264 // reads can occur on this new extent. 01265 // 01266 01267 Fcb = Vcb->MetadataFcb; 01268 UdfLockFcb( IrpContext, Fcb ); 01269 01270 Result = UdfVmcbLbnToVbn( &Vcb->Vmcb, 01271 Psn, 01272 &Vsn, 01273 &SectorCount ); 01274 01275 if (Result) { 01276 01277 // 01278 // If the mapping covers the extent, we can give this back. 01279 // 01280 01281 if (BlocksFromSectors( Vcb, SectorCount ) >= BlocksFromBytes( Vcb, Len )) { 01282 01283 try_leave( NOTHING ); 01284 01285 } 01286 01287 // 01288 // It is a fatal error if the extent we are mapping is not wholly contained 01289 // by an extent of Vsns in the Vmcb. This will indicate that some structure 01290 // is trying to overlap another. 01291 // 01292 01293 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 01294 } 01295 01296 // 01297 // Add the new mapping. We know that it is being added to the end of the stream. 01298 // 01299 01300 UdfAddVmcbMapping( &Vcb->Vmcb, 01301 Psn, 01302 SectorsFromBytes( Vcb, Len ), 01303 ExactEnd, 01304 &Vsn, 01305 &SectorCount ); 01306 01307 UnwindAllocationSize = Fcb->AllocationSize.QuadPart; 01308 UnwindExtension = TRUE; 01309 01310 Fcb->AllocationSize.QuadPart = 01311 Fcb->FileSize.QuadPart = 01312 Fcb->ValidDataLength.QuadPart = LlBytesFromSectors( Vcb, Vsn + SectorCount); 01313 01314 CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize ); 01315 UnwindExtension = FALSE; 01316 01317 // 01318 // We do not need to purge the cache maps since the Vmcb will always be 01319 // page aligned, and thus any reads will have filled it with valid data. 01320 // 01321 01322 } finally { 01323 01324 if (UnwindExtension) { 01325 01326 ULONG FirstZappedVsn; 01327 01328 // 01329 // Strip off the additional mappings we made. 01330 // 01331 01332 Fcb->AllocationSize.QuadPart = 01333 Fcb->FileSize.QuadPart = 01334 Fcb->ValidDataLength.QuadPart = UnwindAllocationSize; 01335 01336 FirstZappedVsn = SectorsFromBytes( Vcb, UnwindAllocationSize ); 01337 01338 UdfRemoveVmcbMapping( &Vcb->Vmcb, 01339 FirstZappedVsn, 01340 Vsn + SectorCount - FirstZappedVsn ); 01341 01342 CcSetFileSizes( Fcb->FileObject, (PCC_FILE_SIZES) &Fcb->AllocationSize ); 01343 } 01344 01345 if (Fcb) { UdfUnlockFcb( IrpContext, Fcb ); } 01346 } 01347 01348 return Vsn; 01349 }

BOOLEAN UdfLookupNextDirEntry IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PDIR_ENUM_CONTEXT  DirContext
 

Definition at line 287 of file dirsup.c.

References Add2Ptr, ASSERT_FCB_INDEX, ASSERT_IRP_CONTEXT, ClearFlag, DIR_CONTEXT_FLAG_FID_BUFFERED, FALSE, FlagOn, PAGED_CODE, UdfFreePool(), and UdfLookupDirEntryPostProcessing().

Referenced by UdfFindDirEntry(), and UdfLookupNextFileIndex().

00295 : 00296 00297 This routine advances the enumeration of a directory by one entry. 00298 00299 Arguments: 00300 00301 Fcb - the directory being enumerated. 00302 00303 DirContext - a corresponding context for the enumeration. 00304 00305 Return Value: 00306 00307 BOOLEAN True if another Fid is avaliable, False if we are at the end. 00308 00309 --*/ 00310 00311 { 00312 PAGED_CODE(); 00313 00314 // 00315 // Check inputs. 00316 // 00317 00318 ASSERT_IRP_CONTEXT( IrpContext ); 00319 ASSERT_FCB_INDEX( Fcb ); 00320 00321 // 00322 // If we have reached the end, stop. 00323 // 00324 00325 if (DirContext->BaseOffset.QuadPart + DirContext->NextFidOffset == Fcb->FileSize.QuadPart) { 00326 00327 return FALSE; 00328 } 00329 00330 // 00331 // If the previous Fid was buffered, dismantle it now. 00332 // 00333 00334 if (FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED )) { 00335 00336 ClearFlag( DirContext->Flags, DIR_CONTEXT_FLAG_FID_BUFFERED ); 00337 UdfFreePool( &DirContext->Fid ); 00338 } 00339 00340 // 00341 // Move the pointers based on the knowledge generated in the previous iteration. 00342 // 00343 00344 DirContext->ViewOffset = DirContext->NextFidOffset; 00345 DirContext->Fid = Add2Ptr( DirContext->View, DirContext->ViewOffset, PNSR_FID ); 00346 00347 // 00348 // The state of the context is now valid. Tail off into our common post-processor 00349 // to finish the work. 00350 // 00351 00352 return UdfLookupDirEntryPostProcessing( IrpContext, 00353 Fcb, 00354 DirContext, 00355 FALSE ); 00356 }

ULONG UdfLookupPsnOfExtent IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN USHORT  Reference,
IN ULONG  Lbn,
IN ULONG  Len
 

Definition at line 1017 of file allocsup.c.

References ASSERT, ASSERT_IRP_CONTEXT, ASSERT_PCB, ASSERT_VCB, BlocksFromBytes, BlockSize, CcMapData(), Dbg, DebugTrace, DebugUnwind, FALSE, _tagPARTITION::Length, Offset, PAGED_CODE, _PCB::Partition, _PCB::Partitions, PBCB, Physical, SectorsFromBlocks, SectorsFromBytes, TRUE, UdfLookupPsnOfExtent(), UdfRaiseStatus(), UdfUnpinData, and Virtual.

Referenced by UdfFindFileSetDescriptor(), UdfInitializeAllocations(), UdfLookupMetaVsnOfExtent(), and UdfLookupPsnOfExtent().

01027 : 01028 01029 This routine maps the input logical block extent on a given partition to 01030 a starting physical sector. It doubles as a bounds checker - if the routine 01031 does not raise, the caller is guaranteed that the extent lies within the 01032 partition. 01033 01034 Arguments: 01035 01036 Vcb - Vcb of logical volume 01037 01038 Reference - Partition reference to use in the mapping 01039 01040 Lbn - Logical block number 01041 01042 Len - Length of extent in bytes 01043 01044 Return Value: 01045 01046 ULONG physical sector number 01047 01048 --*/ 01049 01050 { 01051 PPCB Pcb = Vcb->Pcb; 01052 ULONG Psn; 01053 01054 PBCB Bcb; 01055 LARGE_INTEGER Offset; 01056 PULONG MappedLbn; 01057 01058 PAGED_CODE(); 01059 01060 // 01061 // Check inputs 01062 // 01063 01064 ASSERT_IRP_CONTEXT( IrpContext ); 01065 ASSERT_VCB( Vcb ); 01066 ASSERT_PCB( Pcb ); 01067 01068 DebugTrace(( +1, Dbg, "UdfLookupPsnOfExtent, [%04x/%08x, +%08x)\n", Reference, Lbn, Len )); 01069 01070 if (Reference < Pcb->Partitions) { 01071 01072 while (TRUE) { 01073 01074 switch (Pcb->Partition[Reference].Type) { 01075 01076 case Physical: 01077 01078 // 01079 // Check that the input extent lies inside the partition. Calculate the 01080 // Lbn of the last block and see that it is interior. 01081 // 01082 01083 if (SectorsFromBlocks( Vcb, Lbn ) + SectorsFromBytes( Vcb, Len ) > 01084 Pcb->Partition[Reference].Physical.Length) { 01085 01086 goto NoGood; 01087 } 01088 01089 Psn = Pcb->Partition[Reference].Physical.Start + SectorsFromBlocks( Vcb, Lbn ); 01090 01091 DebugTrace(( -1, Dbg, "UdfLookupPsnOfExtent -> %08x\n", Psn )); 01092 return Psn; 01093 01094 case Virtual: 01095 01096 // 01097 // Bounds check. Per UDF 2.00 2.3.10 and implied in UDF 1.50, virtual 01098 // extent lengths cannot be greater than one block in size. 01099 // 01100 01101 if (Lbn + BlocksFromBytes( Vcb, Len ) > Pcb->Partition[Reference].Virtual.Length || 01102 Len > BlockSize( Vcb )) { 01103 01104 goto NoGood; 01105 } 01106 01107 try { 01108 01109 // 01110 // Calculate the location of the mapping element in the VAT 01111 // and retrieve. 01112 // 01113 01114 Offset.QuadPart = Lbn * sizeof(ULONG); 01115 01116 CcMapData( Vcb->VatFcb->FileObject, 01117 &Offset, 01118 sizeof(ULONG), 01119 TRUE, 01120 &Bcb, 01121 &MappedLbn ); 01122 01123 // 01124 // Now rewrite the inputs in terms of the virtual mapping. We 01125 // will reloop to perform the logical -> physical mapping. 01126 // 01127 01128 DebugTrace(( 0, Dbg, 01129 "UdfLookupPsnOfExtent, Mapping V %04x/%08x -> L %04x/%08x\n", 01130 Reference, 01131 Lbn, 01132 Pcb->Partition[Reference].Virtual.RelatedReference, 01133 *MappedLbn )); 01134 01135 Lbn = *MappedLbn; 01136 Reference = Pcb->Partition[Reference].Virtual.RelatedReference; 01137 01138 } finally { 01139 01140 DebugUnwind( UdfLookupPsnOfExtent ); 01141 01142 UdfUnpinData( IrpContext, &Bcb ); 01143 } 01144 01145 // 01146 // An Lbn of ~0 in the VAT is defined to indicate that the sector is unused, 01147 // so we should never see such a thing. 01148 // 01149 01150 if (Lbn == ~0) { 01151 01152 goto NoGood; 01153 } 01154 01155 break; 01156 01157 default: 01158 01159 ASSERT(FALSE); 01160 break; 01161 } 01162 } 01163 } 01164 01165 NoGood: 01166 01167 // 01168 // Some people have misinterpreted a partition number to equal a 01169 // partition reference, or perhaps this is just corrupt media. 01170 // 01171 01172 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 01173 }

VOID UdfMapMetadataView IN PIRP_CONTEXT  IrpContext,
IN PMAPPED_PVIEW  View,
IN PVCB  Vcb,
IN USHORT  Partition,
IN ULONG  Lbn,
IN ULONG  Length
 

Definition at line 337 of file udfs/cachesup.c.

References ASSERT_IRP_CONTEXT, CcMapData(), FALSE, LlBytesFromSectors, Offset, PMAPPED_PVIEW, TRUE, UdfLookupMetaVsnOfExtent(), and UdfUnpinView.

Referenced by UdfGetNextAllocationPostProcessing(), UdfInitializeIcbContext(), UdfInitializeIcbContextFromFcb(), and UdfLookupActiveIcbInExtent().

00348 : 00349 00350 Perform the common work of mapping an extent of metadata into a mapped view. 00351 00352 Arguments: 00353 00354 View - View structure to map the bytes into 00355 00356 Vcb - Vcb of the volume the extent is on 00357 00358 Partition - Partition of the extent 00359 00360 Lbn - Lbn of the extent 00361 00362 Length - Length of the extent 00363 00364 Return Value: 00365 00366 None. 00367 00368 --*/ 00369 00370 { 00371 LARGE_INTEGER Offset; 00372 ULONG Vsn; 00373 00374 ASSERT_IRP_CONTEXT( IrpContext ); 00375 00376 // 00377 // Remove any existing mapping 00378 // 00379 00380 UdfUnpinView( IrpContext, View ); 00381 00382 // 00383 // Update the view information. 00384 // 00385 00386 View->Partition = Partition; 00387 View->Lbn = Lbn; 00388 View->Length = Length; 00389 00390 // 00391 // Find the mapping of this extent in the Metadata stream. 00392 // 00393 00394 Vsn = UdfLookupMetaVsnOfExtent( IrpContext, 00395 Vcb, 00396 Partition, 00397 Lbn, 00398 Length, 00399 FALSE ); 00400 00401 Offset.QuadPart = LlBytesFromSectors( Vcb, Vsn ); 00402 00403 // 00404 // Map the extent 00405 // 00406 00407 CcMapData( Vcb->MetadataFcb->FileObject, 00408 &Offset, 00409 Length, 00410 TRUE, 00411 &View->Bcb, 00412 &View->View ); 00413 }

NTSTATUS UdfNonCachedRead IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN LONGLONG  StartingOffset,
IN ULONG  ByteCount
 

Definition at line 201 of file deviosup.c.

References Add2Ptr, ASSERT, ClearFlag, DebugUnwind, FALSE, FCB_STATE_EMBEDDED_DATA, FCB_STATE_VMCB_MAPPING, FlagOn, IRP_CONTEXT_FLAG_ALLOC_IO, IRP_CONTEXT_FLAG_WAIT, KeFlushIoBuffers(), MAX_PARALLEL_IOS, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, Status, TRUE, try_leave, UdfCreateUserMdl(), UdfFinishBuffers(), UdfMapUserBuffer, UdfMultipleAsync(), UdfPrepareBuffers(), UdfRaiseStatus(), UdfSingleAsync(), and UdfWaitSync().

Referenced by UdfCommonRead().

00210 : 00211 00212 This routine performs the non-cached reads of sectors. This is done by 00213 performing the following in a loop. 00214 00215 Fill in the IoRuns array for the next block of Io. 00216 Send the Io to the device. 00217 Perform any cleanup on the Io runs array. 00218 00219 We will not do async Io to any request that generates non-aligned Io. 00220 Also we will not perform async Io if it will exceed the size of our 00221 IoRuns array. These should be the unusual cases but we will raise 00222 or return CANT_WAIT in this routine if we detect this case. 00223 00224 Arguments: 00225 00226 Fcb - Fcb representing the file to read. 00227 00228 StartingOffset - Logical offset in the file to read from. 00229 00230 ByteCount - Number of bytes to read. 00231 00232 Return Value: 00233 00234 NTSTATUS - Status indicating the result of the operation. 00235 00236 --*/ 00237 00238 { 00239 NTSTATUS Status = STATUS_SUCCESS; 00240 00241 IO_RUN IoRuns[MAX_PARALLEL_IOS]; 00242 ULONG RunCount = 0; 00243 ULONG CleanupRunCount = 0; 00244 00245 PVOID UserBuffer; 00246 ULONG UserBufferOffset = 0; 00247 LONGLONG CurrentOffset = StartingOffset; 00248 ULONG RemainingByteCount = ByteCount; 00249 ULONG ThisByteCount; 00250 00251 BOOLEAN Unaligned; 00252 BOOLEAN SparseRuns; 00253 BOOLEAN FlushIoBuffers = FALSE; 00254 BOOLEAN FirstPass = TRUE; 00255 00256 PAGED_CODE(); 00257 00258 // 00259 // We want to make sure the user's buffer is locked in all cases. 00260 // 00261 00262 if (IrpContext->Irp->MdlAddress == NULL) { 00263 00264 UdfCreateUserMdl( IrpContext, ByteCount, TRUE ); 00265 } 00266 00267 // 00268 // Use a try-finally to perform the final cleanup. 00269 // 00270 00271 try { 00272 00273 UdfMapUserBuffer( IrpContext, &UserBuffer); 00274 00275 // 00276 // Loop while there are more bytes to transfer. 00277 // 00278 00279 do { 00280 00281 // 00282 // Call prepare buffers to set up the next entries 00283 // in the IoRuns array. Remember if there are any 00284 // unaligned entries. 00285 // 00286 00287 RtlZeroMemory( IoRuns, sizeof( IoRuns )); 00288 00289 Unaligned = UdfPrepareBuffers( IrpContext, 00290 IrpContext->Irp, 00291 Fcb, 00292 UserBuffer, 00293 UserBufferOffset, 00294 CurrentOffset, 00295 RemainingByteCount, 00296 IoRuns, 00297 &CleanupRunCount, 00298 &ThisByteCount, 00299 &SparseRuns ); 00300 00301 00302 RunCount = CleanupRunCount; 00303 00304 // 00305 // Quickly finish if we wound up having no IO to perform. This will 00306 // occur in the presence of unrecorded sectors. 00307 // 00308 00309 ASSERT( !(SparseRuns && FlagOn( Fcb->FcbState, FCB_STATE_VMCB_MAPPING|FCB_STATE_EMBEDDED_DATA ))); 00310 00311 if (RunCount == 0) { 00312 00313 try_leave( Status = IrpContext->Irp->IoStatus.Status = STATUS_SUCCESS ); 00314 } 00315 00316 // 00317 // If this is an async request and there aren't enough entries 00318 // in the Io array then post the request. This routine will 00319 // always raise if we are doing any unaligned Io for an 00320 // async request. 00321 // 00322 00323 if ((ThisByteCount < RemainingByteCount) && 00324 !FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00325 00326 UdfRaiseStatus( IrpContext, STATUS_CANT_WAIT ); 00327 } 00328 00329 // 00330 // If the entire Io is contained in a single run then 00331 // we can pass the Io down to the driver. Send the driver down 00332 // and wait on the result if this is synchronous. We cannot 00333 // do this simple form (just chucking the IRP down) if some 00334 // sparse runs were encountered. 00335 // 00336 00337 if ((RunCount == 1) && !Unaligned && !SparseRuns && FirstPass) { 00338 00339 UdfSingleAsync( IrpContext, 00340 IoRuns[0].DiskOffset, 00341 IoRuns[0].DiskByteCount ); 00342 00343 // 00344 // No cleanup needed for the IoRuns array here. 00345 // 00346 00347 CleanupRunCount = 0; 00348 00349 // 00350 // Wait if we are synchronous, otherwise return 00351 // 00352 00353 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00354 00355 UdfWaitSync( IrpContext ); 00356 00357 Status = IrpContext->Irp->IoStatus.Status; 00358 00359 // 00360 // Our completion routine will free the Io context but 00361 // we do want to return STATUS_PENDING. 00362 // 00363 00364 } else { 00365 00366 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); 00367 Status = STATUS_PENDING; 00368 } 00369 00370 try_leave( NOTHING ); 00371 } 00372 00373 // 00374 // Otherwise we will perform multiple Io to read in the data. 00375 // 00376 00377 UdfMultipleAsync( IrpContext, RunCount, IoRuns ); 00378 00379 // 00380 // No cleanup needed on the IoRuns now. 00381 // 00382 00383 CleanupRunCount = 0; 00384 00385 // 00386 // If this is a synchronous request then perform any necessary 00387 // post-processing. 00388 // 00389 00390 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT )) { 00391 00392 // 00393 // Wait for the request to complete. 00394 // 00395 00396 UdfWaitSync( IrpContext ); 00397 00398 Status = IrpContext->Irp->IoStatus.Status; 00399 00400 // 00401 // Exit this loop if there is an error. 00402 // 00403 00404 if (!NT_SUCCESS( Status )) { 00405 00406 try_leave( NOTHING ); 00407 } 00408 00409 // 00410 // Perform post read operations on the IoRuns if 00411 // necessary. 00412 // 00413 00414 if (Unaligned && 00415 UdfFinishBuffers( IrpContext, IoRuns, RunCount, FALSE )) { 00416 00417 FlushIoBuffers = TRUE; 00418 } 00419 00420 // 00421 // Exit this loop if there are no more bytes to transfer 00422 // or we have any error. 00423 // 00424 00425 RemainingByteCount -= ThisByteCount; 00426 CurrentOffset += ThisByteCount; 00427 UserBuffer = Add2Ptr( UserBuffer, ThisByteCount, PVOID ); 00428 UserBufferOffset += ThisByteCount; 00429 00430 // 00431 // Otherwise this is an asynchronous request. Always return 00432 // STATUS_PENDING. 00433 // 00434 00435 } else { 00436 00437 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_ALLOC_IO ); 00438 CleanupRunCount = 0; 00439 try_leave( Status = STATUS_PENDING ); 00440 break; 00441 } 00442 00443 FirstPass = FALSE; 00444 } while (RemainingByteCount != 0); 00445 00446 // 00447 // Flush the hardware cache if we performed any copy operations. 00448 // 00449 00450 if (FlushIoBuffers) { 00451 00452 KeFlushIoBuffers( IrpContext->Irp->MdlAddress, TRUE, FALSE ); 00453 } 00454 00455 } finally { 00456 00457 DebugUnwind( "UdfNonCachedRead" ); 00458 00459 // 00460 // Perform final cleanup on the IoRuns if necessary. 00461 // 00462 00463 if (CleanupRunCount != 0) { 00464 00465 UdfFinishBuffers( IrpContext, IoRuns, CleanupRunCount, TRUE ); 00466 } 00467 } 00468 00469 return Status; 00470 }

BOOLEAN UdfNoopAcquire IN PVOID  Fcb,
IN BOOLEAN  Wait
 

Definition at line 208 of file resrcsup.c.

References PAGED_CODE, and TRUE.

Referenced by UdfInitializeGlobalData().

00215 : 00216 00217 This routine does nothing. 00218 00219 Arguments: 00220 00221 Fcb - The Fcb/Vcb which was specified as a context parameter for this 00222 routine. 00223 00224 Wait - TRUE if the caller is willing to block. 00225 00226 Return Value: 00227 00228 TRUE 00229 00230 --*/ 00231 00232 { 00233 PAGED_CODE(); 00234 return TRUE; 00235 }

VOID UdfNoopRelease IN PVOID  Fcb  ) 
 

Definition at line 239 of file resrcsup.c.

References PAGED_CODE.

Referenced by UdfInitializeGlobalData().

00245 : 00246 00247 This routine does nothing. 00248 00249 Arguments: 00250 00251 Fcb - The Fcb/Vcb which was specified as a context parameter for this 00252 routine. 00253 00254 Return Value: 00255 00256 None 00257 00258 --*/ 00259 00260 { 00261 PAGED_CODE(); 00262 return; 00263 }

INLINE VOID UdfNormalizeAndRaiseStatus IN PIRP_CONTEXT  IrpContext,
IN NTSTATUS  Status
 

Definition at line 418 of file udfprocs.h.

References ExRaiseStatus(), FsRtlNormalizeNtstatus(), and Status.

Referenced by UdfCommonRead(), UdfPerformVerify(), UdfReadSectors(), and UdfVerifyVcb().

00422 { 00423 IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR ); 00424 ExRaiseStatus( IrpContext->ExceptionStatus ); 00425 }

VOID UdfOplockComplete IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 222 of file workque.c.

References FALSE, _IRP::IoStatus, Irp, IRP_MJ_CREATE, NULL, PAGED_CODE, UdfAddToWorkque(), UdfCompleteRequest(), UdfReleaseFcb, and UdfTeardownStructures().

Referenced by UdfCommonLockControl(), UdfCommonRead(), and UdfCompleteFcbOpen().

00229 : 00230 00231 This routine is called by the oplock package when an oplock break has 00232 completed, allowing an Irp to resume execution. If the status in 00233 the Irp is STATUS_SUCCESS, then we queue the Irp to the Fsp queue. 00234 Otherwise we complete the Irp with the status in the Irp. 00235 00236 If we are completing due to an error then check if there is any 00237 cleanup to do. 00238 00239 Arguments: 00240 00241 Irp - I/O Request Packet. 00242 00243 Return Value: 00244 00245 None. 00246 00247 --*/ 00248 00249 { 00250 BOOLEAN RemovedFcb; 00251 00252 PAGED_CODE(); 00253 00254 // 00255 // Check on the return value in the Irp. If success then we 00256 // are to post this request. 00257 // 00258 00259 if (Irp->IoStatus.Status == STATUS_SUCCESS) { 00260 00261 // 00262 // Check if there is any cleanup work to do. 00263 // 00264 00265 switch (IrpContext->MajorFunction) { 00266 00267 case IRP_MJ_CREATE : 00268 00269 // 00270 // If called from the oplock package then there is an 00271 // Fcb to possibly teardown. We will call the teardown 00272 // routine and release the Fcb if still present. The cleanup 00273 // code in create will know not to release this Fcb because 00274 // we will clear the pointer. 00275 // 00276 00277 if (IrpContext->TeardownFcb != NULL) { 00278 00279 UdfTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), FALSE, &RemovedFcb ); 00280 00281 if (!RemovedFcb) { 00282 00283 UdfReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) ); 00284 } 00285 00286 *(IrpContext->TeardownFcb) = NULL; 00287 IrpContext->TeardownFcb = NULL; 00288 } 00289 00290 break; 00291 } 00292 // 00293 // Insert the Irp context in the workqueue. 00294 // 00295 00296 UdfAddToWorkque( IrpContext, Irp ); 00297 00298 // 00299 // Otherwise complete the request. 00300 // 00301 00302 } else { 00303 00304 UdfCompleteRequest( IrpContext, Irp, Irp->IoStatus.Status ); 00305 } 00306 00307 return; 00308 }

NTSTATUS UdfPerformDevIoCtrl IN PIRP_CONTEXT  IrpContext,
IN ULONG  IoControlCode,
IN PDEVICE_OBJECT  Device,
OUT PVOID OutputBuffer  OPTIONAL,
IN ULONG  OutputBufferLength,
IN BOOLEAN  InternalDeviceIoControl,
IN BOOLEAN  OverrideVerify,
OUT PIO_STATUS_BLOCK Iosb  OPTIONAL
 

Definition at line 573 of file deviosup.c.

References Event(), Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, IoGetNextIrpStackLocation, Irp, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, PAGED_CODE, SetFlag, SL_OVERRIDE_VERIFY_VOLUME, Status, and VOID().

Referenced by UdfDetermineVolumeBounding(), UdfMountVolume(), UdfVerifyVcb(), and UdfVerifyVolume().

00586 : 00587 00588 This routine is called to perform DevIoCtrl functions internally within 00589 the filesystem. We take the status from the driver and return it to our 00590 caller. 00591 00592 Arguments: 00593 00594 IoControlCode - Code to send to driver. 00595 00596 Device - This is the device to send the request to. 00597 00598 OutPutBuffer - Pointer to output buffer. 00599 00600 OutputBufferLength - Length of output buffer above. 00601 00602 InternalDeviceIoControl - Indicates if this is an internal or external 00603 Io control code. 00604 00605 OverrideVerify - Indicates if we should tell the driver not to return 00606 STATUS_VERIFY_REQUIRED for mount and verify. 00607 00608 Iosb - If specified, we return the results of the operation here. 00609 00610 Return Value: 00611 00612 NTSTATUS - Status returned by next lower driver. 00613 00614 --*/ 00615 00616 { 00617 NTSTATUS Status; 00618 PIRP Irp; 00619 KEVENT Event; 00620 IO_STATUS_BLOCK LocalIosb; 00621 PIO_STATUS_BLOCK IosbToUse = &LocalIosb; 00622 00623 PAGED_CODE(); 00624 00625 // 00626 // Check if the user gave us an Iosb. 00627 // 00628 00629 if (ARGUMENT_PRESENT( Iosb )) { 00630 00631 IosbToUse = Iosb; 00632 } 00633 00634 IosbToUse->Status = 0; 00635 IosbToUse->Information = 0; 00636 00637 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 00638 00639 Irp = IoBuildDeviceIoControlRequest( IoControlCode, 00640 Device, 00641 NULL, 00642 0, 00643 OutputBuffer, 00644 OutputBufferLength, 00645 InternalDeviceIoControl, 00646 &Event, 00647 IosbToUse ); 00648 00649 if (Irp == NULL) { 00650 00651 return STATUS_INSUFFICIENT_RESOURCES; 00652 } 00653 00654 if (OverrideVerify) { 00655 00656 SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); 00657 } 00658 00659 Status = IoCallDriver( Device, Irp ); 00660 00661 // 00662 // We check for device not ready by first checking Status 00663 // and then if status pending was returned, the Iosb status 00664 // value. 00665 // 00666 00667 if (Status == STATUS_PENDING) { 00668 00669 (VOID) KeWaitForSingleObject( &Event, 00670 Executive, 00671 KernelMode, 00672 FALSE, 00673 (PLARGE_INTEGER)NULL ); 00674 00675 Status = IosbToUse->Status; 00676 } 00677 00678 return Status; 00679 00680 UNREFERENCED_PARAMETER( IrpContext ); 00681 }

NTSTATUS UdfPerformVerify IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN PDEVICE_OBJECT  DeviceToVerify
 

Definition at line 42 of file udfs/verfysup.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, _IO_STACK_LOCATION::DeviceObject, DO_VERIFY_VOLUME, FALSE, _FILE_OBJECT::FileName, _IO_STACK_LOCATION::FileObject, FlagOn, IO_REMOUNT, IoGetCurrentIrpStackLocation, IoIsErrorUserInduced, IoSetHardErrorOrVerifyDevice(), _IRP::IoStatus, IoVerifyVolume(), Irp, IRP_MJ_CREATE, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MN_MOUNT_VOLUME, IRP_MN_VERIFY_VOLUME, NT_SUCCESS, NTSTATUS(), NULL, _FILE_OBJECT::RelatedFileObject, Status, TRUE, UdfAcquireUdfData, UdfCheckForDismount(), UdfCompleteRequest(), UdfExceptionFilter(), UdfFsdPostRequest(), UdfNormalizeAndRaiseStatus(), UdfProcessException(), UdfReleaseUdfData, _VCB::VcbCondition, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbNotMounted, _VCB::VcbReference, and _VCB::VcbResidualReference.

Referenced by UdfProcessException().

00050 : 00051 00052 This routines performs an IoVerifyVolume operation and takes the 00053 appropriate action. If the verify is successful then we send the originating 00054 Irp off to an Ex Worker Thread. This routine is called from the exception handler. 00055 00056 No file system resources are held when this routine is called. 00057 00058 Arguments: 00059 00060 Irp - The irp to send off after all is well and done. 00061 00062 Device - The real device needing verification. 00063 00064 Return Value: 00065 00066 None. 00067 00068 --*/ 00069 00070 { 00071 PVCB Vcb; 00072 NTSTATUS Status = STATUS_SUCCESS; 00073 PIO_STACK_LOCATION IrpSp; 00074 00075 ASSERT_IRP_CONTEXT( IrpContext ); 00076 ASSERT_IRP( Irp ); 00077 00078 // 00079 // Check if this Irp has a status of Verify required and if it does 00080 // then call the I/O system to do a verify. 00081 // 00082 // Skip the IoVerifyVolume if this is a mount or verify request 00083 // itself. Trying a recursive mount will cause a deadlock with 00084 // the DeviceObject->DeviceLock. 00085 // 00086 00087 if ((IrpContext->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL) && 00088 ((IrpContext->MinorFunction == IRP_MN_MOUNT_VOLUME) || 00089 (IrpContext->MinorFunction == IRP_MN_VERIFY_VOLUME))) { 00090 00091 return UdfFsdPostRequest( IrpContext, Irp ); 00092 } 00093 00094 // 00095 // Extract a pointer to the Vcb from the VolumeDeviceObject. 00096 // Note that since we have specifically excluded mount, 00097 // requests, we know that IrpSp->DeviceObject is indeed a 00098 // volume device object. 00099 // 00100 00101 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00102 00103 Vcb = &CONTAINING_RECORD( IrpSp->DeviceObject, 00104 VOLUME_DEVICE_OBJECT, 00105 DeviceObject )->Vcb; 00106 00107 // 00108 // Check if the volume still thinks it needs to be verified, 00109 // if it doesn't then we can skip doing a verify because someone 00110 // else beat us to it. 00111 // 00112 00113 try { 00114 00115 if (FlagOn( DeviceToVerify->Flags, DO_VERIFY_VOLUME )) { 00116 00117 BOOLEAN AllowRawMount = FALSE; 00118 00119 // 00120 // We will allow Raw to mount this volume if we were doing a 00121 // an absolute DASD open. 00122 // 00123 00124 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) && 00125 (IrpSp->FileObject->FileName.Length == 0) && 00126 (IrpSp->FileObject->RelatedFileObject == NULL)) { 00127 00128 AllowRawMount = TRUE; 00129 } 00130 00131 // 00132 // If the IopMount in IoVerifyVolume did something, and 00133 // this is an absolute open, force a reparse. 00134 // 00135 00136 Status = IoVerifyVolume( DeviceToVerify, AllowRawMount ); 00137 00138 // 00139 // If the verify operation completed it will return 00140 // either STATUS_SUCCESS or STATUS_WRONG_VOLUME, exactly. 00141 // 00142 // If UdfVerifyVolume encountered an error during 00143 // processing, it will return that error. If we got 00144 // STATUS_WRONG_VOLUME from the verify, and our volume 00145 // is now mounted, commute the status to STATUS_SUCCESS. 00146 // 00147 00148 if ((Status == STATUS_WRONG_VOLUME) && 00149 (Vcb->VcbCondition == VcbMounted)) { 00150 00151 Status = STATUS_SUCCESS; 00152 } 00153 00154 // 00155 // Do a quick unprotected check here. The routine will do 00156 // a safe check. After here we can release the resource. 00157 // Note that if the volume really went away, we will be taking 00158 // the Reparse path. 00159 // 00160 00161 // 00162 // If the device might need to go away then call our dismount routine. 00163 // 00164 00165 if (((Vcb->VcbCondition == VcbNotMounted) || 00166 (Vcb->VcbCondition == VcbInvalid) || 00167 (Vcb->VcbCondition == VcbDismountInProgress)) && 00168 (Vcb->VcbReference <= Vcb->VcbResidualReference)) { 00169 00170 UdfAcquireUdfData( IrpContext ); 00171 UdfCheckForDismount( IrpContext, Vcb, FALSE ); 00172 UdfReleaseUdfData( IrpContext ); 00173 } 00174 00175 // 00176 // If this is a create and the verify succeeded then complete the 00177 // request with a REPARSE status. 00178 // 00179 00180 if ((IrpContext->MajorFunction == IRP_MJ_CREATE) && 00181 (IrpSp->FileObject->RelatedFileObject == NULL) && 00182 ((Status == STATUS_SUCCESS) || (Status == STATUS_WRONG_VOLUME))) { 00183 00184 Irp->IoStatus.Information = IO_REMOUNT; 00185 00186 UdfCompleteRequest( IrpContext, Irp, STATUS_REPARSE ); 00187 Status = STATUS_REPARSE; 00188 Irp = NULL; 00189 IrpContext = NULL; 00190 00191 // 00192 // If there is still an error to process then call the Io system 00193 // for a popup. 00194 // 00195 00196 } else if ((Irp != NULL) && !NT_SUCCESS( Status )) { 00197 00198 // 00199 // Fill in the device object if required. 00200 // 00201 00202 if (IoIsErrorUserInduced( Status ) ) { 00203 00204 IoSetHardErrorOrVerifyDevice( Irp, DeviceToVerify ); 00205 } 00206 00207 UdfNormalizeAndRaiseStatus( IrpContext, Status ); 00208 } 00209 } 00210 00211 // 00212 // If there is still an Irp, send it off to an Ex Worker thread. 00213 // 00214 00215 if (IrpContext != NULL) { 00216 00217 Status = UdfFsdPostRequest( IrpContext, Irp ); 00218 } 00219 00220 } except(UdfExceptionFilter( IrpContext, GetExceptionInformation() )) { 00221 00222 // 00223 // We had some trouble trying to perform the verify or raised 00224 // an error ourselves. So we'll abort the I/O request with 00225 // the error status that we get back from the execption code. 00226 // 00227 00228 Status = UdfProcessException( IrpContext, Irp, GetExceptionCode() ); 00229 } 00230 00231 return Status; 00232 }

VOID UdfPrePostIrp IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp
 

Definition at line 111 of file workque.c.

References ASSERT_IRP, ASSERT_IRP_CONTEXT, FALSE, FlagOn, IoGetCurrentIrpStackLocation, IoMarkIrpPending, Irp, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_MJ_CREATE, IRP_MJ_DIRECTORY_CONTROL, IRP_MJ_READ, IRP_MN_MDL, IRP_MN_QUERY_DIRECTORY, NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, SetFlag, TRUE, UdfCleanupIrpContext(), UdfLockUserBuffer, UdfReleaseFcb, and UdfTeardownStructures().

Referenced by UdfCommonRead(), UdfCompleteFcbOpen(), and UdfFsdPostRequest().

00118 : 00119 00120 This routine performs any neccessary work before STATUS_PENDING is 00121 returned with the Fsd thread. This routine is called within the 00122 filesystem and by the oplock package. 00123 00124 Arguments: 00125 00126 Context - Pointer to the IrpContext to be queued to the Fsp 00127 00128 Irp - I/O Request Packet. 00129 00130 Return Value: 00131 00132 None. 00133 00134 --*/ 00135 00136 { 00137 PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00138 BOOLEAN RemovedFcb; 00139 00140 PAGED_CODE(); 00141 00142 ASSERT_IRP_CONTEXT( IrpContext ); 00143 ASSERT_IRP( Irp ); 00144 00145 // 00146 // Case on the type of the operation. 00147 // 00148 00149 switch (IrpContext->MajorFunction) { 00150 00151 case IRP_MJ_CREATE : 00152 00153 // 00154 // If called from the oplock package then there is an 00155 // Fcb to possibly teardown. We will call the teardown 00156 // routine and release the Fcb if still present. The cleanup 00157 // code in create will know not to release this Fcb because 00158 // we will clear the pointer. 00159 // 00160 00161 if ((IrpContext->TeardownFcb != NULL) && 00162 *(IrpContext->TeardownFcb) != NULL) { 00163 00164 UdfTeardownStructures( IrpContext, *(IrpContext->TeardownFcb), FALSE, &RemovedFcb ); 00165 00166 if (!RemovedFcb) { 00167 00168 UdfReleaseFcb( IrpContext, *(IrpContext->TeardownFcb) ); 00169 } 00170 00171 *(IrpContext->TeardownFcb) = NULL; 00172 IrpContext->TeardownFcb = NULL; 00173 } 00174 00175 break; 00176 00177 // 00178 // We need to lock the user's buffer, unless this is an MDL-read, 00179 // in which case there is no user buffer. 00180 // 00181 00182 case IRP_MJ_READ : 00183 00184 if (!FlagOn( IrpContext->MinorFunction, IRP_MN_MDL )) { 00185 00186 UdfLockUserBuffer( IrpContext, IrpSp->Parameters.Read.Length ); 00187 } 00188 00189 break; 00190 00191 // 00192 // We also need to check whether this is a query file operation. 00193 // 00194 00195 case IRP_MJ_DIRECTORY_CONTROL : 00196 00197 if (IrpContext->MinorFunction == IRP_MN_QUERY_DIRECTORY) { 00198 00199 UdfLockUserBuffer( IrpContext, IrpSp->Parameters.QueryDirectory.Length ); 00200 } 00201 00202 break; 00203 } 00204 // 00205 // Cleanup the IrpContext for the post. 00206 // 00207 00208 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00209 UdfCleanupIrpContext( IrpContext, TRUE ); 00210 00211 // 00212 // Mark the Irp to show that we've already returned pending to the user. 00213 // 00214 00215 IoMarkIrpPending( Irp ); 00216 00217 return; 00218 }

NTSTATUS UdfProcessException IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PIRP  Irp,
IN NTSTATUS  ExceptionCode
 

Definition at line 539 of file udfdata.c.

References APC_LEVEL, ASSERT, ASSERT_IRP, ASSERT_OPTIONAL_IRP_CONTEXT, ClearFlag, FlagOn, IoGetCurrentIrpStackLocation, IoGetDeviceToVerify(), IoIsErrorUserInduced, IoMarkIrpPending, IoRaiseHardError(), IoSetDeviceToVerify(), _IRP::IoStatus, Irp, IRP_CONTEXT_FLAG_DISABLE_POPUPS, IRP_CONTEXT_FLAG_FORCE_POST, IRP_CONTEXT_FLAG_MORE_PROCESSING, IRP_CONTEXT_FLAG_TOP_LEVEL, NULL, PsGetCurrentThread, _IRP::Tail, UdfCompleteRequest(), UdfExceptionFilter(), UdfFsdPostRequest(), and UdfPerformVerify().

Referenced by UdfFsdDispatch(), UdfFspDispatch(), and UdfPerformVerify().

00547 : 00548 00549 This routine processes an exception. It either completes the request 00550 with the exception status in the IrpContext, sends this off to the Fsp 00551 workque or causes it to be retried in the current thread if a verification 00552 is needed. 00553 00554 If the volume needs to be verified (STATUS_VERIFY_REQUIRED) and we can 00555 do the work in the current thread we will translate the status code 00556 to STATUS_CANT_WAIT to indicate that we need to retry the request. 00557 00558 Arguments: 00559 00560 Irp - Supplies the Irp being processed 00561 00562 ExceptionCode - Supplies the normalized exception status being handled 00563 00564 Return Value: 00565 00566 NTSTATUS - Returns the results of either posting the Irp or the 00567 saved completion status. 00568 00569 --*/ 00570 00571 { 00572 PDEVICE_OBJECT Device; 00573 PVPB Vpb; 00574 PETHREAD Thread; 00575 00576 ASSERT_OPTIONAL_IRP_CONTEXT( IrpContext ); 00577 ASSERT_IRP( Irp ); 00578 00579 // 00580 // If there is not an irp context, then complete the request with the 00581 // current status code. 00582 // 00583 00584 if (!ARGUMENT_PRESENT( IrpContext )) { 00585 00586 UdfCompleteRequest( NULL, Irp, ExceptionCode ); 00587 return ExceptionCode; 00588 } 00589 00590 // 00591 // Get the real exception status from the IrpContext. 00592 // 00593 00594 ExceptionCode = IrpContext->ExceptionStatus; 00595 00596 // 00597 // If we are not a top level request then we just complete the request 00598 // with the current status code. 00599 // 00600 00601 if (!FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL )) { 00602 00603 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00604 00605 return ExceptionCode; 00606 } 00607 00608 // 00609 // Check if we are posting this request. One of the following must be true 00610 // if we are to post a request. 00611 // 00612 // - Status code is STATUS_CANT_WAIT and the request is asynchronous 00613 // or we are forcing this to be posted. 00614 // 00615 // - Status code is STATUS_VERIFY_REQUIRED and we are at APC level 00616 // or higher. Can't wait for IO in the verify path in this case. 00617 // 00618 // Set the MORE_PROCESSING flag in the IrpContext to keep if from being 00619 // deleted if this is a retryable condition. 00620 // 00621 // Note: Children of UdfFsdPostRequest() can raise. 00622 // 00623 00624 try { 00625 00626 if (ExceptionCode == STATUS_CANT_WAIT) { 00627 00628 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_FORCE_POST )) { 00629 00630 ExceptionCode = UdfFsdPostRequest( IrpContext, Irp ); 00631 } 00632 00633 } else if (ExceptionCode == STATUS_VERIFY_REQUIRED) { 00634 00635 if (KeGetCurrentIrql() >= APC_LEVEL) { 00636 00637 ExceptionCode = UdfFsdPostRequest( IrpContext, Irp ); 00638 } 00639 } 00640 } 00641 except (UdfExceptionFilter( IrpContext, GetExceptionInformation())) { 00642 00643 ExceptionCode = GetExceptionCode(); 00644 } 00645 00646 // 00647 // If we posted the request or our caller will retry then just return here. 00648 // 00649 00650 if ((ExceptionCode == STATUS_PENDING) || 00651 (ExceptionCode == STATUS_CANT_WAIT)) { 00652 00653 return ExceptionCode; 00654 } 00655 00656 ClearFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_MORE_PROCESSING ); 00657 00658 // 00659 // Store this error into the Irp for posting back to the Io system. 00660 // 00661 00662 Irp->IoStatus.Status = ExceptionCode; 00663 00664 if (IoIsErrorUserInduced( ExceptionCode )) { 00665 00666 // 00667 // Check for the various error conditions that can be caused by, 00668 // and possibly resolved my the user. 00669 // 00670 00671 if (ExceptionCode == STATUS_VERIFY_REQUIRED) { 00672 00673 // 00674 // Now we are at the top level file system entry point. 00675 // 00676 // If we have already posted this request then the device to 00677 // verify is in the original thread. Find this via the Irp. 00678 // 00679 00680 Device = IoGetDeviceToVerify( Irp->Tail.Overlay.Thread ); 00681 IoSetDeviceToVerify( Irp->Tail.Overlay.Thread, NULL ); 00682 00683 // 00684 // If there is no device in that location then check in the 00685 // current thread. 00686 // 00687 00688 if (Device == NULL) { 00689 00690 Device = IoGetDeviceToVerify( PsGetCurrentThread() ); 00691 IoSetDeviceToVerify( PsGetCurrentThread(), NULL ); 00692 00693 ASSERT( Device != NULL ); 00694 00695 // 00696 // Let's not BugCheck just because the driver screwed up. 00697 // 00698 00699 if (Device == NULL) { 00700 00701 ExceptionCode = STATUS_DRIVER_INTERNAL_ERROR; 00702 00703 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00704 00705 return ExceptionCode; 00706 } 00707 } 00708 00709 // 00710 // CdPerformVerify() will do the right thing with the Irp. 00711 // If we return STATUS_CANT_WAIT then the current thread 00712 // can retry the request. 00713 // 00714 00715 return UdfPerformVerify( IrpContext, Irp, Device ); 00716 } 00717 00718 // 00719 // The other user induced conditions generate an error unless 00720 // they have been disabled for this request. 00721 // 00722 00723 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_DISABLE_POPUPS )) { 00724 00725 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00726 00727 return ExceptionCode; 00728 00729 } else { 00730 00731 // 00732 // Generate a pop-up 00733 // 00734 00735 if (IoGetCurrentIrpStackLocation( Irp )->FileObject != NULL) { 00736 00737 Vpb = IoGetCurrentIrpStackLocation( Irp )->FileObject->Vpb; 00738 00739 } else { 00740 00741 Vpb = NULL; 00742 } 00743 00744 // 00745 // The device to verify is either in my thread local storage 00746 // or that of the thread that owns the Irp. 00747 // 00748 00749 Thread = Irp->Tail.Overlay.Thread; 00750 Device = IoGetDeviceToVerify( Thread ); 00751 00752 if (Device == NULL) { 00753 00754 Thread = PsGetCurrentThread(); 00755 Device = IoGetDeviceToVerify( Thread ); 00756 00757 ASSERT( Device != NULL ); 00758 00759 // 00760 // Let's not BugCheck just because the driver screwed up. 00761 // 00762 00763 if (Device == NULL) { 00764 00765 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00766 00767 return ExceptionCode; 00768 } 00769 } 00770 00771 // 00772 // This routine actually causes the pop-up. It usually 00773 // does this by queuing an APC to the callers thread, 00774 // but in some cases it will complete the request immediately, 00775 // so it is very important to IoMarkIrpPending() first. 00776 // 00777 00778 IoMarkIrpPending( Irp ); 00779 IoRaiseHardError( Irp, Vpb, Device ); 00780 00781 // 00782 // We will be handing control back to the caller here, so 00783 // reset the saved device object. 00784 // 00785 00786 IoSetDeviceToVerify( Thread, NULL ); 00787 00788 // 00789 // The Irp will be completed by Io or resubmitted. In either 00790 // case we must clean up the IrpContext here. 00791 // 00792 00793 UdfCompleteRequest( IrpContext, NULL, STATUS_SUCCESS ); 00794 return STATUS_PENDING; 00795 } 00796 } 00797 00798 // 00799 // This is just a run of the mill error. 00800 // 00801 00802 UdfCompleteRequest( IrpContext, Irp, ExceptionCode ); 00803 00804 return ExceptionCode; 00805 }

NTSTATUS UdfPurgeVolume IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN BOOLEAN  DismountUnderway
 

Definition at line 417 of file udfs/cachesup.c.

References CcPurgeCacheSection(), _SECTION_OBJECT_POINTERS::DataSectionObject, FALSE, _FCB::FcbNonpaged, _FCB::FcbReference, _SECTION_OBJECT_POINTERS::ImageSectionObject, MmFlushForWrite, MmFlushImageSection(), NTSTATUS(), NULL, PAGED_CODE, SafeNodeType, _FCB_NONPAGED::SegmentObject, Status, TRUE, UdfAcquireAllFiles, UdfDeleteInternalStream(), UdfFspClose(), UdfGetNextFcb(), UdfLockVcb, UdfReleaseAllFiles, UDFS_NTC_FCB_DATA, UdfTeardownStructures(), and UdfUnlockVcb.

Referenced by UdfCommonCleanup(), UdfCompleteFcbOpen(), UdfDismountVcb(), UdfInvalidateVolumes(), UdfLockVolumeInternal(), and UdfVerifyVolume().

00425 : 00426 00427 This routine is called to purge the volume. The purpose is to make all the stale file 00428 objects in the system go away, minimizing the reference counts, so that the volume may 00429 be locked or deleted. 00430 00431 The Vcb is already acquired exclusively. We will lock out all file operations by 00432 acquiring the global file resource. Then we will walk through all of the Fcb's and 00433 perform the purge. 00434 00435 Arguments: 00436 00437 Vcb - Vcb for the volume to purge. 00438 00439 DismountUnderway - Indicates that we are trying to delete all of the objects. 00440 We will purge the Metadata and VolumeDasd and dereference all internal streams. 00441 00442 Return Value: 00443 00444 NTSTATUS - The first failure of the purge operation. 00445 00446 --*/ 00447 00448 { 00449 NTSTATUS Status = STATUS_SUCCESS; 00450 00451 PVOID RestartKey = NULL; 00452 PFCB ThisFcb = NULL; 00453 PFCB NextFcb; 00454 00455 BOOLEAN RemovedFcb; 00456 00457 PAGED_CODE(); 00458 00459 // 00460 // Force any remaining Fcb's in the delayed close queue to be closed. 00461 // 00462 00463 UdfFspClose( Vcb ); 00464 00465 // 00466 // Acquire the global file resource. 00467 // 00468 00469 UdfAcquireAllFiles( IrpContext, Vcb ); 00470 00471 // 00472 // Loop through each Fcb in the Fcb Table and perform the flush. 00473 // 00474 00475 while (TRUE) { 00476 00477 // 00478 // Lock the Vcb to lookup the next Fcb. 00479 // 00480 00481 UdfLockVcb( IrpContext, Vcb ); 00482 NextFcb = UdfGetNextFcb( IrpContext, Vcb, &RestartKey ); 00483 00484 // 00485 // Reference the NextFcb if present. 00486 // 00487 00488 if (NextFcb != NULL) { 00489 00490 NextFcb->FcbReference += 1; 00491 } 00492 00493 // 00494 // If the last Fcb is present then decrement reference count and call teardown 00495 // to see if it should be removed. 00496 // 00497 00498 if (ThisFcb != NULL) { 00499 00500 ThisFcb->FcbReference -= 1; 00501 00502 UdfUnlockVcb( IrpContext, Vcb ); 00503 00504 UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb ); 00505 00506 } else { 00507 00508 UdfUnlockVcb( IrpContext, Vcb ); 00509 } 00510 00511 // 00512 // Break out of the loop if no more Fcb's. 00513 // 00514 00515 if (NextFcb == NULL) { 00516 00517 break; 00518 } 00519 00520 // 00521 // Move to the next Fcb. 00522 // 00523 00524 ThisFcb = NextFcb; 00525 00526 // 00527 // If there is a image section then see if that can be closed. 00528 // 00529 00530 if (ThisFcb->FcbNonpaged->SegmentObject.ImageSectionObject != NULL) { 00531 00532 MmFlushImageSection( &ThisFcb->FcbNonpaged->SegmentObject, MmFlushForWrite ); 00533 } 00534 00535 // 00536 // If there is a data section then purge this. If there is an image 00537 // section then we won't be able to. Remember this if it is our first 00538 // error. 00539 // 00540 00541 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && 00542 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, 00543 NULL, 00544 0, 00545 FALSE ) && 00546 (Status == STATUS_SUCCESS)) { 00547 00548 Status = STATUS_UNABLE_TO_DELETE_SECTION; 00549 } 00550 00551 // 00552 // Dereference the internal stream if dismounting. 00553 // 00554 00555 if (DismountUnderway && 00556 (SafeNodeType( ThisFcb ) != UDFS_NTC_FCB_DATA) && 00557 (ThisFcb->FileObject != NULL)) { 00558 00559 UdfDeleteInternalStream( IrpContext, ThisFcb ); 00560 } 00561 } 00562 00563 // 00564 // Now look at the Root Index, Metadata, Volume Dasd and VAT Fcbs. 00565 // Note that we usually hit the Root Index in the loop above, but 00566 // it is possible miss it if it didn't get into the Fcb table in the 00567 // first place! 00568 // 00569 00570 if (DismountUnderway) { 00571 00572 if (Vcb->RootIndexFcb != NULL) { 00573 00574 ThisFcb = Vcb->RootIndexFcb; 00575 InterlockedIncrement( &ThisFcb->FcbReference ); 00576 00577 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && 00578 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, 00579 NULL, 00580 0, 00581 FALSE ) && 00582 (Status == STATUS_SUCCESS)) { 00583 00584 Status = STATUS_UNABLE_TO_DELETE_SECTION; 00585 } 00586 00587 UdfDeleteInternalStream( IrpContext, ThisFcb ); 00588 InterlockedDecrement( &ThisFcb->FcbReference ); 00589 UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb ); 00590 } 00591 00592 if (Vcb->MetadataFcb != NULL) { 00593 00594 ThisFcb = Vcb->MetadataFcb; 00595 InterlockedIncrement( &ThisFcb->FcbReference ); 00596 00597 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && 00598 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, 00599 NULL, 00600 0, 00601 FALSE ) && 00602 (Status == STATUS_SUCCESS)) { 00603 00604 Status = STATUS_UNABLE_TO_DELETE_SECTION; 00605 } 00606 00607 UdfDeleteInternalStream( IrpContext, ThisFcb ); 00608 InterlockedDecrement( &ThisFcb->FcbReference ); 00609 UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb ); 00610 } 00611 00612 if (Vcb->VatFcb != NULL) { 00613 00614 ThisFcb = Vcb->VatFcb; 00615 InterlockedIncrement( &ThisFcb->FcbReference ); 00616 00617 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && 00618 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, 00619 NULL, 00620 0, 00621 FALSE ) && 00622 (Status == STATUS_SUCCESS)) { 00623 00624 Status = STATUS_UNABLE_TO_DELETE_SECTION; 00625 } 00626 00627 UdfDeleteInternalStream( IrpContext, ThisFcb ); 00628 InterlockedDecrement( &ThisFcb->FcbReference ); 00629 UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb ); 00630 } 00631 00632 if (Vcb->VolumeDasdFcb != NULL) { 00633 00634 ThisFcb = Vcb->VolumeDasdFcb; 00635 InterlockedIncrement( &ThisFcb->FcbReference ); 00636 00637 if ((ThisFcb->FcbNonpaged->SegmentObject.DataSectionObject != NULL) && 00638 !CcPurgeCacheSection( &ThisFcb->FcbNonpaged->SegmentObject, 00639 NULL, 00640 0, 00641 FALSE ) && 00642 (Status == STATUS_SUCCESS)) { 00643 00644 Status = STATUS_UNABLE_TO_DELETE_SECTION; 00645 } 00646 00647 InterlockedDecrement( &ThisFcb->FcbReference ); 00648 UdfTeardownStructures( IrpContext, ThisFcb, FALSE, &RemovedFcb ); 00649 } 00650 } 00651 00652 // 00653 // Release all of the files. 00654 // 00655 00656 UdfReleaseAllFiles( IrpContext, Vcb ); 00657 00658 return Status; 00659 }

INLINE DECLSPEC_NORETURN VOID UdfRaiseStatus IN PIRP_CONTEXT  IrpContext,
IN NTSTATUS  Status
 

Definition at line 406 of file udfprocs.h.

References DebugBreakOnStatus, ExRaiseStatus(), and Status.

Referenced by UdfAcquireResource(), UdfCheckLegalCS0Dstring(), UdfCommonCreate(), UdfCommonRead(), UdfCompleteFcbOpen(), UdfCreateFileLock(), UdfCreateInternalStream(), UdfCreateUserMdl(), UdfDetermineVolumeBounding(), UdfFindPrefix(), UdfGetNextAllocationPostProcessing(), UdfInitializeAllocationContext(), UdfInitializeAllocations(), UdfInitializeEnumeration(), UdfInitializeFcbFromIcbContext(), UdfInitializeIcbContextFromFcb(), UdfInsertPrefix(), UdfLookupActiveIcb(), UdfLookupActiveIcbInExtent(), UdfLookupDirEntryPostProcessing(), UdfLookupEa(), UdfLookupFileEntryInEnumeration(), UdfLookupMetaVsnOfExtent(), UdfLookupPsnOfExtent(), UdfMultipleAsync(), UdfNonCachedRead(), UdfOpenObjectByFileId(), UdfPrepareBuffers(), UdfReadSectors(), UdfUpdateDirNames(), UdfUpdateVcbPhase0(), UdfVerifyDescriptor(), UdfVerifyFcbOperation(), and UdfVerifyVcb().

00410 { 00411 IrpContext->ExceptionStatus = Status; 00412 DebugBreakOnStatus( Status ); 00413 ExRaiseStatus( Status ); 00414 }

INLINE ULONG UdfRawBufferSize IN PVCB  Vcb,
IN ULONG  StructureSize
 

Definition at line 931 of file udfprocs.h.

References ROUND_TO_PAGES, and SectorAlign.

Referenced by UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), and UdfUpdateVcbPhase0().

00935 { 00936 return (ULONG)ROUND_TO_PAGES( SectorAlign( Vcb, StructureSize )); 00937 }

INLINE ULONG UdfRawBufferSizeN IN ULONG  SectorSize,
IN ULONG  StructureSize
 

Definition at line 951 of file udfprocs.h.

References ROUND_TO_PAGES, SectorAlignN, and SectorSize.

Referenced by UdfRecognizeVolume().

00955 { 00956 return (ULONG)ROUND_TO_PAGES( SectorAlignN( SectorSize, StructureSize )); 00957 }

INLINE ULONG UdfRawReadSize IN PVCB  Vcb,
IN ULONG  StructureSize
 

Definition at line 941 of file udfprocs.h.

References SectorAlign.

Referenced by UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), and UdfUpdateVcbPhase0().

00945 { 00946 return SectorAlign( Vcb, StructureSize ); 00947 }

INLINE ULONG UdfRawReadSizeN IN ULONG  SectorSize,
IN ULONG  StructureSize
 

Definition at line 961 of file udfprocs.h.

References SectorAlignN, and SectorSize.

Referenced by UdfRecognizeVolume().

00965 { 00966 return SectorAlignN( SectorSize, StructureSize ); 00967 }

NTSTATUS UdfReadSectors IN PIRP_CONTEXT  IrpContext,
IN LONGLONG  StartingOffset,
IN ULONG  ByteCount,
IN BOOLEAN  ReturnError,
IN OUT PVOID  Buffer,
IN PDEVICE_OBJECT  TargetDeviceObject
 

Definition at line 685 of file deviosup.c.

References ASSERT, Buffer, BytesFromSectors, Dbg, DebugTrace, Event(), Executive, FALSE, FlagOn, FsRtlLookupLargeMcbEntry(), IoBuildSynchronousFsdRequest(), IoCallDriver, IoGetNextIrpStackLocation, Irp, IRP_MJ_READ, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), LlSectorsFromBytes, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, SectorSize, SetFlag, SL_OVERRIDE_VERIFY_VOLUME, Status, UdfMethod2TransformByteOffset, UdfNormalizeAndRaiseStatus(), UdfRaiseStatus(), and VCB_STATE_METHOD_2_FIXUP.

Referenced by UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfLoadSparingTables(), UdfRecognizeVolume(), and UdfUpdateVcbPhase0().

00696 : 00697 00698 This routine is called to transfer sectors from the disk to a 00699 specified buffer. It is used for mount and volume verify operations. 00700 00701 This routine is synchronous, it will not return until the operation 00702 is complete or until the operation fails. 00703 00704 The routine allocates an IRP and then passes this IRP to a lower 00705 level driver. Errors may occur in the allocation of this IRP or 00706 in the operation of the lower driver. 00707 00708 Arguments: 00709 00710 StartingOffset - Logical offset on the disk to start the read. This 00711 must be on a sector boundary, no check is made here. 00712 00713 ByteCount - Number of bytes to read. This is an integral number of 00714 sectors, or otherwise a value we know the driver can handle, 00715 no check is made here to confirm this. 00716 00717 ReturnError - Indicates whether we should return TRUE or FALSE 00718 to indicate an error or raise an error condition. This only applies 00719 to the result of the IO. Any other error may cause a raise. 00720 00721 Buffer - Buffer to transfer the disk data into. 00722 00723 TargetDeviceObject - The device object for the volume to be read. 00724 00725 Return Value: 00726 00727 The final status of the operation. 00728 00729 --*/ 00730 00731 { 00732 PLONGLONG UseStartingOffset; 00733 LONGLONG LocalStartingOffset; 00734 NTSTATUS Status; 00735 KEVENT Event; 00736 PIRP Irp; 00737 00738 PAGED_CODE(); 00739 00740 DebugTrace(( +1, Dbg, 00741 "UdfReadSectors, %x%08x +%x -> %08x from DO %08x\n", 00742 ((PLARGE_INTEGER)&StartingOffset)->HighPart, 00743 ((PLARGE_INTEGER)&StartingOffset)->LowPart, 00744 ByteCount, 00745 Buffer, 00746 TargetDeviceObject )); 00747 00748 // 00749 // For the time being, we assume that we only read sector-at-a-time. 00750 // This simplifies sparing, and is the only way I am aware of this 00751 // code would not be ready for blocksize != sectorsize. It just is 00752 // not worth writing dead (but straightforward) code right now. 00753 // 00754 00755 ASSERT( IrpContext->Vcb == NULL || ByteCount == SectorSize( IrpContext->Vcb )); 00756 00757 // 00758 // If the volume is spared (and at a point where sparing is possible), 00759 // check if a mapping needs to be performed. 00760 // 00761 00762 if (IrpContext->Vcb && 00763 IrpContext->Vcb->Pcb && 00764 IrpContext->Vcb->Pcb->SparingMcb) { 00765 00766 LONGLONG SparingPsn; 00767 00768 if (FsRtlLookupLargeMcbEntry( IrpContext->Vcb->Pcb->SparingMcb, 00769 LlSectorsFromBytes( IrpContext->Vcb, StartingOffset ), 00770 &SparingPsn, 00771 NULL, 00772 NULL, 00773 NULL, 00774 NULL ) && 00775 SparingPsn != -1) { 00776 00777 StartingOffset = BytesFromSectors( IrpContext->Vcb, (ULONG) SparingPsn ); 00778 } 00779 } 00780 00781 // 00782 // Initialize the event. 00783 // 00784 00785 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 00786 00787 // 00788 // Correct the starting offset by the method 2 fixup if neccesary. This also 00789 // assumes sector-at-a-time and sector == block so we don't need to fragment 00790 // the request or check if it spans a packet boundary. 00791 // 00792 // We assume that no fixups are required until a Vcb exists. This is true 00793 // since volume recognition may proceed in the first packet. 00794 // 00795 00796 UseStartingOffset = &StartingOffset; 00797 00798 if (IrpContext->Vcb && 00799 FlagOn( IrpContext->Vcb->VcbState, VCB_STATE_METHOD_2_FIXUP )) { 00800 00801 LocalStartingOffset = UdfMethod2TransformByteOffset( IrpContext->Vcb, StartingOffset ); 00802 UseStartingOffset = &LocalStartingOffset; 00803 00804 DebugTrace(( 0, Dbg, 00805 "UdfReadSectors, Method2 Fixup to %x%08x\n", 00806 ((PLARGE_INTEGER)UseStartingOffset)->HighPart, 00807 ((PLARGE_INTEGER)UseStartingOffset)->LowPart )); 00808 } 00809 00810 // 00811 // Attempt to allocate the IRP. If unsuccessful, raise 00812 // STATUS_INSUFFICIENT_RESOURCES. 00813 // 00814 00815 Irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, 00816 TargetDeviceObject, 00817 Buffer, 00818 ByteCount, 00819 (PLARGE_INTEGER) UseStartingOffset, 00820 &Event, 00821 &IrpContext->Irp->IoStatus ); 00822 00823 if (Irp == NULL) { 00824 00825 UdfRaiseStatus( IrpContext, STATUS_INSUFFICIENT_RESOURCES ); 00826 } 00827 00828 // 00829 // Ignore the change line (verify) for mount and verify requests 00830 // 00831 00832 SetFlag( IoGetNextIrpStackLocation( Irp )->Flags, SL_OVERRIDE_VERIFY_VOLUME ); 00833 00834 // 00835 // Send the request down to the driver. If an error occurs return 00836 // it to the caller. 00837 // 00838 00839 Status = IoCallDriver( TargetDeviceObject, Irp ); 00840 00841 // 00842 // If the status was STATUS_PENDING then wait on the event. 00843 // 00844 00845 if (Status == STATUS_PENDING) { 00846 00847 Status = KeWaitForSingleObject( &Event, 00848 Executive, 00849 KernelMode, 00850 FALSE, 00851 NULL ); 00852 00853 // 00854 // On a successful wait pull the status out of the IoStatus block. 00855 // 00856 00857 if (NT_SUCCESS( Status )) { 00858 00859 Status = IrpContext->Irp->IoStatus.Status; 00860 } 00861 } 00862 00863 DebugTrace(( -1, Dbg, "UdfReadSectors -> %08x\n", Status )); 00864 00865 // 00866 // Check whether we should raise in the error case. 00867 // 00868 00869 if (!NT_SUCCESS( Status ) && !ReturnError) { 00870 00871 UdfNormalizeAndRaiseStatus( IrpContext, Status ); 00872 } 00873 00874 return Status; 00875 }

VOID UdfReleaseForCreateSection IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 302 of file resrcsup.c.

References ExReleaseResource, and PAGED_CODE.

Referenced by UdfInitializeGlobalData().

00308 : 00309 00310 This is the callback routine for MM to use to release a file acquired with 00311 the AcquireForCreateSection call above. 00312 00313 Arguments: 00314 00315 FileObject - File object for a Udffs stream. 00316 00317 Return Value: 00318 00319 None 00320 00321 --*/ 00322 00323 { 00324 PAGED_CODE(); 00325 00326 // 00327 // Release the resource in the Fcb. 00328 // 00329 00330 ExReleaseResource( &((PFCB) FileObject->FsContext)->FcbNonpaged->FcbResource ); 00331 00332 return; 00333 } }

VOID UdfReleaseFromCache IN PFCB  Fcb  ) 
 

Definition at line 172 of file resrcsup.c.

References ASSERT, ExReleaseResource, FSRTL_CACHE_TOP_LEVEL_IRP, IoGetTopLevelIrp(), IoSetTopLevelIrp(), NULL, and PAGED_CODE.

Referenced by UdfInitializeGlobalData().

00178 : 00179 00180 The address of this routine is specified when creating a CacheMap for 00181 a virtual file. It is subsequently called by the Lazy Writer to release 00182 a resource acquired above. 00183 00184 Arguments: 00185 00186 Fcb - The pointer supplied as context to the cache initialization 00187 routine. 00188 00189 Return Value: 00190 00191 None 00192 00193 --*/ 00194 00195 { 00196 PAGED_CODE(); 00197 00198 ASSERT(IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); 00199 IoSetTopLevelIrp( NULL ); 00200 00201 ExReleaseResource( Fcb->Resource ); 00202 00203 return; 00204 }

VOID UdfRemovePrefix IN PIRP_CONTEXT  IrpContext,
IN PLCB  Lcb
 

Definition at line 256 of file prefxsup.c.

References ASSERT_EXCLUSIVE_FCB_OR_VCB, ASSERT_IRP_CONTEXT, ASSERT_LCB, ExFreePool(), ExFreeToPagedLookasideList(), FlagOn, LCB_FLAG_IGNORE_CASE, LCB_FLAG_POOL_ALLOCATED, PAGED_CODE, RtlDelete(), and UdfLcbLookasideList.

Referenced by UdfTeardownStructures().

00263 : 00264 00265 This routine is called to remove a given prefix of an Fcb. 00266 00267 Arguments: 00268 00269 Lcb - the prefix being removed. 00270 00271 Return Value: 00272 00273 None 00274 00275 --*/ 00276 00277 { 00278 PAGED_CODE(); 00279 00280 // 00281 // Check inputs. 00282 // 00283 00284 ASSERT_IRP_CONTEXT( IrpContext ); 00285 ASSERT_LCB( Lcb ); 00286 00287 // 00288 // Check the acquisition of the two Fcbs. 00289 // 00290 00291 ASSERT_EXCLUSIVE_FCB_OR_VCB( Lcb->ParentFcb ); 00292 ASSERT_EXCLUSIVE_FCB_OR_VCB( Lcb->ChildFcb ); 00293 00294 // 00295 // Now remove the linkage and delete the Lcb. 00296 // 00297 00298 RemoveEntryList( &Lcb->ParentFcbLinks ); 00299 RemoveEntryList( &Lcb->ChildFcbLinks ); 00300 00301 if (FlagOn( Lcb->Flags, LCB_FLAG_IGNORE_CASE )) { 00302 00303 Lcb->ParentFcb->IgnoreCaseRoot = RtlDelete( &Lcb->Links ); 00304 00305 } else { 00306 00307 Lcb->ParentFcb->ExactCaseRoot = RtlDelete( &Lcb->Links ); 00308 } 00309 00310 if (FlagOn( Lcb->Flags, LCB_FLAG_POOL_ALLOCATED )) { 00311 00312 ExFreePool( Lcb ); 00313 00314 } else { 00315 00316 ExFreeToPagedLookasideList( &UdfLcbLookasideList, Lcb ); 00317 } 00318 00319 return; 00320 }

VOID UdfRemoveVmcbMapping IN PVMCB  Vmcb,
IN LBN  Lbn,
IN ULONG  SectorCount
 

VOID UdfRenderNameToLegalUnicode IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  Name,
IN PUNICODE_STRING  RenderedName
 

Definition at line 927 of file namesup.c.

References ASSERT, CRC_LEN, CRC_MARK, EXT_LEN, FALSE, ILLEGAL_CHAR_MARK, INT16, IsDeviceName, IsFileNameCharLegal, MAX_LEN, Name, NativeCharLength, PERIOD, SPACE, TRUE, UdfComputeCrc16Uni(), UdfCrcChar, UINT16, UNICODE_CHAR, and USHORT.

Referenced by UdfUpdateDirNames().

00935 : 00936 00937 This routine will take a Unicode string containing illegal characters and 00938 run it through the UDF standard algorithim to render it into a "legal" 00939 name. 00940 00941 The short form is to convert all runs of illegal characters to "_" and tack 00942 on a hex representation of the CRC of the original name. The algorithm is 00943 nearly directly lifted from the UDF (2.01 proposed!) standard, so apologies 00944 for the style clash. 00945 00946 Arguments: 00947 00948 Name - the actual name 00949 00950 RenderedName - the name rendered into legal characters 00951 00952 Return Value: 00953 00954 BOOLEAN - TRUE if the expressions match, FALSE otherwise. 00955 00956 --*/ 00957 00958 { 00959 INT16 index; 00960 INT16 targetIndex; 00961 INT16 crcIndex; 00962 INT16 extLen; 00963 INT16 nameLen; 00964 INT16 charLen; 00965 INT16 overlayBytes; 00966 INT16 bytesLeft; 00967 UNICODE_CHAR current; 00968 BOOLEAN needsCRC; 00969 BOOLEAN foundDot; 00970 UNICODE_CHAR ext[EXT_LEN]; 00971 00972 // 00973 // So as to lift as directly as possible from the standard, chunk things around. 00974 // 00975 00976 PWCHAR newName = RenderedName->Buffer; 00977 PWCHAR udfName = Name->Buffer; 00978 LONG udfNameLen = Name->Length / sizeof(WCHAR); 00979 00980 /* Remove trailing periods ('.') and spaces (' '), Windows */ 00981 /* does not like them. */ 00982 foundDot = FALSE; 00983 index = udfNameLen; 00984 while (index-- > 0) { 00985 if (udfName[index] == PERIOD) 00986 foundDot = TRUE; 00987 else if (udfName[index] != SPACE) 00988 break; 00989 } 00990 00991 /* If any trailing periods or spaces were found, a CRC code */ 00992 /* needs to be added to the resulting file name. */ 00993 nameLen = index + 1; 00994 if (nameLen < udfNameLen) 00995 needsCRC = TRUE; 00996 00997 needsCRC = FALSE; 00998 bytesLeft = MAX_LEN; 00999 extLen = 0; 01000 01001 if (needsCRC == FALSE || foundDot == FALSE) { 01002 /* Look for an extension in the file name. We do not */ 01003 /* need to look for one if there were any trailing periods */ 01004 /* removed. */ 01005 INT16 endIndex; 01006 INT16 prevCharLen = 1; 01007 INT16 extBytes = 0; 01008 01009 targetIndex = 0; 01010 index = nameLen; 01011 01012 /* Determine how many bytes we need to scan to find the */ 01013 /* extension delimiter. The extension has a maximum of */ 01014 /* five characters, but we do not want to scan past the */ 01015 /* beginning of the buffer. */ 01016 endIndex = (udfNameLen > EXT_LEN + 1) ? 01017 udfNameLen - EXT_LEN - 1 : 1; 01018 01019 /* Start at the end of the name and scan backward, looking */ 01020 /* for the extension delimiter ("."). */ 01021 while (index-- > endIndex) { 01022 /* Get the character to test. */ 01023 current = udfName[index]; 01024 01025 if (current == '.') { 01026 /* The extension delimiter was found, figure out */ 01027 /* how many characters the extension contains and */ 01028 /* the length of the resulting file name without */ 01029 /* the extension. */ 01030 extLen = nameLen - index - 1; 01031 nameLen = index; 01032 break; 01033 } 01034 01035 /* Determine the byte length of the current character */ 01036 /* when converted to native format. */ 01037 charLen = (IsFileNameCharLegal(current)) ? 01038 NativeCharLength(current) : 0; 01039 01040 if (charLen == 0) { 01041 /* If the character byte length is zero, it is */ 01042 /* illegal or unprintable, place an underscore */ 01043 /* ("_") in the extension buffer if the previous */ 01044 /* character tested was legal. Not that the */ 01045 /* characters placed in the extension buffer are */ 01046 /* in reverse order. */ 01047 if (prevCharLen != 0) { 01048 ext[targetIndex++] = ILLEGAL_CHAR_MARK; 01049 extBytes++; 01050 } 01051 } 01052 else { 01053 /* The current character is legal and printable, */ 01054 /* put it in the extension buffer. Note that the */ 01055 /* characters placed in the extension buffer are */ 01056 /* in reverse order. */ 01057 ext[targetIndex++] = current; 01058 extBytes += charLen; 01059 } 01060 01061 /* Save the byte length of the current character, so */ 01062 /* we can determine if it was a legal character during */ 01063 /* the next test. */ 01064 prevCharLen = charLen; 01065 } 01066 01067 /* If an extension was found, determine how many bytes */ 01068 /* remain in the file name buffer once we account for it. */ 01069 if (extLen > 0) 01070 bytesLeft -= extBytes + 1; 01071 } 01072 01073 index = 0; 01074 targetIndex = 0; 01075 crcIndex = 0; 01076 overlayBytes = -1; 01077 while (index < nameLen && bytesLeft > 0) { 01078 /* Get the current character and convert it to upper case. */ 01079 current = udfName[index]; 01080 01081 /* Determine if this is a valid file name char and */ 01082 /* calculate its corresponding native character byte */ 01083 /* length (zero if the char is not legal or undiplayable */ 01084 /* on this system). */ 01085 charLen = (IsFileNameCharLegal(current)) ? 01086 NativeCharLength(current) : 0; 01087 01088 /* If the char is larger than the available space in the */ 01089 /* buffer, pretend it is undisplayable. */ 01090 if (charLen > bytesLeft) 01091 charLen = 0; 01092 01093 if (charLen == 0) { 01094 /* Undisplayable or illegal characters are substituted */ 01095 /* with an underscore ("_"), and requires a CRC code */ 01096 /* appended to the mangled file name. */ 01097 needsCRC = TRUE; 01098 charLen = 1; 01099 current = '_'; 01100 01101 /* Skip over any following undiplayable or illegal */ 01102 /* chars. */ 01103 while (index + 1 < udfNameLen && 01104 (!IsFileNameCharLegal(udfName[index + 1]) || 01105 NativeCharLength(udfName[index + 1]) == 0)) 01106 index++; 01107 01108 /* Terminate loop if at the end of the file name. */ 01109 if (index >= udfNameLen) 01110 break; 01111 } 01112 01113 /* Assign the resulting char to the next index in the file */ 01114 /* name buffer and determine how many native bytes are */ 01115 /* left. */ 01116 newName[targetIndex++] = current; 01117 bytesLeft -= charLen; 01118 01119 /* This figures out where the CRC code needs to start in */ 01120 /* the file name buffer. */ 01121 if (bytesLeft >= CRC_LEN) { 01122 /* If there is enough space left, just tack it onto */ 01123 /* the end. */ 01124 crcIndex = targetIndex; 01125 } 01126 else { 01127 /* If there is not enough space left, the CRC must */ 01128 /* overlay a character already in the file name */ 01129 /* buffer. Once this condition has been met, the */ 01130 /* value will not change. */ 01131 if (overlayBytes < 0) { 01132 /* Determine the index and save the length of the */ 01133 /* native character that is overlayed. It is */ 01134 /* possible that the CRC might overlay half of a */ 01135 /* two-byte native character depending upon how */ 01136 /* the character boundaries line up. */ 01137 overlayBytes = (bytesLeft + charLen > CRC_LEN) 01138 ? 1 : 0; 01139 crcIndex = targetIndex - 1; 01140 } 01141 } 01142 01143 /* Advance to the next character. */ 01144 index++; 01145 } 01146 01147 /* If the scan did not reach the end of the file name, or the */ 01148 /* length of the file name is zero, a CRC code is needed. */ 01149 if (index < nameLen || index == 0) 01150 needsCRC = TRUE; 01151 01152 /* If the name has illegal characters or and extension, it */ 01153 /* is not a DOS device name. */ 01154 if (needsCRC == FALSE && extLen == 0) { 01155 /* If this is the name of a DOS device, a CRC code should */ 01156 /* be appended to the file name. */ 01157 if (IsDeviceName(udfName, udfNameLen)) 01158 needsCRC = TRUE; 01159 } 01160 01161 /* Append the CRC code to the file name, if needed. */ 01162 if (needsCRC) { 01163 /* Get the CRC value for the original Unicode string */ 01164 UINT16 udfCRCValue = UdfComputeCrc16Uni(udfName, udfNameLen); 01165 01166 /* Determine the character index where the CRC should */ 01167 /* begin. */ 01168 targetIndex = crcIndex; 01169 01170 /* If the character being overlayed is a two-byte native */ 01171 /* character, replace the first byte with an underscore. */ 01172 if (overlayBytes > 0) 01173 newName[targetIndex++] = ILLEGAL_CHAR_MARK; 01174 01175 /* Append the encoded CRC value with delimiter. */ 01176 newName[targetIndex++] = CRC_MARK; 01177 newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0xf000) >> 12]; 01178 newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x0f00) >> 8]; 01179 newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x00f0) >> 4]; 01180 newName[targetIndex++] = UdfCrcChar[(udfCRCValue & 0x000f)]; 01181 } 01182 01183 01184 /* If an extension was found, append it here. */ 01185 if (extLen > 0) { 01186 /* Add the period ('.') for the extension delimiter. */ 01187 newName[targetIndex++] = PERIOD; 01188 01189 /* Append the characters in the extension buffer. They */ 01190 /* were stored in reverse order, so we need to begin with */ 01191 /* the last character and work forward. */ 01192 while (extLen-- > 0) 01193 newName[targetIndex++] = ext[extLen]; 01194 } 01195 01196 ASSERT( (targetIndex * sizeof(WCHAR)) <= RenderedName->MaximumLength ); 01197 01198 RenderedName->Length = (USHORT) (targetIndex * sizeof(WCHAR)); 01199 }

VOID UdfResetVmcb IN PVMCB  Vmcb  ) 
 

Definition at line 370 of file vmcbsup.c.

References Dbg, DebugTrace, FsRtlResetLargeMcb(), PAGED_CODE, PLARGE_MCB, and TRUE.

Referenced by UdfUpdateVcbPhase0().

00376 : 00377 00378 This routine resets the mappings in an existing VMCB structure. 00379 00380 Arguments: 00381 00382 Vmcb - Supplies a pointer to the VMCB structure to reset. 00383 00384 Return Value: 00385 00386 None. 00387 00388 --*/ 00389 00390 { 00391 PAGED_CODE(); 00392 00393 DebugTrace(( +1, Dbg, "UdfResetVmcb, Vmcb = %08x\n", Vmcb )); 00394 00395 // 00396 // Unitialize the fields in the Vmcb structure 00397 // 00398 00399 FsRtlResetLargeMcb( (PLARGE_MCB) &Vmcb->VbnIndexed, TRUE ); 00400 FsRtlResetLargeMcb( (PLARGE_MCB) &Vmcb->LbnIndexed, TRUE ); 00401 00402 // 00403 // And return to our caller 00404 // 00405 00406 DebugTrace(( -1, Dbg, "UdfResetVmcb -> VOID\n" )); 00407 00408 return; 00409 }

INLINE VOID UdfRestoreThreadContext IN PIRP_CONTEXT  IrpContext  ) 
 

Definition at line 543 of file udfprocs.h.

References IoSetTopLevelIrp(), and NULL.

Referenced by UdfCleanupIrpContext().

00546 { 00547 IrpContext->ThreadContext->Udfs = 0; 00548 IoSetTopLevelIrp( IrpContext->ThreadContext->SavedTopLevelIrp ); 00549 IrpContext->ThreadContext = NULL; 00550 }

ULONG UdfSerial32 IN PCHAR  Buffer,
IN ULONG  ByteCount
 

Definition at line 1022 of file udfdata.c.

References Buffer, PAGED_CODE, and SerialId.

Referenced by UdfUpdateVolumeSerialNumber().

01029 : 01030 01031 This routine is called to generate a 32 bit serial number. This is 01032 done by doing four separate checksums into an array of bytes and 01033 then treating the bytes as a ULONG. 01034 01035 Arguments: 01036 01037 Buffer - Pointer to the buffer to generate the ID for. 01038 01039 ByteCount - Number of bytes in the buffer. 01040 01041 Return Value: 01042 01043 ULONG - The 32 bit serial number. 01044 01045 --*/ 01046 01047 { 01048 union { 01049 UCHAR Bytes[4]; 01050 ULONG SerialId; 01051 } Checksum; 01052 01053 PAGED_CODE(); 01054 01055 // 01056 // Initialize the serial number. 01057 // 01058 01059 Checksum.SerialId = 0; 01060 01061 // 01062 // Continue while there are more bytes to use. 01063 // 01064 01065 while (ByteCount--) { 01066 01067 // 01068 // Increment this sub-checksum. 01069 // 01070 01071 Checksum.Bytes[ByteCount & 0x3] += *(Buffer++); 01072 } 01073 01074 // 01075 // Return the checksums as a ULONG. 01076 // 01077 01078 return Checksum.SerialId; 01079 }

VOID UdfSetFileObject IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  FileObject,
IN TYPE_OF_OPEN  TypeOfOpen,
IN PFCB Fcb  OPTIONAL,
IN PCCB Ccb  OPTIONAL
 

Definition at line 49 of file filobsup.c.

References ASSERTMSG, BeyondValidType, FlagOn, NULL, PAGED_CODE, SetFlag, TYPE_OF_OPEN_MASK, and UnopenedFileObject.

Referenced by UdfCompleteFcbOpen(), and UdfCreateInternalStream().

00059 : 00060 00061 This routine will initialize the FileObject context fields based on the 00062 input type and data structures. 00063 00064 Arguments: 00065 00066 FileObject - Supplies the file object pointer being initialized. 00067 00068 TypeOfOpen - Sets the type of open. 00069 00070 Fcb - Fcb for this file object. Ignored for UnopenedFileObject. 00071 00072 Ccb - Ccb for the handle corresponding to this file object. Will not 00073 be present for stream file objects. 00074 00075 Return Value: 00076 00077 None. 00078 00079 --*/ 00080 00081 { 00082 PAGED_CODE(); 00083 00084 // 00085 // We only have values 0 to 7 available so make sure we didn't 00086 // inadvertantly add a new type. 00087 // 00088 00089 ASSERTMSG( "FileObject types exceed available bits\n", BeyondValidType <= 8 ); 00090 00091 // 00092 // Setting a file object to type UnopenedFileObject means just 00093 // clearing all of the context fields. All the other input 00094 // 00095 00096 if (TypeOfOpen == UnopenedFileObject) { 00097 00098 FileObject->FsContext = 00099 FileObject->FsContext2 = NULL; 00100 00101 return; 00102 } 00103 00104 // 00105 // Check that the 3 low-order bits of the Ccb are clear. 00106 // 00107 00108 ASSERTMSG( "Ccb is not quad-aligned\n", !FlagOn( ((ULONG_PTR) Ccb), TYPE_OF_OPEN_MASK )); 00109 00110 // 00111 // We will or the type of open into the low order bits of FsContext2 00112 // along with the Ccb value. 00113 // The Fcb is stored into the FsContext field. 00114 // 00115 00116 FileObject->FsContext = Fcb; 00117 FileObject->FsContext2 = Ccb; 00118 00119 SetFlag( ((ULONG_PTR) FileObject->FsContext2), TypeOfOpen ); 00120 00121 // 00122 // Set the Vpb field in the file object. 00123 // 00124 00125 FileObject->Vpb = Fcb->Vcb->Vpb; 00126 00127 return; 00128 }

VOID UdfSetMaximumLbnVmcb IN PVMCB  Vmcb,
IN ULONG  MaximumLbn
 

Definition at line 413 of file vmcbsup.c.

References Dbg, DebugTrace, and PAGED_CODE.

00420 : 00421 00422 This routine sets/resets the maximum allowed LBN for the specified 00423 Vmcb structure. The Vmcb structure must already have been initialized 00424 by calling UdfInitializeVmcb. 00425 00426 Arguments: 00427 00428 Vmcb - Supplies a pointer to the volume file structure to initialize. 00429 00430 MaximumLbn - Supplies the maximum Lbn value that is valid for this 00431 volume. 00432 00433 Return Value: 00434 00435 None 00436 00437 --*/ 00438 00439 { 00440 PAGED_CODE(); 00441 00442 DebugTrace(( +1, Dbg, "UdfSetMaximumLbnVmcb, Vmcb = %08x\n", Vmcb )); 00443 00444 // 00445 // Set the field 00446 // 00447 00448 Vmcb->MaximumLbn = MaximumLbn; 00449 00450 // 00451 // And return to our caller 00452 // 00453 00454 DebugTrace(( -1, Dbg, "UdfSetMaximumLbnVmcb -> VOID\n" )); 00455 00456 return; 00457 }

VOID UdfSetThreadContext IN PIRP_CONTEXT  IrpContext,
IN PTHREAD_CONTEXT  ThreadContext
 

Definition at line 873 of file udfdata.c.

References ASSERT_IRP_CONTEXT, FlagOn, IoGetStackLimits(), IoGetTopLevelIrp(), IoSetTopLevelIrp(), IRP_CONTEXT_FLAG_TOP_LEVEL, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS, LongOffsetPtr, NULL, PAGED_CODE, PTHREAD_CONTEXT, SetFlag, ThreadContext, _THREAD_CONTEXT::TopLevelIrpContext, _THREAD_CONTEXT::Udfs, and UDFS_SIGNATURE.

Referenced by UdfFsdDispatch(), UdfFspClose(), and UdfFspDispatch().

00880 : 00881 00882 This routine is called at each Fsd/Fsp entry point set up the IrpContext 00883 and thread local storage to track top level requests. If there is 00884 not a Udfs context in the thread local storage then we use the input one. 00885 Otherwise we use the one already there. This routine also updates the 00886 IrpContext based on the state of the top-level context. 00887 00888 If the TOP_LEVEL flag in the IrpContext is already set when we are called 00889 then we force this request to appear top level. 00890 00891 Arguments: 00892 00893 ThreadContext - Address on stack for local storage if not already present. 00894 00895 ForceTopLevel - We force this request to appear top level regardless of 00896 any previous stack value. 00897 00898 Return Value: 00899 00900 None 00901 00902 --*/ 00903 00904 { 00905 PTHREAD_CONTEXT CurrentThreadContext; 00906 ULONG_PTR StackTop; 00907 ULONG_PTR StackBottom; 00908 00909 PAGED_CODE(); 00910 00911 ASSERT_IRP_CONTEXT( IrpContext ); 00912 00913 // 00914 // Get the current top-level irp out of the thread storage. 00915 // If NULL then this is the top-level request. 00916 // 00917 00918 CurrentThreadContext = (PTHREAD_CONTEXT) IoGetTopLevelIrp(); 00919 00920 if (CurrentThreadContext == NULL) { 00921 00922 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ); 00923 } 00924 00925 // 00926 // Initialize the input context unless we are using the current 00927 // thread context block. We use the new block if our caller 00928 // specified this or the existing block is invalid. 00929 // 00930 // The following must be true for the current to be a valid Udfs context. 00931 // 00932 // Structure must lie within current stack. 00933 // Address must be ULONG aligned. 00934 // Udfs signature must be present. 00935 // 00936 // If this is not a valid Udfs context then use the input thread 00937 // context and store it in the top level context. 00938 // 00939 00940 IoGetStackLimits( &StackTop, &StackBottom); 00941 00942 if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) || 00943 (((ULONG_PTR) CurrentThreadContext > StackBottom - sizeof( THREAD_CONTEXT )) || 00944 ((ULONG_PTR) CurrentThreadContext <= StackTop) || 00945 LongOffsetPtr( CurrentThreadContext ) || 00946 (CurrentThreadContext->Udfs != UDFS_SIGNATURE))) { 00947 00948 ThreadContext->Udfs = UDFS_SIGNATURE; 00949 ThreadContext->SavedTopLevelIrp = (PIRP) CurrentThreadContext; 00950 ThreadContext->TopLevelIrpContext = IrpContext; 00951 IoSetTopLevelIrp( (PIRP) ThreadContext ); 00952 00953 IrpContext->TopLevel = IrpContext; 00954 IrpContext->ThreadContext = ThreadContext; 00955 00956 SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS ); 00957 00958 // 00959 // Otherwise use the IrpContext in the thread context. 00960 // 00961 00962 } else { 00963 00964 IrpContext->TopLevel = CurrentThreadContext->TopLevelIrpContext; 00965 } 00966 00967 return; 00968 }

VOID UdfStoreVolumeDescriptorIfPrevailing IN OUT PNSR_VD_GENERIC StoredVD,
IN OUT PNSR_VD_GENERIC  NewVD
 

Definition at line 235 of file udfs/fsctrl.c.

References FsRtlAllocatePoolWithTag, NULL, TAG_NSR_VDSD, and UdfNonPagedPool.

Referenced by UdfAddToPcb(), and UdfFindVolumeDescriptors().

00242 : 00243 00244 This routine updates Volume Descriptor if the new descriptor 00245 is more prevailing than the one currently stored. 00246 00247 Arguments: 00248 00249 StoredVD - pointer to a currently stored descriptor 00250 00251 NewVD - pointer to a candidate descriptor 00252 00253 Return Value: 00254 00255 None. 00256 00257 --*/ 00258 00259 { 00260 PNSR_VD_GENERIC TempVD; 00261 00262 // 00263 // If we haven't stored a volume descriptor or the sequence number 00264 // of the stored descriptor is less than the new descriptor, make a copy 00265 // of it and store it. 00266 // 00267 00268 if ((NULL == *StoredVD) || ((*StoredVD)->Sequence < NewVD->Sequence)) { 00269 00270 if ( NULL == *StoredVD) { 00271 00272 *StoredVD = (PNSR_VD_GENERIC) FsRtlAllocatePoolWithTag( UdfNonPagedPool, 00273 sizeof(NSR_VD_GENERIC), 00274 TAG_NSR_VDSD ); 00275 } 00276 00277 RtlCopyMemory( *StoredVD, NewVD, sizeof( NSR_VD_GENERIC)); 00278 } 00279 }

VOID UdfTeardownStructures IN PIRP_CONTEXT  IrpContext,
IN PFCB  StartingFcb,
IN BOOLEAN  Recursive,
OUT PBOOLEAN  RemovedStartingFcb
 

Definition at line 1606 of file udfs/strucsup.c.

References ASSERT, ASSERT_FCB, ASSERT_IRP_CONTEXT, ASSERT_LCB, _LCB::ChildFcb, ClearFlag, Dbg, DebugTrace, FALSE, FCB_STATE_IN_FCB_TABLE, _FCB::FcbReference, _FCB::FcbState, _FCB::FcbUserReference, FlagOn, IRP_CONTEXT_FLAG_IN_TEARDOWN, NULL, PAGED_CODE, _LCB::ParentFcb, _FCB::ParentLcbQueue, _LCB::Reference, SafeNodeType, SetFlag, TRUE, UdfAcquireFcbExclusive, UdfDecrementReferenceCounts, UdfDeleteFcb(), UdfDeleteFcbTable, UdfDeleteInternalStream(), UdfLockVcb, UdfReleaseFcb, UdfRemovePrefix(), UDFS_NTC_FCB_DATA, UdfUnlockVcb, _VCB::VcbReference, and _VCB::VcbUserReference.

Referenced by UdfCommonClosePrivate(), UdfCommonCreate(), UdfOplockComplete(), UdfPrePostIrp(), and UdfPurgeVolume().

01615 : 01616 01617 This routine is used to walk from some starting point in the Fcb tree towards 01618 the root. It will remove the Fcb and continue walking up the tree until 01619 it finds a point where we can't remove an Fcb. 01620 01621 We look at the following fields in the Fcb to determine whether we can 01622 remove this. 01623 01624 1 - Handle count must be zero. 01625 2 - If directory then only the only reference can be for a stream file. 01626 3 - Reference count must either be zero or go to zero here. 01627 01628 We return immediately if we are recursively entering this routine. 01629 01630 Arguments: 01631 01632 StartingFcb - This is the Fcb node in the tree to begin with. This Fcb 01633 must currently be acquired exclusively. 01634 01635 Recursive - Indicates if this call is an intentional recursion. 01636 01637 RemovedStartingFcb - Address to store whether we removed the starting Fcb. 01638 01639 Return Value: 01640 01641 None 01642 01643 --*/ 01644 01645 { 01646 PVCB Vcb = StartingFcb->Vcb; 01647 PFCB CurrentFcb = StartingFcb; 01648 BOOLEAN AcquiredCurrentFcb = FALSE; 01649 PFCB ParentFcb = NULL; 01650 PLCB Lcb; 01651 01652 PLIST_ENTRY ListLinks; 01653 BOOLEAN Abort = FALSE; 01654 BOOLEAN Removed; 01655 01656 PAGED_CODE(); 01657 01658 // 01659 // Check input. 01660 // 01661 01662 ASSERT_IRP_CONTEXT( IrpContext ); 01663 ASSERT_FCB( StartingFcb ); 01664 01665 *RemovedStartingFcb = FALSE; 01666 01667 // 01668 // If this is not an intentionally recursive call we need to check if this 01669 // is a layered close and we're already in another instance of teardown. 01670 // 01671 01672 DebugTrace(( +1, Dbg, 01673 "UdfTeardownStructures, StartingFcb %08x %s\n", 01674 StartingFcb, 01675 ( Recursive? "Recursive" : "Flat" ))); 01676 01677 if (!Recursive) { 01678 01679 // 01680 // If this is a recursive call to TearDownStructures we return immediately 01681 // doing no operation. 01682 // 01683 01684 if (FlagOn( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN )) { 01685 01686 return; 01687 } 01688 01689 SetFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN ); 01690 } 01691 01692 // 01693 // Use a try-finally to safely clear the top-level field. 01694 // 01695 01696 try { 01697 01698 // 01699 // Loop until we find an Fcb we can't remove. 01700 // 01701 01702 do { 01703 01704 // 01705 // See if there is an internal stream we should delete. 01706 // Only do this if it is the last reference on the Fcb. 01707 // 01708 01709 if ((SafeNodeType( CurrentFcb ) != UDFS_NTC_FCB_DATA) && 01710 (CurrentFcb->FcbUserReference == 0) && 01711 (CurrentFcb->FileObject != NULL)) { 01712 01713 // 01714 // Go ahead and delete the stream file object. 01715 // 01716 01717 UdfDeleteInternalStream( IrpContext, CurrentFcb ); 01718 } 01719 01720 // 01721 // If the reference count is non-zero then break. 01722 // 01723 01724 if (CurrentFcb->FcbReference != 0) { 01725 01726 break; 01727 } 01728 01729 // 01730 // It looks like we have a candidate for removal here. We 01731 // will need to walk the list of prefixes and delete them 01732 // from their parents. If it turns out that we have multiple 01733 // parents of this Fcb, we are going to recursively teardown 01734 // on each of these. 01735 // 01736 01737 for ( ListLinks = CurrentFcb->ParentLcbQueue.Flink; 01738 ListLinks != &CurrentFcb->ParentLcbQueue; ) { 01739 01740 Lcb = CONTAINING_RECORD( ListLinks, LCB, ChildFcbLinks ); 01741 01742 ASSERT_LCB( Lcb ); 01743 01744 // 01745 // We advance the pointer now because we will be toasting this guy, 01746 // invalidating whatever is here. 01747 // 01748 01749 ListLinks = ListLinks->Flink; 01750 01751 // 01752 // We may have multiple parents through hard links. If the previous parent we 01753 // dealt with is not the parent of this new Lcb, lets do some work. 01754 // 01755 01756 if (ParentFcb != Lcb->ParentFcb) { 01757 01758 // 01759 // We need to deal with the previous parent. It may now be the case that 01760 // we deleted the last child reference and it wants to go away at this point. 01761 // 01762 01763 if (ParentFcb) { 01764 01765 // 01766 // It should never be the case that we have to recurse more than one level on 01767 // any teardown since no cross-linkage of directories is possible. 01768 // 01769 01770 ASSERT( !Recursive ); 01771 01772 UdfTeardownStructures( IrpContext, ParentFcb, TRUE, &Removed ); 01773 01774 if (!Removed) { 01775 01776 UdfReleaseFcb( IrpContext, ParentFcb ); 01777 } 01778 } 01779 01780 // 01781 // Get this new parent Fcb to work on. 01782 // 01783 01784 ParentFcb = Lcb->ParentFcb; 01785 UdfAcquireFcbExclusive( IrpContext, ParentFcb, FALSE ); 01786 } 01787 01788 // 01789 // Lock the Vcb so we can look at references. 01790 // 01791 01792 UdfLockVcb( IrpContext, Vcb ); 01793 01794 // 01795 // Now check that the reference counts on the Lcb are zero. 01796 // 01797 01798 if ( Lcb->Reference != 0 ) { 01799 01800 // 01801 // A create is interested in getting in here, so we should 01802 // stop right now. 01803 // 01804 01805 UdfUnlockVcb( IrpContext, Vcb ); 01806 UdfReleaseFcb( IrpContext, ParentFcb ); 01807 Abort = TRUE; 01808 01809 break; 01810 } 01811 01812 // 01813 // Now remove this prefix and drop the references to the parent. 01814 // 01815 01816 ASSERT( Lcb->ChildFcb == CurrentFcb ); 01817 ASSERT( Lcb->ParentFcb == ParentFcb ); 01818 01819 DebugTrace(( +0, Dbg, 01820 "UdfTeardownStructures, Lcb %08x P %08x <-> C %08x Vcb %d/%d PFcb %d/%d CFcb %d/%d\n", 01821 Lcb, 01822 ParentFcb, 01823 CurrentFcb, 01824 Vcb->VcbReference, 01825 Vcb->VcbUserReference, 01826 ParentFcb->FcbReference, 01827 ParentFcb->FcbUserReference, 01828 CurrentFcb->FcbReference, 01829 CurrentFcb->FcbUserReference )); 01830 01831 UdfRemovePrefix( IrpContext, Lcb ); 01832 UdfDecrementReferenceCounts( IrpContext, ParentFcb, 1, 1 ); 01833 01834 DebugTrace(( +0, Dbg, 01835 "UdfTeardownStructures, Vcb %d/%d PFcb %d/%d\n", 01836 Vcb->VcbReference, 01837 Vcb->VcbUserReference, 01838 ParentFcb->FcbReference, 01839 ParentFcb->FcbUserReference )); 01840 01841 UdfUnlockVcb( IrpContext, Vcb ); 01842 } 01843 01844 // 01845 // Now really leave if we have to. 01846 // 01847 01848 if (Abort) { 01849 01850 break; 01851 } 01852 01853 // 01854 // Now that we have removed all of the prefixes of this Fcb we can make the final check. 01855 // Lock the Vcb again so we can inspect the child's references. 01856 // 01857 01858 UdfLockVcb( IrpContext, Vcb ); 01859 01860 if (CurrentFcb->FcbReference != 0) { 01861 01862 DebugTrace(( +0, Dbg, 01863 "UdfTeardownStructures, saving Fcb %08x %d/%d\n", 01864 CurrentFcb, 01865 CurrentFcb->FcbReference, 01866 CurrentFcb->FcbUserReference )); 01867 01868 // 01869 // Nope, nothing more to do. Stop right now. 01870 // 01871 01872 UdfUnlockVcb( IrpContext, Vcb ); 01873 01874 if (ParentFcb != NULL) { 01875 01876 UdfReleaseFcb( IrpContext, ParentFcb ); 01877 } 01878 01879 break; 01880 } 01881 01882 // 01883 // This Fcb is toast. Remove it from the Fcb Table as appropriate and delete. 01884 // 01885 01886 if (FlagOn( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE )) { 01887 01888 UdfDeleteFcbTable( IrpContext, CurrentFcb ); 01889 ClearFlag( CurrentFcb->FcbState, FCB_STATE_IN_FCB_TABLE ); 01890 01891 } 01892 01893 // 01894 // Unlock the Vcb but hold the parent in order to walk up 01895 // the tree. 01896 // 01897 01898 DebugTrace(( +0, Dbg, 01899 "UdfTeardownStructures, toasting Fcb %08x %d/%d\n", 01900 CurrentFcb, 01901 CurrentFcb->FcbReference, 01902 CurrentFcb->FcbUserReference )); 01903 01904 UdfUnlockVcb( IrpContext, Vcb ); 01905 UdfDeleteFcb( IrpContext, CurrentFcb ); 01906 01907 // 01908 // Move to the parent Fcb. 01909 // 01910 01911 CurrentFcb = ParentFcb; 01912 ParentFcb = NULL; 01913 AcquiredCurrentFcb = TRUE; 01914 01915 } while (CurrentFcb != NULL); 01916 01917 } finally { 01918 01919 // 01920 // Release the current Fcb if we have acquired it. 01921 // 01922 01923 if (AcquiredCurrentFcb && (CurrentFcb != NULL)) { 01924 01925 UdfReleaseFcb( IrpContext, CurrentFcb ); 01926 } 01927 01928 // 01929 // Clear the teardown flag. 01930 // 01931 01932 if (!Recursive) { 01933 01934 ClearFlag( IrpContext->TopLevel->Flags, IRP_CONTEXT_FLAG_IN_TEARDOWN ); 01935 } 01936 } 01937 01938 *RemovedStartingFcb = (CurrentFcb != StartingFcb); 01939 01940 DebugTrace(( -1, Dbg, 01941 "UdfTeardownStructures, RemovedStartingFcb -> %c\n", 01942 ( *RemovedStartingFcb? 'T' : 'F' ))); 01943 01944 return; 01945 }

INLINE BOOLEAN UdfUdfIdentifierContained IN PREGID  RegID,
IN PSTRING  Type,
IN USHORT  RevisionMin,
IN USHORT  RevisionMax,
IN UCHAR  OSClass,
IN UCHAR  OSIdentifier
 

Definition at line 2060 of file udfprocs.h.

References NULL, _UDF_SUFFIX_UDF::OSClass, OSCLASS_INVALID, _UDF_SUFFIX_UDF::OSIdentifier, OSIDENTIFIER_INVALID, UdfEqualEntityId(), and _UDF_SUFFIX_UDF::UdfRevision.

Referenced by UdfLoadSparingTables(), and UdfUpdateVcbPhase0().

02068 { 02069 PUDF_SUFFIX_UDF UdfSuffix = (PUDF_SUFFIX_UDF) RegID->Suffix; 02070 02071 return ((UdfSuffix->UdfRevision <= RevisionMax && UdfSuffix->UdfRevision >= RevisionMin) && 02072 (OSClass == OSCLASS_INVALID || UdfSuffix->OSClass == OSClass) && 02073 (OSIdentifier == OSIDENTIFIER_INVALID || UdfSuffix->OSIdentifier == OSIdentifier) && 02074 UdfEqualEntityId( RegID, Type, NULL )); 02075 }

VOID UdfUninitializeVmcb IN PVMCB  Vmcb  ) 
 

Definition at line 325 of file vmcbsup.c.

References Dbg, DebugTrace, FsRtlUninitializeMcb(), and PAGED_CODE.

Referenced by UdfDeleteFcb().

00331 : 00332 00333 This routine uninitializes an existing VMCB structure. After calling 00334 this routine the input VMCB structure must be re-initialized before 00335 being used again. 00336 00337 Arguments: 00338 00339 Vmcb - Supplies a pointer to the VMCB structure to uninitialize. 00340 00341 Return Value: 00342 00343 None. 00344 00345 --*/ 00346 00347 { 00348 PAGED_CODE(); 00349 00350 DebugTrace(( +1, Dbg, "UdfUninitializeVmcb, Vmcb = %08x\n", Vmcb )); 00351 00352 // 00353 // Unitialize the fields in the Vmcb structure 00354 // 00355 00356 FsRtlUninitializeMcb( &Vmcb->VbnIndexed ); 00357 FsRtlUninitializeMcb( &Vmcb->LbnIndexed ); 00358 00359 // 00360 // And return to our caller 00361 // 00362 00363 DebugTrace(( -1, Dbg, "UdfUninitializeVmcb -> VOID\n" )); 00364 00365 return; 00366 }

NTSTATUS UdfUnlockVolumeInternal IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb,
IN PFILE_OBJECT FileObject  OPTIONAL
 

Definition at line 732 of file udfs/fsctrl.c.

References ClearFlag, FlagOn, NTSTATUS(), NULL, Status, and VCB_STATE_LOCKED.

Referenced by UdfPnpCancelRemove(), UdfPnpRemove(), and UdfUnlockVolume().

00740 : 00741 00742 This routine performs the actual unlock volume operation. 00743 00744 The volume must be held exclusive by the caller. 00745 00746 Arguments: 00747 00748 Vcb - The volume being locked. 00749 00750 FileObject - File corresponding to the handle locking the volume. If this 00751 is not specified, a system lock is assumed. 00752 00753 Return Value: 00754 00755 NTSTATUS - The return status for the operation 00756 00757 Attempting to remove a system lock that did not exist is OK. 00758 00759 --*/ 00760 00761 { 00762 NTSTATUS Status = STATUS_INVALID_PARAMETER; 00763 00764 if (FlagOn(Vcb->VcbState, VCB_STATE_LOCKED) && FileObject == Vcb->VolumeLockFileObject) { 00765 00766 ClearFlag( Vcb->VcbState, VCB_STATE_LOCKED ); 00767 Vcb->VolumeLockFileObject = NULL; 00768 Status = STATUS_SUCCESS; 00769 } 00770 00771 return Status; 00772 }

INLINE VOID UdfUpcaseName IN PIRP_CONTEXT  IrpContext,
IN PUNICODE_STRING  Name,
IN OUT PUNICODE_STRING  UpcaseName
 

Definition at line 1131 of file udfprocs.h.

References ASSERT, FALSE, Name, NTSTATUS(), RtlUpcaseUnicodeString(), and Status.

Referenced by UdfGenerate8dot3Name(), UdfNormalizeFileNames(), and UdfUpdateDirNames().

01139 : 01140 01141 This routine upcases a name with an assertion of success. 01142 01143 Arguments: 01144 01145 Name - an name to upcase 01146 01147 Length - a place to put the upcased name (can be the same as Name) 01148 01149 Return Value: 01150 01151 None. 01152 01153 --*/ 01154 01155 { 01156 NTSTATUS Status; 01157 01158 // 01159 // Upcase the string using the correct upcase routine. 01160 // 01161 01162 Status = RtlUpcaseUnicodeString( UpcaseName, 01163 Name, 01164 FALSE ); 01165 01166 // 01167 // This should never fail. 01168 // 01169 01170 ASSERT( Status == STATUS_SUCCESS ); 01171 01172 return; 01173 }

VOID UdfUpdateDirNames IN PIRP_CONTEXT  IrpContext,
IN PDIR_ENUM_CONTEXT  DirContext,
IN BOOLEAN  IgnoreCase
 

Definition at line 360 of file dirsup.c.

References Add2Ptr, ASSERT, ASSERT_IRP_CONTEXT, BYTE_COUNT_8_DOT_3, CRC_LEN, Dbg, DebugTrace, DIR_CONTEXT_FLAG_SEEN_NONCONSTANT, DIR_CONTEXT_FLAG_SEEN_PARENT, FALSE, FlagOn, FsRtlAllocatePoolWithTag, ISONsrFidConstantSize, Max, MAX_LEN, NSR_FID_F_PARENT, NULL, PAGED_CODE, PARENT_ENTRY, SELF_ENTRY, SetFlag, TAG_FILE_NAME, UdfCheckLegalCS0Dstring(), UdfConvertCS0DstringToUnicode(), UdfCS0DstringContainsLegalCharacters(), UdfCS0DstringUnicodeSize(), UdfFreePool(), UdfPagedPool, UdfRaiseStatus(), UdfRenderNameToLegalUnicode(), UdfUnicodeDirectoryNames, UdfUpcaseName(), and USHORT.

Referenced by UdfEnumerateIndex(), UdfFindDirEntry(), and UdfInitializeEnumeration().

00368 : 00369 00370 This routine fills in the non-short names of a directory enumeration context 00371 for the Fid currently referenced. 00372 00373 Arguments: 00374 00375 DirContext - a corresponding context to fill in. 00376 00377 IgnoreCase - whether the caller wants to be insensitive to case. 00378 00379 Return Value: 00380 00381 None. 00382 00383 --*/ 00384 00385 { 00386 PUCHAR NameDstring; 00387 BOOLEAN ContainsIllegal; 00388 00389 USHORT NameLength; 00390 USHORT BufferLength; 00391 USHORT PresentLength; 00392 00393 PAGED_CODE(); 00394 00395 // 00396 // Check input. 00397 // 00398 00399 ASSERT_IRP_CONTEXT( IrpContext ); 00400 00401 DebugTrace(( +1, Dbg, "UdfUpdateDirNames\n" )); 00402 00403 // 00404 // Handle the case of the self directory entry. 00405 // 00406 00407 if (DirContext->Fid == NULL) { 00408 00409 // 00410 // Simply synthesize 00411 // 00412 00413 // 00414 // It doesn't hurt to be pedantic about initialization, so do it all. 00415 // 00416 00417 DirContext->PureObjectName.Length = 00418 DirContext->CaseObjectName.Length = 00419 DirContext->ObjectName.Length = UdfUnicodeDirectoryNames[SELF_ENTRY].Length; 00420 00421 DirContext->PureObjectName.MaximumLength = 00422 DirContext->CaseObjectName.MaximumLength = 00423 DirContext->ObjectName.MaximumLength = UdfUnicodeDirectoryNames[SELF_ENTRY].MaximumLength; 00424 00425 DirContext->PureObjectName.Buffer = 00426 DirContext->CaseObjectName.Buffer = 00427 DirContext->ObjectName.Buffer = UdfUnicodeDirectoryNames[SELF_ENTRY].Buffer; 00428 00429 // 00430 // All done. 00431 // 00432 00433 DebugTrace(( 0, Dbg, "Self Entry case\n" )); 00434 DebugTrace(( -1, Dbg, "UdfUpdateDirNames -> VOID\n" )); 00435 00436 return; 00437 } 00438 00439 // 00440 // Handle the case of the parent directory entry. 00441 // 00442 00443 if (FlagOn( DirContext->Fid->Flags, NSR_FID_F_PARENT )) { 00444 00445 // 00446 // Parent entries must occur at the front of the directory and 00447 // have a fid length of zero (13346 4/14.4.4). 00448 // 00449 00450 if (FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_SEEN_NONCONSTANT ) || 00451 DirContext->Fid->FileIDLen != 0) { 00452 00453 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 00454 } 00455 00456 // 00457 // Note that we have seen the parent entry. 00458 // 00459 00460 SetFlag( DirContext->Flags, DIR_CONTEXT_FLAG_SEEN_PARENT ); 00461 00462 // 00463 // It doesn't hurt to be pedantic about initialization, so do it all. 00464 // 00465 00466 DirContext->PureObjectName.Length = 00467 DirContext->CaseObjectName.Length = 00468 DirContext->ObjectName.Length = UdfUnicodeDirectoryNames[PARENT_ENTRY].Length; 00469 00470 DirContext->PureObjectName.MaximumLength = 00471 DirContext->CaseObjectName.MaximumLength = 00472 DirContext->ObjectName.MaximumLength = UdfUnicodeDirectoryNames[PARENT_ENTRY].MaximumLength; 00473 00474 DirContext->PureObjectName.Buffer = 00475 DirContext->CaseObjectName.Buffer = 00476 DirContext->ObjectName.Buffer = UdfUnicodeDirectoryNames[PARENT_ENTRY].Buffer; 00477 00478 // 00479 // All done. 00480 // 00481 00482 DebugTrace(( 0, Dbg, "Parent Entry case\n" )); 00483 DebugTrace(( -1, Dbg, "UdfUpdateDirNames -> VOID\n" )); 00484 00485 return; 00486 } 00487 00488 // 00489 // We now know that we will need to convert the name in a real FID, so figure out where 00490 // it sits in the descriptor. 00491 // 00492 00493 NameDstring = Add2Ptr( DirContext->Fid, ISONsrFidConstantSize + DirContext->Fid->ImpUseLen, PUCHAR ); 00494 00495 // 00496 // Every directory must record a parent entry. 00497 // 00498 00499 if (!FlagOn( DirContext->Flags, DIR_CONTEXT_FLAG_SEEN_PARENT)) { 00500 00501 UdfRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR ); 00502 } 00503 00504 // 00505 // Note that we are proceeding into the non-constant portion of a directory. 00506 // 00507 00508 SetFlag( DirContext->Flags, DIR_CONTEXT_FLAG_SEEN_NONCONSTANT ); 00509 00510 // 00511 // Make sure the dstring is good CS0 00512 // 00513 00514 UdfCheckLegalCS0Dstring( IrpContext, 00515 NameDstring, 00516 DirContext->Fid->FileIDLen, 00517 0, 00518 FALSE ); 00519 00520 // 00521 // Don't bother allocating tiny buffers - always make sure we get enough for an 8.3 name. 00522 // 00523 00524 BufferLength = 00525 NameLength = Max( BYTE_COUNT_8_DOT_3, UdfCS0DstringUnicodeSize( IrpContext, 00526 NameDstring, 00527 DirContext->Fid->FileIDLen) ); 00528 00529 // 00530 // Illegality is both actual illegal characters and too many characters. 00531 // 00532 00533 ContainsIllegal = (!UdfCS0DstringContainsLegalCharacters( NameDstring, DirContext->Fid->FileIDLen ) || 00534 (NameLength / sizeof( WCHAR )) > MAX_LEN); 00535 00536 00537 // 00538 // If we're illegal, we will need more characters to hold the uniqifying stamp. 00539 // 00540 00541 if (ContainsIllegal) { 00542 00543 BufferLength = (NameLength += (CRC_LEN * sizeof(WCHAR))); 00544 } 00545 00546 00547 // 00548 // If we need to build a case insensitive name, need more space. 00549 // 00550 00551 if (IgnoreCase) { 00552 00553 BufferLength += NameLength; 00554 } 00555 00556 // 00557 // If we need to render the names due to illegal characters, more space again. 00558 // 00559 00560 if (ContainsIllegal) { 00561 00562 BufferLength += NameLength; 00563 00564 } else { 00565 00566 // 00567 // Make sure the names aren't seperated. If more illegal names are found we can 00568 // resplit the buffer but until then avoid the expense of having to copy bytes 00569 // ... odds are that illegal characters are going to be a rarish occurance. 00570 // 00571 00572 DirContext->PureObjectName.Buffer = DirContext->ObjectName.Buffer; 00573 } 00574 00575 DebugTrace(( 0, Dbg, 00576 "Ob %s%sneeds %d bytes (%d byte chunks), have %d\n", 00577 (IgnoreCase? "Ic " : ""), 00578 (ContainsIllegal? "Ci " : ""), 00579 BufferLength, 00580 NameLength, 00581 DirContext->AllocLength )); 00582 00583 // 00584 // Check if we need more space for the names. We will need more if the name size is greater 00585 // than the maximum we can currently store, or if we have stumbled across illegal characters 00586 // and the current Pure name is not seperated from the exposed Object name. 00587 // 00588 // Note that IgnoreCase remains constant across usage of a context so we don't have to wonder 00589 // if it has been seperated from the ObjectName - it'll always be correct. 00590 // 00591 00592 if ((NameLength > DirContext->ObjectName.MaximumLength) || 00593 (ContainsIllegal && DirContext->ObjectName.Buffer == DirContext->PureObjectName.Buffer)) { 00594 00595 DebugTrace(( 0, Dbg, "Resizing buffers\n" )); 00596 00597 // 00598 // For some reason the sizing is not good for the current name we have to unroll. Figure 00599 // out if we can break up the current allocation in a different way before falling back 00600 // to a new allocation. 00601 // 00602 00603 if (DirContext->AllocLength >= BufferLength) { 00604 00605 // 00606 // So we can still use the current allocation. Chop it up into the required number 00607 // of chunks. 00608 // 00609 00610 DirContext->PureObjectName.MaximumLength = 00611 DirContext->CaseObjectName.MaximumLength = 00612 DirContext->ObjectName.MaximumLength = DirContext->AllocLength / (1 + 00613 (IgnoreCase? 1 : 0) + 00614 (ContainsIllegal? 1 : 0)); 00615 00616 DebugTrace(( 0, Dbg, 00617 "... by resplit into %d byte chunks\n", 00618 DirContext->ObjectName.MaximumLength )); 00619 00620 // 00621 // Set the buffer pointers up. Required adjustment will occur below. 00622 // 00623 00624 DirContext->PureObjectName.Buffer = 00625 DirContext->CaseObjectName.Buffer = 00626 DirContext->ObjectName.Buffer = DirContext->NameBuffer; 00627 00628 } else { 00629 00630 DebugTrace(( 0, Dbg, "... by allocating new pool\n" )); 00631 00632 // 00633 // Oh well, no choice but to fall back into the pool. Drop our previous hunk. 00634 // 00635 00636 UdfFreePool( &DirContext->NameBuffer ); 00637 DirContext->AllocLength = 0; 00638 00639 // 00640 // The names share an allocation for efficiency. 00641 // 00642 00643 DirContext->PureObjectName.MaximumLength = 00644 DirContext->CaseObjectName.MaximumLength = 00645 DirContext->ObjectName.MaximumLength = NameLength; 00646 00647 DirContext->NameBuffer = 00648 DirContext->PureObjectName.Buffer = 00649 DirContext->CaseObjectName.Buffer = 00650 DirContext->ObjectName.Buffer = FsRtlAllocatePoolWithTag( UdfPagedPool, 00651 BufferLength, 00652 TAG_FILE_NAME ); 00653 00654 DirContext->AllocLength = BufferLength; 00655 } 00656 00657 // 00658 // In the presence of the "as appropriate" names, adjust the buffer locations. Note 00659 // that ObjectName.Buffer is always the base of the allocated space. 00660 // 00661 00662 if (IgnoreCase) { 00663 00664 DirContext->CaseObjectName.Buffer = Add2Ptr( DirContext->ObjectName.Buffer, 00665 DirContext->ObjectName.MaximumLength, 00666 PWCHAR ); 00667 } 00668 00669 if (ContainsIllegal) { 00670 00671 DirContext->PureObjectName.Buffer = Add2Ptr( DirContext->CaseObjectName.Buffer, 00672 DirContext->CaseObjectName.MaximumLength, 00673 PWCHAR ); 00674 } 00675 } 00676 00677 ASSERT( BufferLength <= DirContext->AllocLength ); 00678 00679 // 00680 // Convert the dstring. 00681 // 00682 00683 UdfConvertCS0DstringToUnicode( IrpContext, 00684 NameDstring, 00685 DirContext->Fid->FileIDLen, 00686 0, 00687 &DirContext->PureObjectName ); 00688 00689 // 00690 // If illegal characters were present, run the name through the UDF transmogrifier. 00691 // 00692 00693 if (ContainsIllegal) { 00694 00695 UdfRenderNameToLegalUnicode( IrpContext, 00696 &DirContext->PureObjectName, 00697 &DirContext->ObjectName ); 00698 00699 // 00700 // The ObjectName is the same as the PureObjectName. 00701 // 00702 00703 } else { 00704 00705 DirContext->ObjectName.Length = DirContext->PureObjectName.Length; 00706 } 00707 00708 // 00709 // Upcase the result if required. 00710 // 00711 00712 if (IgnoreCase) { 00713 00714 UdfUpcaseName( IrpContext, 00715 &DirContext->ObjectName, 00716 &DirContext->CaseObjectName ); 00717 } 00718 00719 DebugTrace(( -1, Dbg, "UdfUpdateDirNames -> VOID\n" )); 00720 00721 return; 00722 }

VOID UdfUpdateTimestampsFromIcbContext IN PIRP_CONTEXT  IrpContext,
IN PICB_SEARCH_CONTEXT  IcbContext,
IN PTIMESTAMP_BUNDLE  Timestamps
 

Definition at line 3595 of file udfs/strucsup.c.

References ICBFILE::AccessTime, ASSERT, ASSERT_IRP_CONTEXT, ICBFILE::Destag, DESTAG_ID_NSR_FILE, _EA_SEARCH_CONTEXT::Ea, EA_FILETIMES_E_CREATION, EA_INFOTIMES_E_CREATION, EA_INFOTIMES_E_MODIFICATION, EA_SUBTYPE_BASE, EA_TYPE_FILETIMES, EA_TYPE_INFOTIMES, NSR_EA_FILETIMES::Existence, FALSE, FlagOn, DESTAG::Ident, ICBFILE::ModifyTime, PAGED_CODE, PNSR_EA_FILETIMES, PTIMESTAMP_BUNDLE, NSR_EA_FILETIMES::Stamps, TRUE, UdfConvertUdfTimeToNtTime(), UdfInitializeEaContext(), and UdfLookupEa().

Referenced by UdfInitializeFcbFromIcbContext(), and UdfQueryDirectory().

03603 : 03604 03605 This routine converts the set of timestamps associated with a given ICB into 03606 an NT native form. 03607 03608 Arguments: 03609 03610 IcbOontext - An search context containing the active direct ICB for the object 03611 03612 Timestamps - the bundle of timestamps to receive the converted times. 03613 03614 Return Value: 03615 03616 None. 03617 03618 --*/ 03619 03620 { 03621 EA_SEARCH_CONTEXT EaContext; 03622 PICBFILE Icb; 03623 03624 PAGED_CODE(); 03625 03626 // 03627 // Check inputs 03628 // 03629 03630 ASSERT_IRP_CONTEXT( IrpContext ); 03631 03632 // 03633 // Directly reference for convenience. 03634 // 03635 03636 Icb = IcbContext->Active.View; 03637 03638 ASSERT( Icb->Destag.Ident == DESTAG_ID_NSR_FILE ); 03639 03640 // 03641 // Initialize the timestamps for this object. Due to basic idiocy in ISO 13346, 03642 // we must gather EAs and figure out which of several timestamps is most valid. 03643 // 03644 03645 // 03646 // Begin by using the fields in the ICB itself. 03647 // 03648 03649 UdfConvertUdfTimeToNtTime( IrpContext, 03650 &Icb->ModifyTime, 03651 (PLARGE_INTEGER) &Timestamps->ModificationTime ); 03652 03653 Timestamps->CreationTime = Timestamps->ModificationTime; 03654 03655 UdfConvertUdfTimeToNtTime( IrpContext, 03656 &Icb->AccessTime, 03657 (PLARGE_INTEGER) &Timestamps->AccessTime ); 03658 03659 // 03660 // Gather the File Times and Information Times EAs for this object, if they exist, 03661 // and set the timestamps. Just override timestamps if they exist. 03662 // 03663 03664 UdfInitializeEaContext( IrpContext, 03665 &EaContext, 03666 IcbContext, 03667 EA_TYPE_FILETIMES, 03668 EA_SUBTYPE_BASE ); 03669 03670 if (UdfLookupEa( IrpContext, &EaContext )) { 03671 03672 PNSR_EA_FILETIMES FileTimes = EaContext.Ea; 03673 03674 if (FlagOn(FileTimes->Existence, EA_FILETIMES_E_CREATION)) { 03675 03676 UdfConvertUdfTimeToNtTime( IrpContext, 03677 &FileTimes->Stamps[0], 03678 (PLARGE_INTEGER) &Timestamps->CreationTime ); 03679 } 03680 } 03681 03682 UdfInitializeEaContext( IrpContext, 03683 &EaContext, 03684 IcbContext, 03685 EA_TYPE_INFOTIMES, 03686 EA_SUBTYPE_BASE ); 03687 03688 if (UdfLookupEa( IrpContext, &EaContext )) { 03689 03690 PNSR_EA_FILETIMES InfoTimes = EaContext.Ea; 03691 BOOLEAN CreationPresent = FALSE; 03692 03693 if (FlagOn(InfoTimes->Existence, EA_INFOTIMES_E_CREATION)) { 03694 03695 UdfConvertUdfTimeToNtTime( IrpContext, 03696 &InfoTimes->Stamps[0], 03697 (PLARGE_INTEGER) &Timestamps->CreationTime ); 03698 03699 CreationPresent = TRUE; 03700 } 03701 03702 if (FlagOn(InfoTimes->Existence, EA_INFOTIMES_E_MODIFICATION)) { 03703 03704 UdfConvertUdfTimeToNtTime( IrpContext, 03705 &InfoTimes->Stamps[CreationPresent? 1: 0], 03706 (PLARGE_INTEGER) &Timestamps->CreationTime ); 03707 } 03708 } 03709 }

VOID UdfUpdateVcbPhase0 IN PIRP_CONTEXT  IrpContext,
IN OUT PVCB  Vcb
 

Definition at line 477 of file udfs/strucsup.c.

References _ICB_SEARCH_CONTEXT::Active, ANCHOR_SECTOR, ASSERT, ASSERT_IRP_CONTEXT, ASSERT_VCB, BlocksFromSectors, BlockSize, CcMapData(), CcPurgeCacheSection(), CcSetFileSizes(), Dbg, DebugTrace, DebugUnwind, DESTAG_ID_NSR_FILE, ExFreePool(), FALSE, FCB_STATE_INITIALIZED, FCB_STATE_VMCB_MAPPING, FlagOn, FsRtlAllocatePoolWithTag, ICB_SEARCH_CONTEXT, ICBTAG_FILE_T_NOTSPEC, _MAPPED_PVIEW::Lbn, LlBytesFromSectors, LlSectorAlign, LongOffset, NT_SUCCESS, NULL, Offset, OSCLASS_INVALID, OSIDENTIFIER_INVALID, PAGED_CODE, _MAPPED_PVIEW::Partition, PCB_FLAG_VIRTUAL_PARTITION, PDESTAG, PFILE_ID, Physical, PICBFILE, PREGID, SectorSize, SetFlag, TAG_NSR_VDSD, TRUE, UDF_CDUDF_MAXIMUM_VAT_SIZE, UDF_CDUDF_MINIMUM_VAT_SIZE, UDF_CDUDF_TRAILING_DATA_SIZE, UDF_VERSION_150, UDF_VERSION_RECOGNIZED, UdfCleanupIcbContext(), UdfCreateFcb(), UdfCreateInternalStream(), UdfIncrementReferenceCounts, UdfInitializeAllocations(), UdfInitializeVmcb(), UdfLockFcb, UdfLockVcb, UdfLookupMetaVsnOfExtent(), UdfPagedPool, UdfRaiseStatus(), UdfRawBufferSize(), UdfRawReadSize(), UdfReadSectors(), UdfResetVmcb(), UDFS_CDUDF_RESIDUAL_REFERENCE, UDFS_CDUDF_RESIDUAL_USER_REFERENCE, UDFS_NTC_FCB_INDEX, UdfUdfIdentifierContained(), UdfUnlockFcb, UdfUnlockVcb, UdfUnpinData, UdfVatTableIdentifier, UdfVerifyDescriptor(), USHORT, _MAPPED_PVIEW::View, and Virtual.

Referenced by UdfMountVolume().

00484 : 00485 00486 This routine is called to perform the initial spinup of the volume so that 00487 we can do reads into it. Primarily, this is required since virtual partitions 00488 make us lift the remapping table, and the final sets of descriptors from the volume 00489 can be off in these virtual partitions. 00490 00491 So, we need to get everything set up to read. 00492 00493 Arguments: 00494 00495 Vcb - Vcb for the volume being mounted. We have already set up and completed 00496 the Pcb. 00497 00498 Return Value: 00499 00500 None 00501 00502 --*/ 00503 00504 { 00505 ICB_SEARCH_CONTEXT IcbContext; 00506 00507 LONGLONG FileId = 0; 00508 00509 PICBFILE VatIcb = NULL; 00510 PREGID RegId; 00511 ULONG ThisPass; 00512 ULONG Psn; 00513 ULONG Vsn; 00514 ULONG Lbn; 00515 ULONG SectorCount; 00516 USHORT Reference; 00517 00518 BOOLEAN UnlockVcb = FALSE; 00519 BOOLEAN CleanupIcbContext = FALSE; 00520 00521 PBCB Bcb = NULL; 00522 LARGE_INTEGER Offset; 00523 00524 PAGED_CODE(); 00525 00526 // 00527 // Check input. 00528 // 00529 00530 ASSERT_IRP_CONTEXT( IrpContext ); 00531 ASSERT_VCB( Vcb ); 00532 00533 DebugTrace(( +1, Dbg, "UdfUpdateVcbPhase0, Vcb %08x\n", Vcb )); 00534 00535 try { 00536 00538 // 00539 // Create the Metadata Fcb and refererence it and the Vcb. 00540 // 00542 00543 UdfLockVcb( IrpContext, Vcb ); 00544 UnlockVcb = TRUE; 00545 00546 Vcb->MetadataFcb = UdfCreateFcb( IrpContext, 00547 *((PFILE_ID) &FileId), 00548 UDFS_NTC_FCB_INDEX, 00549 NULL ); 00550 00551 UdfIncrementReferenceCounts( IrpContext, Vcb->MetadataFcb, 1, 1 ); 00552 UdfUnlockVcb( IrpContext, Vcb ); 00553 UnlockVcb = FALSE; 00554 00555 // 00556 // The metadata stream is grown lazily as we reference disk structures. 00557 // 00558 00559 Vcb->MetadataFcb->FileSize.QuadPart = 00560 Vcb->MetadataFcb->ValidDataLength.QuadPart = 00561 Vcb->MetadataFcb->AllocationSize.QuadPart = 0; 00562 00563 // 00564 // Initialize the volume Vmcb 00565 // 00566 00567 UdfLockFcb( IrpContext, Vcb->MetadataFcb ); 00568 00569 UdfInitializeVmcb( &Vcb->Vmcb, 00570 UdfPagedPool, 00571 MAXULONG, 00572 SectorSize(Vcb) ); 00573 00574 UdfUnlockFcb( IrpContext, Vcb->MetadataFcb ); 00575 00576 // 00577 // Point to the file resource and set the flag that will cause mappings 00578 // to go through the Vmcb 00579 // 00580 00581 Vcb->MetadataFcb->Resource = &Vcb->FileResource; 00582 00583 SetFlag( Vcb->MetadataFcb->FcbState, FCB_STATE_VMCB_MAPPING | FCB_STATE_INITIALIZED ); 00584 00585 // 00586 // Create the stream file for this. 00587 // 00588 00589 UdfCreateInternalStream( IrpContext, Vcb, Vcb->MetadataFcb ); 00590 00592 // 00593 // If this is a volume containing a virtual partition, set up the 00594 // Virtual Allocation Table Fcb and adjust the residual reference 00595 // counts comensurately. 00596 // 00598 00599 if (FlagOn( Vcb->Pcb->Flags, PCB_FLAG_VIRTUAL_PARTITION )) { 00600 00601 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, handling VAT setup\n" )); 00602 00603 // 00604 // Now if some dummy has stuck us in the situation of not giving us 00605 // the tools to figure out where the end of the media is, tough luck. 00606 // 00607 00608 if (!Vcb->BoundN || Vcb->BoundN < ANCHOR_SECTOR) { 00609 00610 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, no end bound was discoverable!\n" )); 00611 00612 UdfRaiseStatus( IrpContext, STATUS_UNRECOGNIZED_VOLUME ); 00613 } 00614 00615 // 00616 // We take care of this first since the residuals must be in place 00617 // if we raise while finding the VAT, else we will get horribly 00618 // confused when the in-progress references are seen. We will think 00619 // that the extra real referenes are indications that the volume can't 00620 // be dismounted. 00621 // 00622 00623 Vcb->VcbResidualReference += UDFS_CDUDF_RESIDUAL_REFERENCE; 00624 Vcb->VcbResidualUserReference += UDFS_CDUDF_RESIDUAL_USER_REFERENCE; 00625 00626 Vcb->VcbReference += UDFS_CDUDF_RESIDUAL_REFERENCE; 00627 00628 // 00629 // Now, we need to hunt about for the VAT ICB. This is defined, on 00630 // closed media (meaning that the sessions have been finalized for use 00631 // in CDROM drives), to be in the very last information sector on the 00632 // media. Complicating this simple picture is that CDROMs tell us the 00633 // "last sector" by telling us where the start of the leadout area is, 00634 // not where the end of the informational sectors are. This is an 00635 // important distinction because any combination of the following can 00636 // be used in closing a CDROM session: 2 runout sectors, and/or 150 00637 // sectors (2 seconds) of postgap, or nothing. Immediately after these 00638 // "closing" writes is where the leadout begins. 00639 // 00640 // Runout is usually found on CD-E media and corresponds to the time it 00641 // will take to turn the writing laser off. Postgap is what is used to 00642 // generate audio pauses. It is easy to see that the kind of media and 00643 // kind of mastering tool/system used will affect us here. There is no 00644 // way to know either ahead of time. 00645 // 00646 // So, finally, these are the offsets from our previously discovered 00647 // bounding information where we might find the last information sector: 00648 // 00649 // -152 runout + postgap 00650 // -150 postgap 00651 // -2 runout 00652 // 0 nothing 00653 // 00654 // We must search these from low to high since it is extrememly expensive 00655 // to guess wrong - CDROMs will sit there for tens of seconds trying to 00656 // read unwritten/unreadable sectors. Hopefully we will find the VAT 00657 // ICB beforehand. 00658 // 00659 // This should all be highly disturbing. 00660 // 00661 00662 VatIcb = FsRtlAllocatePoolWithTag( UdfPagedPool, 00663 UdfRawBufferSize( Vcb, BlockSize( Vcb )), 00664 TAG_NSR_VDSD); 00665 00666 for (ThisPass = 0; ThisPass < 4; ThisPass++) { 00667 00668 // 00669 // Lift the appropriate sector. The discerning reader will be confused that 00670 // this is done in sector terms, not block. So is the implementor. 00671 // 00672 00673 Psn = Vcb->BoundN - ( ThisPass == 0? 152 : 00674 ( ThisPass == 1? 150 : 00675 ( ThisPass == 2? 2 : 0 ))); 00676 00677 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, looking at Psn 0x%08x\n", Psn )); 00678 00679 // 00680 // Now, try to figure out what physical partition this sector lives in so 00681 // that we can eventually establish workable metadata mappings to it and 00682 // dereference short allocation descriptors it may use. 00683 // 00684 00685 for (Reference = 0; 00686 Reference < Vcb->Pcb->Partitions; 00687 Reference++) { 00688 00689 if (Vcb->Pcb->Partition[Reference].Type == Physical && 00690 Vcb->Pcb->Partition[Reference].Physical.Start <= Psn && 00691 Vcb->Pcb->Partition[Reference].Physical.Start + 00692 Vcb->Pcb->Partition[Reference].Physical.Length > Psn) { 00693 00694 break; 00695 } 00696 } 00697 00698 // 00699 // If this sector is not contained in a partition, we do not 00700 // need to look at it. 00701 // 00702 00703 if (Reference == Vcb->Pcb->Partitions) { 00704 00705 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... but it isn't in a partition.\n" )); 00706 00707 continue; 00708 } 00709 00710 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... in partition Ref %u.\n", Reference )); 00711 00712 // 00713 // We must locate the Lbn of this Psn by figuring out the offset of it 00714 // in the partition we already know that it is recorded in. 00715 // 00716 00717 Lbn = BlocksFromSectors( Vcb, Psn - Vcb->Pcb->Partition[Reference].Physical.Start ); 00718 00719 if (!NT_SUCCESS( UdfReadSectors( IrpContext, 00720 LlBytesFromSectors( Vcb, Psn ), 00721 UdfRawReadSize( Vcb, BlockSize( Vcb )), 00722 TRUE, 00723 VatIcb, 00724 Vcb->TargetDeviceObject ))) { 00725 00726 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... but couldn't read it.\n" )); 00727 00728 continue; 00729 } 00730 00731 // 00732 // First make sure this looks vageuly like a file entry. 00733 // 00734 00735 if (!UdfVerifyDescriptor( IrpContext, 00736 (PDESTAG) VatIcb, 00737 DESTAG_ID_NSR_FILE, 00738 BlockSize( Vcb ), 00739 Lbn, 00740 TRUE )) { 00741 00742 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... but it didn't verify.\n" )); 00743 00744 continue; 00745 } 00746 00747 // 00748 // Make sure this is a NOTSPEC object. We can also presume that a VAT isn't 00749 // linked into any directory, so it would be surprising if the link count was 00750 // nonzero. 00751 // 00752 00753 if (VatIcb->Icbtag.FileType != ICBTAG_FILE_T_NOTSPEC || 00754 VatIcb->LinkCount) { 00755 00756 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... but the type/linkcount is wrong.\n" )); 00757 00758 continue; 00759 } 00760 00761 // 00762 // The VAT must be at least large enough to contain the required information and 00763 // be a multiple of 4byte elements in length. We also have defined a sanity upper 00764 // bound beyond which we never expect to see a VAT go. 00765 // 00766 00767 ASSERT( !LongOffset( UDF_CDUDF_MINIMUM_VAT_SIZE )); 00768 00769 if (VatIcb->InfoLength < UDF_CDUDF_MINIMUM_VAT_SIZE || 00770 VatIcb->InfoLength > UDF_CDUDF_MAXIMUM_VAT_SIZE || 00771 LongOffset( VatIcb->InfoLength )) { 00772 00773 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... but the size looks pretty bogus.\n" )); 00774 00775 continue; 00776 } 00777 00778 // 00779 // At this point we have to take a wild guess that this will be the guy. Since the only 00780 // way to be sure is to look at the very end of the file an look for the regid, we've got 00781 // to go map this thing. 00782 // 00783 00784 // 00785 // This is pretty ugly, but we have to cobble this maybe-Icb into the metadata stream 00786 // so that initialization/use is possible (embedded data!). Normally regular Icb searches 00787 // would have done this for us, but since we have to go through such an amusing search 00788 // procedure that isn't possible. So, add it as a single sector mapping. 00789 // 00790 // Since this lives in a partition, we can just do the "lookup" in the metadata stream. 00791 // If we did not have this guarantee, we'd need to do a bit more of this by hand. 00792 // 00793 // As this is at mount time, we are very sure we are the only person messing with the 00794 // metadata stream. 00795 // 00796 00797 // 00798 // Zap the previous mapping and invalidate the metadata and VAT stream content. 00799 // 00800 00801 if (Vcb->VatFcb) { 00802 00803 UdfResetVmcb( &Vcb->Vmcb ); 00804 00805 UdfUnpinData( IrpContext, &Bcb ); 00806 00807 CcPurgeCacheSection( Vcb->MetadataFcb->FileObject->SectionObjectPointer, 00808 NULL, 00809 0, 00810 FALSE ); 00811 00812 CcPurgeCacheSection( Vcb->VatFcb->FileObject->SectionObjectPointer, 00813 NULL, 00814 0, 00815 FALSE ); 00816 } 00817 00818 Vsn = UdfLookupMetaVsnOfExtent( IrpContext, 00819 Vcb, 00820 Reference, 00821 Lbn, 00822 BlockSize( Vcb ), 00823 TRUE ); 00824 00825 if (Vcb->VatFcb == NULL) { 00826 00827 // 00828 // Now stamp out the Fcb. 00829 // 00830 00831 UdfLockVcb( IrpContext, Vcb ); 00832 UnlockVcb = TRUE; 00833 00834 Vcb->VatFcb = UdfCreateFcb( IrpContext, 00835 *((PFILE_ID) &FileId), 00836 UDFS_NTC_FCB_INDEX, 00837 NULL ); 00838 00839 UdfIncrementReferenceCounts( IrpContext, Vcb->VatFcb, 1, 1 ); 00840 UdfUnlockVcb( IrpContext, Vcb ); 00841 UnlockVcb = FALSE; 00842 00843 // 00844 // Point to the file resource and set the flag that will cause mappings 00845 // to go through the Vmcb 00846 // 00847 00848 Vcb->VatFcb->Resource = &Vcb->FileResource; 00849 } 00850 00851 // 00852 // Now size and try to pick up all of the allocation descriptors for this guy. 00853 // We're going to need to conjure an IcbContext for this. 00854 // 00855 00856 Vcb->VatFcb->AllocationSize.QuadPart = LlSectorAlign( Vcb, VatIcb->InfoLength ); 00857 00858 Vcb->VatFcb->FileSize.QuadPart = 00859 Vcb->VatFcb->ValidDataLength.QuadPart = VatIcb->InfoLength; 00860 00861 // 00862 // Clean out any previous failed attempts. 00863 // 00864 00865 if (CleanupIcbContext) { 00866 00867 UdfCleanupIcbContext( IrpContext, &IcbContext ); 00868 00869 } else { 00870 00871 RtlZeroMemory( &IcbContext, sizeof( ICB_SEARCH_CONTEXT )); 00872 } 00873 00874 // 00875 // Now construct the ICB search context we would have had 00876 // made in the process of normal ICB discovery. Since we 00877 // were unable to do that, gotta do it by hand. 00878 // 00879 00880 IcbContext.Active.View = (PVOID) VatIcb; 00881 IcbContext.Active.Partition = Reference; 00882 IcbContext.Active.Lbn = Lbn; 00883 CleanupIcbContext = TRUE; 00884 00885 UdfInitializeAllocations( IrpContext, 00886 Vcb->VatFcb, 00887 &IcbContext ); 00888 00889 // 00890 // Create or resize the stream file for the VAT as appropriate. 00891 // 00892 00893 if (!FlagOn( Vcb->VatFcb->FcbState, FCB_STATE_INITIALIZED )) { 00894 00895 UdfCreateInternalStream( IrpContext, Vcb, Vcb->VatFcb ); 00896 SetFlag( Vcb->VatFcb->FcbState, FCB_STATE_INITIALIZED ); 00897 00898 } else { 00899 00900 CcSetFileSizes( Vcb->VatFcb->FileObject, (PCC_FILE_SIZES) &Vcb->VatFcb->AllocationSize ); 00901 } 00902 00903 // 00904 // To complete VAT discovery, we now look for the regid at the end of the stream 00905 // that will definitively tell us that this is really a VAT. Bias from the back 00906 // by the previous VAT pointer and the regid itself. We already know the stream 00907 // is big enough by virtue of our preliminary sanity checks. 00908 // 00909 00910 Offset.QuadPart = Vcb->VatFcb->FileSize.QuadPart - UDF_CDUDF_TRAILING_DATA_SIZE; 00911 00912 CcMapData( Vcb->VatFcb->FileObject, 00913 &Offset, 00914 sizeof(REGID), 00915 TRUE, 00916 &Bcb, 00917 &RegId ); 00918 00919 if (!UdfUdfIdentifierContained( RegId, 00920 &UdfVatTableIdentifier, 00921 UDF_VERSION_150, 00922 UDF_VERSION_RECOGNIZED, 00923 OSCLASS_INVALID, 00924 OSIDENTIFIER_INVALID )) { 00925 00926 // 00927 // Oh well, no go here. 00928 // 00929 00930 continue; 00931 } 00932 00933 // 00934 // Got it! 00935 // 00936 00937 break; 00938 } 00939 00940 // 00941 // If we didn't find anything ... 00942 // 00943 00944 if (ThisPass == 4) { 00945 00946 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... and so we didn't find a VAT!\n" )); 00947 00948 UdfRaiseStatus( IrpContext, STATUS_DISK_CORRUPT_ERROR ); 00949 } 00950 00951 // 00952 // Go find the virtual reference so we can further update the Pcb 00953 // with information from the VAT. 00954 // 00955 00956 for (Reference = 0; 00957 Reference < Vcb->Pcb->Partitions; 00958 Reference++) { 00959 00960 if (Vcb->Pcb->Partition[Reference].Type == Virtual) { 00961 00962 break; 00963 } 00964 } 00965 00966 ASSERT( Reference < Vcb->Pcb->Partitions ); 00967 00968 // 00969 // We note the length so we can easily do bounds checking for 00970 // virtual mappings. 00971 // 00972 00973 Offset.QuadPart = (Vcb->VatFcb->FileSize.QuadPart - 00974 UDF_CDUDF_TRAILING_DATA_SIZE) / sizeof(ULONG); 00975 00976 ASSERT( Offset.HighPart == 0 ); 00977 Vcb->Pcb->Partition[Reference].Virtual.Length = Offset.LowPart; 00978 00979 DebugTrace(( 0, Dbg, "UdfUpdateVcbPhase0, ... got it!\n" )); 00980 } 00981 00982 } finally { 00983 00984 DebugUnwind( "UdfUpdateVcbPhase0" ); 00985 00986 UdfUnpinData( IrpContext, &Bcb ); 00987 if (CleanupIcbContext) { UdfCleanupIcbContext( IrpContext, &IcbContext ); } 00988 if (UnlockVcb) { UdfUnlockVcb( IrpContext, Vcb ); } 00989 if (VatIcb) { ExFreePool( VatIcb ); } 00990 } 00991 00992 DebugTrace(( -1, Dbg, "UdfUpdateVcbPhase0 -> VOID\n" )); 00993 }

VOID UdfUpdateVcbPhase1 IN PIRP_CONTEXT  IrpContext,
IN OUT PVCB  Vcb,
IN PNSR_FSD  Fsd
 

Definition at line 997 of file udfs/strucsup.c.

References ASSERT_IRP_CONTEXT, ASSERT_VCB, Dbg, DebugTrace, DebugUnwind, FALSE, FCB_STATE_INITIALIZED, _FCB::FcbState, FsRtlAddLargeMcbEntry(), LlBytesFromSectors, _FCB::Mcb, NULL, PAGED_CODE, PFILE_ID, Physical, PNSR_FSD, SetFlag, TRUE, UdfCleanupIcbContext(), UdfCreateFcb(), UdfCreateInternalStream(), UdfIncrementReferenceCounts, UdfInitializeFcbFromIcbContext(), UdfInitializeFcbMcb(), UdfInitializeIcbContextFromFcb(), UdfLockFcb, UdfLockVcb, UdfLookupActiveIcb(), UDFS_NTC_FCB_DATA, UDFS_NTC_FCB_INDEX, UdfSetFidDirectory, UdfSetFidFromLbAddr, UdfUnlockFcb, and UdfUnlockVcb.

Referenced by UdfMountVolume().

01005 : 01006 01007 This routine is called to perform the final initialization of a Vcb and Vpb 01008 from the volume descriptors on the disk. 01009 01010 Arguments: 01011 01012 Vcb - Vcb for the volume being mounted. We have already done phase 0. 01013 01014 Fsd - The fileset descriptor for this volume. 01015 01016 Return Value: 01017 01018 None 01019 01020 --*/ 01021 01022 { 01023 ICB_SEARCH_CONTEXT IcbContext; 01024 01025 LONGLONG FileId = 0; 01026 01027 PFCB Fcb; 01028 01029 BOOLEAN UnlockVcb = FALSE; 01030 BOOLEAN UnlockFcb = FALSE; 01031 BOOLEAN CleanupIcbContext = FALSE; 01032 01033 ULONG Reference; 01034 01035 ULONG BoundSector = 0; 01036 01037 PAGED_CODE(); 01038 01039 // 01040 // Check input. 01041 // 01042 01043 ASSERT_IRP_CONTEXT( IrpContext ); 01044 ASSERT_VCB( Vcb ); 01045 01046 DebugTrace(( +1, Dbg, "UdfUpdateVcbPhase1, Vcb %08x Fsd %08x\n", Vcb, Fsd )); 01047 01048 // 01049 // Use a try-finally to facilitate cleanup. 01050 // 01051 01052 try { 01053 01054 // 01055 // Do the final internal Fcb's and other Vcb fields. 01056 // 01057 01059 // 01060 // Create the root index and reference it in the Vcb. 01061 // 01063 01064 UdfLockVcb( IrpContext, Vcb ); 01065 UnlockVcb = TRUE; 01066 01067 Vcb->RootIndexFcb = UdfCreateFcb( IrpContext, 01068 *((PFILE_ID) &FileId), 01069 UDFS_NTC_FCB_INDEX, 01070 NULL ); 01071 01072 UdfIncrementReferenceCounts( IrpContext, Vcb->RootIndexFcb, 1, 1 ); 01073 UdfUnlockVcb( IrpContext, Vcb ); 01074 UnlockVcb = FALSE; 01075 01076 // 01077 // Create the File id by hand for this Fcb. 01078 // 01079 01080 UdfSetFidFromLbAddr( Vcb->RootIndexFcb->FileId, Fsd->IcbRoot.Start ); 01081 UdfSetFidDirectory( Vcb->RootIndexFcb->FileId ); 01082 Vcb->RootIndexFcb->RootExtentLength = Fsd->IcbRoot.Length.Length; 01083 01084 // 01085 // Get the direct entry for the root directory and initialize 01086 // the Fcb from it. 01087 // 01088 01089 UdfInitializeIcbContextFromFcb( IrpContext, 01090 &IcbContext, 01091 Vcb->RootIndexFcb ); 01092 CleanupIcbContext = TRUE; 01093 01094 UdfLookupActiveIcb( IrpContext, &IcbContext ); 01095 01096 UdfInitializeFcbFromIcbContext( IrpContext, 01097 Vcb->RootIndexFcb, 01098 &IcbContext ); 01099 01100 UdfCleanupIcbContext( IrpContext, &IcbContext ); 01101 CleanupIcbContext = FALSE; 01102 01103 // 01104 // Create the stream file for the root directory. 01105 // 01106 01107 UdfCreateInternalStream( IrpContext, Vcb, Vcb->RootIndexFcb ); 01108 01110 // 01111 // Now do the volume dasd Fcb. Create this and reference it in the 01112 // Vcb. 01113 // 01115 01116 UdfLockVcb( IrpContext, Vcb ); 01117 UnlockVcb = TRUE; 01118 01119 Vcb->VolumeDasdFcb = UdfCreateFcb( IrpContext, 01120 *((PFILE_ID) &FileId), 01121 UDFS_NTC_FCB_DATA, 01122 NULL ); 01123 01124 UdfIncrementReferenceCounts( IrpContext, Vcb->VolumeDasdFcb, 1, 1 ); 01125 UdfUnlockVcb( IrpContext, Vcb ); 01126 UnlockVcb = FALSE; 01127 01128 Fcb = Vcb->VolumeDasdFcb; 01129 UdfLockFcb( IrpContext, Fcb ); 01130 UnlockFcb = TRUE; 01131 01132 // 01133 // If we were unable to determine a last sector on the media, walk the Pcb and guess 01134 // that it is probably OK to think of the last sector of the last partition as The 01135 // Last Sector. Note that we couldn't do this before since the notion of a last 01136 // sector has significance at mount time, if it had been possible to find one. 01137 // 01138 01139 for ( Reference = 0; 01140 Reference < Vcb->Pcb->Partitions; 01141 Reference++ ) { 01142 01143 if (Vcb->Pcb->Partition[Reference].Type == Physical && 01144 Vcb->Pcb->Partition[Reference].Physical.Start + 01145 Vcb->Pcb->Partition[Reference].Physical.Length > BoundSector) { 01146 01147 BoundSector = Vcb->Pcb->Partition[Reference].Physical.Start + 01148 Vcb->Pcb->Partition[Reference].Physical.Length; 01149 } 01150 } 01151 01152 // 01153 // Note that we cannot restrict the bound by the "physical" bound discovered 01154 // eariler. This is because the MSF format of the TOC request we send is only 01155 // capable of representing about 2.3gb, and a lot of media we will be on that 01156 // responds to TOCs will be quite a bit larger - ex: DVD. 01157 // 01158 // This, of course, barring proper means of discovering media bounding, prohibits 01159 // the possibility of having UDF virtual partitions on DVD-R. 01160 // 01161 01162 // 01163 // Build the mapping from [0, Bound). We have to initialize the Mcb by hand since 01164 // this is usually left to when we lift retrieval information from an Icb in 01165 // UdfInitializeAllocations. 01166 // 01167 01168 UdfInitializeFcbMcb( Fcb ); 01169 01170 FsRtlAddLargeMcbEntry( &Fcb->Mcb, 01171 (LONGLONG) 0, 01172 (LONGLONG) 0, 01173 (LONGLONG) BoundSector ); 01174 01175 Fcb->FileSize.QuadPart += LlBytesFromSectors( Vcb, BoundSector ); 01176 01177 Fcb->AllocationSize.QuadPart = 01178 Fcb->ValidDataLength.QuadPart = Fcb->FileSize.QuadPart; 01179 01180 UdfUnlockFcb( IrpContext, Fcb ); 01181 UnlockFcb = FALSE; 01182 01183 SetFlag( Fcb->FcbState, FCB_STATE_INITIALIZED ); 01184 01185 // 01186 // Point to the file resource. 01187 // 01188 01189 Vcb->VolumeDasdFcb->Resource = &Vcb->FileResource; 01190 01191 Vcb->VolumeDasdFcb->FileAttributes = FILE_ATTRIBUTE_READONLY; 01192 01193 } finally { 01194 01195 DebugUnwind( "UdfUpdateVcbPhase1" ); 01196 01197 if (CleanupIcbContext) { UdfCleanupIcbContext( IrpContext, &IcbContext ); } 01198 01199 if (UnlockFcb) { UdfUnlockFcb( IrpContext, Fcb ); } 01200 if (UnlockVcb) { UdfUnlockVcb( IrpContext, Vcb ); } 01201 } 01202 01203 DebugTrace(( -1, Dbg, "UdfUpdateVcbPhase1 -> VOID\n" )); 01204 01205 return; 01206 }

BOOLEAN UdfVerifyDescriptor IN PIRP_CONTEXT  IrpContext,
IN PDESTAG  Descriptor,
IN USHORT  Tag,
IN ULONG  Size,
IN ULONG  Lbn,
IN BOOLEAN  ReturnError
 

Definition at line 2617 of file udfs/strucsup.c.

References ASSERT, ASSERT_IRP_CONTEXT, Dbg, DebugTrace, DESTAG_VER_CURRENT, FALSE, PAGED_CODE, Size, TRUE, UdfComputeCrc16(), UdfRaiseStatus(), and USHORT.

Referenced by UdfFindAnchorVolumeDescriptor(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfGetNextAllocationPostProcessing(), UdfInitializeIcbContextFromFcb(), UdfLoadSparingTables(), UdfLookupActiveIcbInExtent(), UdfLookupDirEntryPostProcessing(), UdfLookupEa(), and UdfUpdateVcbPhase0().

02628 : 02629 02630 This routine verifies that a descriptor using a Descriptor tag (3/7.2) is 02631 consistent with itself and the descriptor data. 02632 02633 Arguments: 02634 02635 Descriptor - This is the pointer to the descriptor tag, which is always 02636 at the front of a descriptor 02637 02638 Tag - The Tag Identifier this descriptor should have 02639 02640 Size - Size of this descriptor 02641 02642 Lbn - The logical block number this descriptor should claim it is recorded at 02643 02644 ReturnError - Whether this routine should return an error or raise 02645 02646 Return Value: 02647 02648 Boolean TRUE if the descriptor is consistent, FALSE or a raised status of 02649 STATUS_DISK_CORRUPT_ERROR otherwise. 02650 02651 --*/ 02652 02653 { 02654 UCHAR Checksum = 0; 02655 PCHAR CheckPtr; 02656 USHORT Crc; 02657 02658 #ifdef UDF_SANITY 02659 02660 VERIFY_FAILURE FailReason = Nothing; 02661 02662 #endif 02663 02664 // 02665 // Check our inputs 02666 // 02667 02668 ASSERT_IRP_CONTEXT( IrpContext ); 02669 02670 PAGED_CODE(); 02671 02672 #ifdef UDF_SANITY 02673 02674 if (UdfNoisyVerifyDescriptor) { 02675 02676 goto BeNoisy; 02677 } 02678 02679 RegularEntry: 02680 02681 #endif 02682 02683 // 02684 // The version of the Descriptor Tag specified in ISO 13346 and used in 02685 // UDF is a particular value; presumeably, previous versions were used 02686 // in some older revision of the standard. 02687 // 02688 02689 #ifdef UDF_SUPPORT_NONSTANDARD_ADAPTEC 02690 02691 // 02692 // Let bad descriptor version numbers through. 02693 // 02694 // Reasons: 02695 // 02696 // ADAPTEC - early CDUDF wrote version 1 as opposed to version 2. 02697 // 02698 02699 if (TRUE) 02700 02701 #else 02702 02703 if (Descriptor->Version == DESTAG_VER_CURRENT) 02704 02705 #endif 02706 02707 { 02708 02709 // 02710 // A descriptor is stamped in four ways. First, the Lbn of the sector 02711 // containing the descriptor is written here. (3/7.2.8) 02712 // 02713 02714 02715 #ifdef UDF_SUPPORT_NONSTANDARD_HP 02716 02717 // 02718 // Let bad lbn through. 02719 // 02720 // Reasons: 02721 // 02722 // HP - Rob Sim;s CD-RW model disc doesn't record this reliably. 02723 // 02724 02725 if (TRUE) 02726 02727 #else 02728 02729 if (Descriptor->Lbn == Lbn) 02730 02731 #endif 02732 { 02733 // 02734 // Next, the descriptor tag itself has an identifier which should match 02735 // the type we expect to find here (3/7.2.1) 02736 // 02737 02738 if (Descriptor->Ident == Tag) { 02739 02740 // 02741 // Next, the descriptor tag itself is checksumed, minus the byte 02742 // used to store the checksum. (3/7.2.3) 02743 // 02744 02745 for (CheckPtr = (PCHAR) Descriptor; 02746 CheckPtr < (PCHAR) Descriptor + FIELD_OFFSET( DESTAG, Checksum ); 02747 CheckPtr++) { 02748 02749 Checksum += *CheckPtr; 02750 } 02751 02752 for (CheckPtr = (PCHAR) Descriptor + FIELD_OFFSET( DESTAG, Checksum ) + sizeof(UCHAR); 02753 CheckPtr < (PCHAR) Descriptor + sizeof(DESTAG); 02754 CheckPtr++) { 02755 02756 Checksum += *CheckPtr; 02757 } 02758 02759 if (Descriptor->Checksum == Checksum) { 02760 02761 // 02762 // Now we check that the CRC in the Descriptor tag is sized sanely 02763 // and matches the Descriptor data. (3/7.2.6) 02764 // 02765 02766 #ifdef UDF_SUPPORT_NONSTANDARD_HP 02767 02768 // 02769 // Let zero-length CRCs through. 02770 // 02771 // Reasons: 02772 // 02773 // HP - early CDUDF didn't CRC the terminationg descriptors (tag 8). 02774 // 02775 02776 if (!Descriptor->CRCLen || 02777 Descriptor->CRCLen <= Size - sizeof(DESTAG)) 02778 #else 02779 02780 if (Descriptor->CRCLen && 02781 Descriptor->CRCLen <= Size - sizeof(DESTAG)) 02782 02783 #endif 02784 { 02785 02786 Crc = UdfComputeCrc16( (PCHAR) Descriptor + sizeof(DESTAG), 02787 Descriptor->CRCLen ); 02788 02789 #ifdef UDF_SUPPORT_NONSTANDARD_HP 02790 02791 // 02792 // Let zero-length CRCs through. 02793 // 02794 // Reasons: as above. 02795 // 02796 02797 if (!Descriptor->CRCLen || 02798 Descriptor->CRC == Crc) 02799 02800 #else 02801 02802 if (Descriptor->CRC == Crc) 02803 02804 #endif 02805 { 02806 02807 // 02808 // This descriptor checks out. 02809 // 02810 02811 #ifdef UDF_SANITY 02812 if (UdfNoisyVerifyDescriptor) { 02813 02814 DebugTrace(( -1, Dbg, "UdfVerifyDescriptor -> TRUE\n" )); 02815 } 02816 #endif 02817 return TRUE; 02818 02819 } else { 02820 #ifdef UDF_SANITY 02821 FailReason = BadCrc; 02822 goto ReportFailure; 02823 #endif 02824 } 02825 02826 } else { 02827 #ifdef UDF_SANITY 02828 FailReason = BadCrcLength; 02829 goto ReportFailure; 02830 #endif 02831 } 02832 02833 } else { 02834 #ifdef UDF_SANITY 02835 FailReason = BadChecksum; 02836 goto ReportFailure; 02837 #endif 02838 } 02839 02840 } else { 02841 #ifdef UDF_SANITY 02842 FailReason = BadTag; 02843 goto ReportFailure; 02844 #endif 02845 } 02846 02847 } else { 02848 #ifdef UDF_SANITY 02849 FailReason = BadLbn; 02850 goto ReportFailure; 02851 #endif 02852 } 02853 02854 } else { 02855 #ifdef UDF_SANITY 02856 FailReason = BadDestagVersion; 02857 goto ReportFailure; 02858 #endif 02859 } 02860 02861 #ifdef UDF_SANITY 02862 02863 BeNoisy: 02864 02865 DebugTrace(( +1, Dbg, 02866 "UdfVerifyDescriptor, Destag %08x, Tag %x, Size %x, Lbn %x\n", 02867 Descriptor, 02868 Tag, 02869 Size, 02870 Lbn )); 02871 02872 if (FailReason == Nothing) { 02873 02874 goto RegularEntry; 02875 02876 } else if (!UdfNoisyVerifyDescriptor) { 02877 02878 goto ReallyReportFailure; 02879 } 02880 02881 ReportFailure: 02882 02883 if (!UdfNoisyVerifyDescriptor) { 02884 02885 goto BeNoisy; 02886 } 02887 02888 ReallyReportFailure: 02889 02890 switch (FailReason) { 02891 case BadLbn: 02892 DebugTrace(( 0, Dbg, 02893 "Lbn mismatch - Lbn %x != expected %x\n", 02894 Descriptor->Lbn, 02895 Lbn )); 02896 break; 02897 02898 case BadTag: 02899 DebugTrace(( 0, Dbg, 02900 "Tag mismatch - Ident %x != expected %x\n", 02901 Descriptor->Ident, 02902 Tag )); 02903 break; 02904 02905 case BadChecksum: 02906 DebugTrace(( 0, Dbg, 02907 "Checksum mismatch - Checksum %x != descriptor's %x\n", 02908 Checksum, 02909 Descriptor->Checksum )); 02910 break; 02911 02912 case BadCrcLength: 02913 DebugTrace(( 0, Dbg, 02914 "CRC'd size bad - CrcLen %x is 0 or > max %x\n", 02915 Descriptor->CRCLen, 02916 Size - sizeof(DESTAG) )); 02917 break; 02918 02919 case BadCrc: 02920 DebugTrace(( 0, Dbg, 02921 "CRC mismatch - Crc %x != descriptor's %x\n", 02922 Crc, 02923 Descriptor->CRC )); 02924 break; 02925 02926 case BadDestagVersion: 02927 DebugTrace(( 0, Dbg, 02928 "Bad Destag Verion - %x != descriptor's %x\n", 02929 DESTAG_VER_CURRENT, 02930 Descriptor->Version )); 02931 break; 02932 02933 default: 02934 ASSERT( FALSE ); 02935 } 02936 02937 DebugTrace(( -1, Dbg, "UdfVerifyDescriptor -> FALSE\n" )); 02938 02939 #endif 02940 02941 if (!ReturnError) { 02942 02943 UdfRaiseStatus( IrpContext, STATUS_CRC_ERROR ); 02944 } 02945 02946 return FALSE; 02947 }

BOOLEAN UdfVerifyFcbOperation IN PIRP_CONTEXT IrpContext  OPTIONAL,
IN PFCB  Fcb
 

Definition at line 760 of file udfs/verfysup.c.

References DO_VERIFY_VOLUME, FALSE, FlagOn, _DEVICE_OBJECT::Flags, IoSetHardErrorOrVerifyDevice(), NTSTATUS(), PAGED_CODE, _VPB::RealDevice, SetFlag, Status, TRUE, UdfRaiseStatus(), _VCB::VcbCondition, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbMountInProgress, VcbNotMounted, and _VCB::Vpb.

Referenced by UdfCommonLockControl(), UdfCommonQueryInfo(), UdfCommonRead(), UdfCommonSetInfo(), UdfFastLock(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfOplockRequest(), and UdfQueryDirectory().

00767 : 00768 00769 This routine is called to verify that the state of the Fcb is valid 00770 to allow the current operation to continue. We use the state of the 00771 Vcb, target device and type of operation to determine this. 00772 00773 Arguments: 00774 00775 IrpContext - IrpContext for the request. If not present then we 00776 were called from the fast IO path. 00777 00778 Fcb - Fcb to perform the request on. 00779 00780 Return Value: 00781 00782 BOOLEAN - TRUE if the request can continue, FALSE otherwise. 00783 00784 --*/ 00785 00786 { 00787 NTSTATUS Status = STATUS_SUCCESS; 00788 PVCB Vcb = Fcb->Vcb; 00789 PDEVICE_OBJECT RealDevice = Vcb->Vpb->RealDevice; 00790 00791 PAGED_CODE(); 00792 00793 // 00794 // Fail immediately if the volume is in the progress of being dismounted 00795 // or has been marked invalid. 00796 // 00797 00798 if ((Vcb->VcbCondition == VcbInvalid) || 00799 (Vcb->VcbCondition == VcbDismountInProgress)) { 00800 00801 if (ARGUMENT_PRESENT( IrpContext )) { 00802 00803 UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID ); 00804 } 00805 00806 return FALSE; 00807 } 00808 00809 // 00810 // Always fail if the volume needs to be verified. 00811 // 00812 00813 if (FlagOn( RealDevice->Flags, DO_VERIFY_VOLUME )) { 00814 00815 if (ARGUMENT_PRESENT( IrpContext )) { 00816 00817 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, 00818 RealDevice ); 00819 00820 UdfRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED ); 00821 } 00822 00823 return FALSE; 00824 00825 // 00826 // All operations are allowed on mounted volumes. 00827 // 00828 00829 } else if ((Vcb->VcbCondition == VcbMounted) || 00830 (Vcb->VcbCondition == VcbMountInProgress)) { 00831 00832 return TRUE; 00833 00834 // 00835 // Fail all requests for fast Io on other Vcb conditions. 00836 // 00837 00838 } else if (!ARGUMENT_PRESENT( IrpContext )) { 00839 00840 return FALSE; 00841 00842 // 00843 // The remaining case is VcbNotMounted. 00844 // Mark the device to be verified and raise WRONG_VOLUME. 00845 // 00846 00847 } else if (Vcb->VcbCondition == VcbNotMounted) { 00848 00849 if (ARGUMENT_PRESENT( IrpContext )) { 00850 00851 SetFlag(RealDevice->Flags, DO_VERIFY_VOLUME); 00852 00853 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, RealDevice ); 00854 UdfRaiseStatus( IrpContext, STATUS_WRONG_VOLUME ); 00855 } 00856 00857 return FALSE; 00858 } 00859 00860 return TRUE; 00861 }

VOID UdfVerifyVcb IN PIRP_CONTEXT  IrpContext,
IN PVCB  Vcb
 

Definition at line 603 of file udfs/verfysup.c.

References DO_VERIFY_VOLUME, FALSE, FlagOn, IoSetHardErrorOrVerifyDevice(), NT_SUCCESS, NTSTATUS(), PAGED_CODE, SetFlag, Status, UdfIsRawDevice, UdfNormalizeAndRaiseStatus(), UdfPerformDevIoCtrl(), UdfRaiseStatus(), VCB_STATE_REMOVABLE_MEDIA, VcbDismountInProgress, VcbInvalid, VcbMounted, VcbMountInProgress, VcbNotMounted, and VOID().

Referenced by UdfCommonCreate(), UdfCommonDevControl(), UdfCommonQueryVolInfo(), UdfIsVolumeMounted(), UdfLockVolume(), and UdfNotifyChangeDirectory().

00610 : 00611 00612 This routine checks that the current Vcb is valid and currently mounted 00613 on the device. It will raise on an error condition. 00614 00615 We check whether the volume needs verification and the current state 00616 of the Vcb. 00617 00618 Arguments: 00619 00620 Vcb - This is the volume to verify. 00621 00622 Return Value: 00623 00624 None 00625 00626 --*/ 00627 00628 { 00629 NTSTATUS Status; 00630 IO_STATUS_BLOCK Iosb; 00631 ULONG MediaChangeCount = 0; 00632 00633 PAGED_CODE(); 00634 00635 // 00636 // Fail immediately if the volume is in the progress of being dismounted 00637 // or has been marked invalid. 00638 // 00639 00640 if ((Vcb->VcbCondition == VcbInvalid) || 00641 (Vcb->VcbCondition == VcbDismountInProgress)) { 00642 00643 UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID ); 00644 } 00645 00646 // 00647 // If the media is removable and the verify volume flag in the 00648 // device object is not set then we want to ping the device 00649 // to see if it needs to be verified 00650 // 00651 00652 if ((Vcb->VcbCondition != VcbMountInProgress) && 00653 FlagOn( Vcb->VcbState, VCB_STATE_REMOVABLE_MEDIA ) && 00654 !FlagOn( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME )) { 00655 00656 Status = UdfPerformDevIoCtrl( IrpContext, 00657 ( Vcb->Vpb->RealDevice->DeviceType == FILE_DEVICE_CD_ROM ? 00658 IOCTL_CDROM_CHECK_VERIFY : 00659 IOCTL_DISK_CHECK_VERIFY ), 00660 Vcb->TargetDeviceObject, 00661 &MediaChangeCount, 00662 sizeof(ULONG), 00663 FALSE, 00664 FALSE, 00665 &Iosb ); 00666 00667 if (Iosb.Information != sizeof(ULONG)) { 00668 00669 // 00670 // Be safe about the count in case the driver didn't fill it in 00671 // 00672 00673 MediaChangeCount = 0; 00674 } 00675 00676 // 00677 // If the volume is now an empty device, or we have receieved a 00678 // bare STATUS_VERIFY_REQUIRED (various hardware conditions such 00679 // as bus resets, etc., will trigger this in the drivers), or the 00680 // media change count has moved since we last inspected the device, 00681 // then mark the volume to be verified. 00682 // 00683 00684 if ((Vcb->VcbCondition == VcbMounted && 00685 UdfIsRawDevice( IrpContext, Status )) || 00686 (Status == STATUS_VERIFY_REQUIRED) || 00687 (NT_SUCCESS(Status) && 00688 (Vcb->MediaChangeCount != MediaChangeCount))) { 00689 00690 SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME ); 00691 00692 // 00693 // If the volume is not mounted and we got a media change count, 00694 // update the Vcb so we do not trigger a verify again at this 00695 // count value. If the verify->mount path detects that the media 00696 // has actually changed and this Vcb is valid again, this will have 00697 // done nothing. We are already synchronized since the caller has 00698 // the Vcb. 00699 // 00700 00701 if ((Vcb->VcbCondition == VcbNotMounted) && 00702 NT_SUCCESS(Status)) { 00703 00704 Vcb->MediaChangeCount = MediaChangeCount; 00705 } 00706 00707 // 00708 // Raise the error condition otherwise. 00709 // 00710 00711 } else if (!NT_SUCCESS( Status )) { 00712 00713 UdfNormalizeAndRaiseStatus( IrpContext, Status ); 00714 } 00715 00716 } 00717 00718 // 00719 // The Vcb may be mounted but the underlying real device may need to be verified. 00720 // If it does then we'll set the Iosb in the irp to be our real device 00721 // and raise Verify required 00722 // 00723 00724 if (FlagOn( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME )) { 00725 00726 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, 00727 Vcb->Vpb->RealDevice ); 00728 00729 UdfRaiseStatus( IrpContext, STATUS_VERIFY_REQUIRED ); 00730 } 00731 00732 // 00733 // Based on the condition of the Vcb we'll either return to our 00734 // caller or raise an error condition 00735 // 00736 00737 switch (Vcb->VcbCondition) { 00738 00739 case VcbNotMounted: 00740 00741 SetFlag( Vcb->Vpb->RealDevice->Flags, DO_VERIFY_VOLUME ); 00742 00743 IoSetHardErrorOrVerifyDevice( IrpContext->Irp, Vcb->Vpb->RealDevice ); 00744 00745 UdfRaiseStatus( IrpContext, STATUS_WRONG_VOLUME ); 00746 break; 00747 00748 case VcbInvalid: 00749 case VcbDismountInProgress : 00750 00751 UdfRaiseStatus( IrpContext, STATUS_FILE_INVALID ); 00752 break; 00753 } 00754 00755 return; 00756 }

BOOLEAN UdfVmcbLbnToVbn IN PVMCB  Vmcb,
IN LBN  Lbn,
OUT PVBN  Vbn,
OUT PULONG SectorCount  OPTIONAL
 

Definition at line 553 of file vmcbsup.c.

References Dbg, DebugTrace, DebugUnwind, Executive, FALSE, KeReleaseMutex(), KernelMode, KeWaitForSingleObject(), NULL, PAGED_CODE, UdfVmcbLookupMcbEntry(), and VOID().

Referenced by UdfLookupMetaVsnOfExtent().

00562 : 00563 00564 This routine translates an LBN to a VBN. 00565 00566 Arguments: 00567 00568 Vmcb - Supplies the VMCB structure being queried. 00569 00570 Lbn - Supplies the LBN to translate from. 00571 00572 Vbn - Recieves the VBN mapped by the input LBN. This value is 00573 only valid if the function result is TRUE. 00574 00575 SectorCount - Optionally receives the number of sectors corresponding 00576 to the run. 00577 00578 Return Value: 00579 00580 BOOLEAN - TRUE if the mapping is valid and FALSE otherwise. 00581 00582 --*/ 00583 00584 { 00585 BOOLEAN Result; 00586 00587 PAGED_CODE(); 00588 00589 DebugTrace(( +1, Dbg, "UdfVmcbLbnToVbn, Lbn = %08x\n", Lbn )); 00590 00591 // 00592 // If the requested Lbn is greater than the maximum allowed Lbn 00593 // then the result is FALSE 00594 // 00595 00596 if (Lbn > Vmcb->MaximumLbn) { 00597 00598 DebugTrace(( -1, Dbg, "Lbn too large, UdfVmcbLbnToVbn -> FALSE\n" )); 00599 00600 return FALSE; 00601 } 00602 00603 // 00604 // Now grab the mutex for the vmcb 00605 // 00606 00607 (VOID)KeWaitForSingleObject( &Vmcb->Mutex, 00608 Executive, 00609 KernelMode, 00610 FALSE, 00611 (PLARGE_INTEGER) NULL ); 00612 00613 try { 00614 00615 Result = UdfVmcbLookupMcbEntry( &Vmcb->LbnIndexed, 00616 Lbn, 00617 Vbn, 00618 SectorCount, 00619 NULL ); 00620 00621 DebugTrace(( 0, Dbg, "*Vbn = %08x\n", *Vbn )); 00622 00623 } finally { 00624 00625 (VOID) KeReleaseMutex( &Vmcb->Mutex, FALSE ); 00626 00627 00628 DebugUnwind("UdfVmcbLbnToVbn"); 00629 DebugTrace(( -1, Dbg, "UdfVmcbLbnToVbn -> Result = %08x\n", Result )); 00630 } 00631 00632 return Result; 00633 }

BOOLEAN UdfVmcbVbnToLbn IN PVMCB  Vmcb,
IN VBN  Vbn,
OUT PLBN  Lbn,
OUT PULONG SectorCount  OPTIONAL
 


Generated on Sat May 15 19:45:51 2004 for test by doxygen 1.3.7