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

fsrtl.h File Reference

Go to the source code of this file.

Classes

struct  _FSRTL_COMMON_FCB_HEADER
struct  _FSRTL_ADVANCED_FCB_HEADER
struct  _EOF_WAIT_BLOCK
struct  _FSRTL_AUXILIARY_BUFFER
struct  _FILE_LOCK_INFO
struct  _FILE_LOCK
struct  TUNNEL
struct  _LARGE_MCB
struct  _MCB
struct  _FSRTL_FILTER_CONTEXT

Defines

#define FSRTL_FLAG_FILE_MODIFIED   (0x01)
#define FSRTL_FLAG_FILE_LENGTH_CHANGED   (0x02)
#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES   (0x04)
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX   (0x08)
#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH   (0x10)
#define FSRTL_FLAG_USER_MAPPED_FILE   (0x20)
#define FSRTL_FLAG_ADVANCED_HEADER   (0x40)
#define FSRTL_FLAG_EOF_ADVANCE_ACTIVE   (0x80)
#define FSRTL_FLAG2_DO_MODIFIED_WRITE   (0x01)
#define FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS   (0x02)
#define FSRTL_FLAG2_PURGE_WHEN_MAPPED   (0x04)
#define FSRTL_FSP_TOP_LEVEL_IRP   0x01
#define FSRTL_CACHE_TOP_LEVEL_IRP   0x02
#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP   0x03
#define FSRTL_FAST_IO_TOP_LEVEL_IRP   0x04
#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG   0x04
#define FSRTL_AUXILIARY_FLAG_DEALLOCATE   0x00000001
#define FsRtlSetTopLevelIrpForModWriter()
#define FsRtlFastLock(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11)
#define FsRtlAreThereCurrentFileLocks(FL)
#define LEGAL_ANSI_CHARACTER_ARRAY   FsRtlLegalAnsiCharacterArray
#define NLS_MB_CODE_PAGE_TAG   NlsMbOemCodePageTag
#define NLS_OEM_LEAD_BYTE_INFO   NlsOemLeadByteInfo
#define FSRTL_FAT_LEGAL   0x01
#define FSRTL_HPFS_LEGAL   0x02
#define FSRTL_NTFS_LEGAL   0x04
#define FSRTL_WILD_CHARACTER   0x08
#define FSRTL_OLE_LEGAL   0x10
#define FSRTL_NTFS_STREAM_LEGAL   (FSRTL_NTFS_LEGAL | FSRTL_OLE_LEGAL)
#define FsRtlIsAnsiCharacterWild(C)
#define FsRtlIsAnsiCharacterLegalFat(C, WILD_OK)
#define FsRtlIsAnsiCharacterLegalHpfs(C, WILD_OK)
#define FsRtlIsAnsiCharacterLegalNtfs(C, WILD_OK)
#define FsRtlIsAnsiCharacterLegalNtfsStream(C, WILD_OK)
#define FsRtlIsAnsiCharacterLegal(C, FLAGS)
#define FsRtlTestAnsiCharacter(C, DEFAULT_RET, WILD_OK, FLAGS)
#define FsRtlIsLeadDbcsCharacter(DBCS_CHAR)
#define FsRtlAllocatePoolWithTag(PoolType, NumberOfBytes, Tag)
#define FsRtlAllocatePoolWithQuotaTag(PoolType, NumberOfBytes, Tag)
#define FSRTL_VOLUME_DISMOUNT   1
#define FSRTL_VOLUME_DISMOUNT_FAILED   2
#define FSRTL_VOLUME_LOCK   3
#define FSRTL_VOLUME_LOCK_FAILED   4
#define FSRTL_VOLUME_UNLOCK   5
#define FSRTL_VOLUME_MOUNT   6
#define FsRtlIsUnicodeCharacterWild(C)
#define FsRtlLookupFilterContext(fo, oid, iid)
#define FsRtlCompleteRequest(IRP, STATUS)
#define FsRtlEnterFileSystem()
#define FsRtlExitFileSystem()

Typedefs

typedef ULONG LBN
typedef LBNPLBN
typedef ULONG VBN
typedef VBNPVBN
typedef enum _FAST_IO_POSSIBLE FAST_IO_POSSIBLE
typedef _FSRTL_COMMON_FCB_HEADER FSRTL_COMMON_FCB_HEADER
typedef FSRTL_COMMON_FCB_HEADERPFSRTL_COMMON_FCB_HEADER
typedef _FSRTL_ADVANCED_FCB_HEADER FSRTL_ADVANCED_FCB_HEADER
typedef FSRTL_ADVANCED_FCB_HEADERPFSRTL_ADVANCED_FCB_HEADER
typedef _EOF_WAIT_BLOCK EOF_WAIT_BLOCK
typedef EOF_WAIT_BLOCKPEOF_WAIT_BLOCK
typedef _FSRTL_AUXILIARY_BUFFER FSRTL_AUXILIARY_BUFFER
typedef FSRTL_AUXILIARY_BUFFERPFSRTL_AUXILIARY_BUFFER
typedef _FILE_LOCK_INFO FILE_LOCK_INFO
typedef FILE_LOCK_INFOPFILE_LOCK_INFO
typedef NTSTATUS(* PCOMPLETE_LOCK_IRP_ROUTINE )(IN PVOID Context, IN PIRP Irp)
typedef VOID(* PUNLOCK_ROUTINE )(IN PVOID Context, IN PFILE_LOCK_INFO FileLockInfo)
typedef _FILE_LOCK FILE_LOCK
typedef FILE_LOCKPFILE_LOCK
typedef * PTUNNEL
typedef enum _FSRTL_COMPARISON_RESULT FSRTL_COMPARISON_RESULT
typedef _LARGE_MCB LARGE_MCB
typedef LARGE_MCBPLARGE_MCB
typedef _MCB MCB
typedef MCBPMCB
typedef PVOID OPLOCK
typedef PVOID * POPLOCK
typedef VOID(* POPLOCK_WAIT_COMPLETE_ROUTINE )(IN PVOID Context, IN PIRP Irp)
typedef VOID(* POPLOCK_FS_PREPOST_IRP )(IN PVOID Context, IN PIRP Irp)
typedef PVOID PNOTIFY_SYNC
typedef BOOLEAN(* PCHECK_FOR_TRAVERSE_ACCESS )(IN PVOID NotifyContext, IN PVOID TargetContext, IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
typedef VOID(* PFSRTL_STACK_OVERFLOW_ROUTINE )(IN PVOID Context, IN PKEVENT Event)
typedef _FSRTL_FILTER_CONTEXT FSRTL_FILTER_CONTEXT
typedef _FSRTL_FILTER_CONTEXTPFSRTL_FILTER_CONTEXT

Enumerations

enum  _FAST_IO_POSSIBLE { FastIoIsNotPossible = 0, FastIoIsPossible, FastIoIsQuestionable }
enum  _FSRTL_COMPARISON_RESULT { LessThan = -1, EqualTo = 0, GreaterThan = 1 }

Functions

NTKERNELAPI BOOLEAN FsRtlInitSystem ()
NTKERNELAPI BOOLEAN FsRtlCopyRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, OUT PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlCopyWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN BOOLEAN Wait, IN ULONG LockKey, IN PVOID Buffer, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlMdlRead (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
BOOLEAN FsRtlMdlReadComplete (IN PFILE_OBJECT FileObject, IN PMDL MdlChain)
NTKERNELAPI BOOLEAN FsRtlPrepareMdlWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus)
BOOLEAN FsRtlMdlWriteComplete (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain)
NTKERNELAPI BOOLEAN FsRtlMdlReadDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlMdlReadCompleteDev (IN PFILE_OBJECT FileObject, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlPrepareMdlWriteDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN ULONG Length, IN ULONG LockKey, OUT PMDL *MdlChain, OUT PIO_STATUS_BLOCK IoStatus, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlMdlWriteCompleteDev (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PMDL MdlChain, IN PDEVICE_OBJECT DeviceObject)
NTKERNELAPI BOOLEAN FsRtlAcquireFileForModWrite (IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER StartingOffset, OUT PERESOURCE *ResourceToRelease)
NTKERNELAPI VOID FsRtlReleaseFileForModWrite (IN PFILE_OBJECT FileObject, IN PERESOURCE ResourceToRelease)
NTKERNELAPI VOID FsRtlAcquireFileForCcFlush (IN PFILE_OBJECT FileObject)
NTKERNELAPI VOID FsRtlReleaseFileForCcFlush (IN PFILE_OBJECT FileObject)
NTKERNELAPI VOID FsRtlAcquireFileExclusive (IN PFILE_OBJECT FileObject)
NTKERNELAPI VOID FsRtlReleaseFile (IN PFILE_OBJECT FileObject)
NTSTATUS FsRtlGetFileSize (IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
NTSTATUS FsRtlSetFileSize (IN PFILE_OBJECT FileObject, IN OUT PLARGE_INTEGER FileSize)
NTKERNELAPI BOOLEAN FsRtlIsTotalDeviceFailure (IN NTSTATUS Status)
PFILE_LOCK FsRtlAllocateFileLock (IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
VOID FsRtlFreeFileLock (IN PFILE_LOCK FileLock)
NTKERNELAPI VOID FsRtlInitializeFileLock (IN PFILE_LOCK FileLock, IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine OPTIONAL, IN PUNLOCK_ROUTINE UnlockRoutine OPTIONAL)
NTKERNELAPI VOID FsRtlUninitializeFileLock (IN PFILE_LOCK FileLock)
NTKERNELAPI NTSTATUS FsRtlProcessFileLock (IN PFILE_LOCK FileLock, IN PIRP Irp, IN PVOID Context OPTIONAL)
NTKERNELAPI BOOLEAN FsRtlCheckLockForReadAccess (IN PFILE_LOCK FileLock, IN PIRP Irp)
NTKERNELAPI BOOLEAN FsRtlCheckLockForWriteAccess (IN PFILE_LOCK FileLock, IN PIRP Irp)
NTKERNELAPI BOOLEAN FsRtlFastCheckLockForRead (IN PFILE_LOCK FileLock, IN PLARGE_INTEGER StartingByte, IN PLARGE_INTEGER Length, IN ULONG Key, IN PFILE_OBJECT FileObject, IN PVOID ProcessId)
NTKERNELAPI BOOLEAN FsRtlFastCheckLockForWrite (IN PFILE_LOCK FileLock, IN PLARGE_INTEGER StartingByte, IN PLARGE_INTEGER Length, IN ULONG Key, IN PVOID FileObject, IN PVOID ProcessId)
NTKERNELAPI PFILE_LOCK_INFO FsRtlGetNextFileLock (IN PFILE_LOCK FileLock, IN BOOLEAN Restart)
NTKERNELAPI NTSTATUS FsRtlFastUnlockSingle (IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN LARGE_INTEGER UNALIGNED *FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS ProcessId, IN ULONG Key, IN PVOID Context OPTIONAL, IN BOOLEAN AlreadySynchronized)
NTKERNELAPI NTSTATUS FsRtlFastUnlockAll (IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS ProcessId, IN PVOID Context OPTIONAL)
NTKERNELAPI NTSTATUS FsRtlFastUnlockAllByKey (IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PEPROCESS ProcessId, IN ULONG Key, IN PVOID Context OPTIONAL)
NTKERNELAPI BOOLEAN FsRtlPrivateLock (IN PFILE_LOCK FileLock, IN PFILE_OBJECT FileObject, IN PLARGE_INTEGER FileOffset, IN PLARGE_INTEGER Length, IN PEPROCESS ProcessId, IN ULONG Key, IN BOOLEAN FailImmediately, IN BOOLEAN ExclusiveLock, OUT PIO_STATUS_BLOCK Iosb, IN PIRP Irp, IN PVOID Context, IN BOOLEAN AlreadySynchronized)
NTKERNELAPI VOID FsRtlInitializeTunnelCache (IN TUNNEL *Cache)
NTKERNELAPI VOID FsRtlAddToTunnelCache (IN TUNNEL *Cache, IN ULONGLONG DirectoryKey, IN UNICODE_STRING *ShortName, IN UNICODE_STRING *LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN VOID *Data)
NTKERNELAPI BOOLEAN FsRtlFindInTunnelCache (IN TUNNEL *Cache, IN ULONGLONG DirectoryKey, IN UNICODE_STRING *Name, OUT UNICODE_STRING *ShortName, OUT UNICODE_STRING *LongName, IN OUT ULONG *DataLength, OUT VOID *Data)
NTKERNELAPI VOID FsRtlDeleteKeyFromTunnelCache (IN TUNNEL *Cache, IN ULONGLONG DirectoryKey)
NTKERNELAPI VOID FsRtlDeleteTunnelCache (IN TUNNEL *Cache)
NTKERNELAPI VOID FsRtlDissectDbcs (IN ANSI_STRING InputName, OUT PANSI_STRING FirstPart, OUT PANSI_STRING RemainingPart)
NTKERNELAPI BOOLEAN FsRtlDoesDbcsContainWildCards (IN PANSI_STRING Name)
NTKERNELAPI BOOLEAN FsRtlIsDbcsInExpression (IN PANSI_STRING Expression, IN PANSI_STRING Name)
NTKERNELAPI BOOLEAN FsRtlIsFatDbcsLegal (IN ANSI_STRING DbcsName, IN BOOLEAN WildCardsPermissible, IN BOOLEAN PathNamePermissible, IN BOOLEAN LeadingBackslashPermissible)
NTKERNELAPI BOOLEAN FsRtlIsHpfsDbcsLegal (IN ANSI_STRING DbcsName, IN BOOLEAN WildCardsPermissible, IN BOOLEAN PathNamePermissible, IN BOOLEAN LeadingBackslashPermissible)
NTKERNELAPI NTSTATUS FsRtlNormalizeNtstatus (IN NTSTATUS Exception, IN NTSTATUS GenericException)
NTKERNELAPI BOOLEAN FsRtlIsNtstatusExpected (IN NTSTATUS Exception)
NTKERNELAPI PERESOURCE FsRtlAllocateResource ()
NTKERNELAPI VOID FsRtlInitializeLargeMcb (IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
NTKERNELAPI VOID FsRtlUninitializeLargeMcb (IN PLARGE_MCB Mcb)
NTKERNELAPI VOID FsRtlResetLargeMcb (IN PLARGE_MCB Mcb, IN BOOLEAN SelfSynchronized)
NTKERNELAPI VOID FsRtlTruncateLargeMcb (IN PLARGE_MCB Mcb, IN LONGLONG Vbn)
NTKERNELAPI BOOLEAN FsRtlAddLargeMcbEntry (IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
NTKERNELAPI VOID FsRtlRemoveLargeMcbEntry (IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
NTKERNELAPI BOOLEAN FsRtlLookupLargeMcbEntry (IN PLARGE_MCB Mcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL)
NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntry (IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn)
NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntryAndIndex (IN PLARGE_MCB OpaqueMcb, OUT PLONGLONG LargeVbn, OUT PLONGLONG LargeLbn, OUT PULONG Index)
NTKERNELAPI ULONG FsRtlNumberOfRunsInLargeMcb (IN PLARGE_MCB Mcb)
NTKERNELAPI BOOLEAN FsRtlGetNextLargeMcbEntry (IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
NTKERNELAPI BOOLEAN FsRtlSplitLargeMcb (IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Amount)
NTKERNELAPI VOID FsRtlInitializeMcb (IN PMCB Mcb, IN POOL_TYPE PoolType)
NTKERNELAPI VOID FsRtlUninitializeMcb (IN PMCB Mcb)
NTKERNELAPI VOID FsRtlTruncateMcb (IN PMCB Mcb, IN VBN Vbn)
NTKERNELAPI BOOLEAN FsRtlAddMcbEntry (IN PMCB Mcb, IN VBN Vbn, IN LBN Lbn, IN ULONG SectorCount)
NTKERNELAPI VOID FsRtlRemoveMcbEntry (IN PMCB Mcb, IN VBN Vbn, IN ULONG SectorCount)
NTKERNELAPI BOOLEAN FsRtlLookupMcbEntry (IN PMCB Mcb, IN VBN Vbn, OUT PLBN Lbn, OUT PULONG SectorCount OPTIONAL, OUT PULONG Index)
NTKERNELAPI BOOLEAN FsRtlLookupLastMcbEntry (IN PMCB Mcb, OUT PVBN Vbn, OUT PLBN Lbn)
NTKERNELAPI ULONG FsRtlNumberOfRunsInMcb (IN PMCB Mcb)
NTKERNELAPI BOOLEAN FsRtlGetNextMcbEntry (IN PMCB Mcb, IN ULONG RunIndex, OUT PVBN Vbn, OUT PLBN Lbn, OUT PULONG SectorCount)
NTKERNELAPI NTSTATUS FsRtlBalanceReads (IN PDEVICE_OBJECT TargetDevice)
NTKERNELAPI NTSTATUS FsRtlSyncVolumes (IN PDEVICE_OBJECT TargetDevice, IN PLARGE_INTEGER ByteOffset OPTIONAL, IN PLARGE_INTEGER ByteCount)
NTKERNELAPI VOID FsRtlInitializeOplock (IN OUT POPLOCK Oplock)
NTKERNELAPI VOID FsRtlUninitializeOplock (IN OUT POPLOCK Oplock)
NTKERNELAPI NTSTATUS FsRtlOplockFsctrl (IN POPLOCK Oplock, IN PIRP Irp, IN ULONG OpenCount)
NTKERNELAPI NTSTATUS FsRtlCheckOplock (IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
NTKERNELAPI BOOLEAN FsRtlOplockIsFastIoPossible (IN POPLOCK Oplock)
NTKERNELAPI BOOLEAN FsRtlCurrentBatchOplock (IN POPLOCK Oplock)
NTKERNELAPI NTSTATUS FsRtlNotifyVolumeEvent (IN PFILE_OBJECT FileObject, IN ULONG EventCode)
NTKERNELAPI VOID FsRtlNotifyInitializeSync (IN PNOTIFY_SYNC *NotifySync)
NTKERNELAPI VOID FsRtlNotifyUninitializeSync (IN PNOTIFY_SYNC *NotifySync)
NTKERNELAPI VOID FsRtlNotifyChangeDirectory (IN PNOTIFY_SYNC NotifySync, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN PLIST_ENTRY NotifyList, IN BOOLEAN WatchTree, IN ULONG CompletionFilter, IN PIRP NotifyIrp)
NTKERNELAPI VOID FsRtlNotifyFullChangeDirectory (IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
NTKERNELAPI VOID FsRtlNotifyReportChange (IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN PSTRING TargetName, IN ULONG FilterMatch)
NTKERNELAPI VOID FsRtlNotifyFullReportChange (IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext)
NTKERNELAPI VOID FsRtlNotifyCleanup (IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext)
NTKERNELAPI VOID FsRtlDissectName (IN UNICODE_STRING Path, OUT PUNICODE_STRING FirstName, OUT PUNICODE_STRING RemainingName)
NTKERNELAPI BOOLEAN FsRtlDoesNameContainWildCards (IN PUNICODE_STRING Name)
NTKERNELAPI BOOLEAN FsRtlAreNamesEqual (PCUNICODE_STRING ConstantNameA, PCUNICODE_STRING ConstantNameB, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
NTKERNELAPI BOOLEAN FsRtlIsNameInExpression (IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCH UpcaseTable OPTIONAL)
NTKERNELAPI VOID FsRtlPostStackOverflow (IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
NTKERNELAPI VOID FsRtlPostPagingFileStackOverflow (IN PVOID Context, IN PKEVENT Event, IN PFSRTL_STACK_OVERFLOW_ROUTINE StackOverflowRoutine)
NTKERNELAPI NTSTATUS FsRtlRegisterUncProvider (IN OUT PHANDLE MupHandle, IN PUNICODE_STRING RedirectorDeviceName, IN BOOLEAN MailslotsSupported)
NTKERNELAPI VOID FsRtlDeregisterUncProvider (IN HANDLE Handle)
NTKERNELAPI NTSTATUS FsRtlInsertFilterContext (IN PFILE_OBJECT FileObject, IN PFSRTL_FILTER_CONTEXT Ptr)
NTKERNELAPI PFSRTL_FILTER_CONTEXT FsRtlLookupFilterContextInternal (IN PFILE_OBJECT FileObject, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL)
NTKERNELAPI PFSRTL_FILTER_CONTEXT FsRtlRemoveFilterContext (IN PFILE_OBJECT FileObject, IN PVOID OwnerId OPTIONAL, IN PVOID InstanceId OPTIONAL)
NTKERNELAPI VOID FsRtlTeardownFilterContexts (IN PLIST_ENTRY FilterContexts)

Variables

PUCHAR LEGAL_ANSI_CHARACTER_ARRAY
PUSHORT NLS_OEM_LEAD_BYTE_INFO


Define Documentation

#define FSRTL_AUXILIARY_FLAG_DEALLOCATE   0x00000001
 

Definition at line 453 of file fsrtl.h.

#define FSRTL_CACHE_TOP_LEVEL_IRP   0x02
 

Definition at line 283 of file fsrtl.h.

Referenced by UdfAcquireForCache(), and UdfReleaseFromCache().

#define FSRTL_FAST_IO_TOP_LEVEL_IRP   0x04
 

Definition at line 285 of file fsrtl.h.

Referenced by FsRtlCopyRead(), FsRtlCopyWrite(), FsRtlMdlReadDev(), and FsRtlPrepareMdlWriteDev().

#define FSRTL_FAT_LEGAL   0x01
 

Definition at line 935 of file fsrtl.h.

#define FSRTL_FLAG2_DO_MODIFIED_WRITE   (0x01)
 

Definition at line 256 of file fsrtl.h.

Referenced by CcInitializeCacheMap().

#define FSRTL_FLAG2_PURGE_WHEN_MAPPED   (0x04)
 

Definition at line 272 of file fsrtl.h.

Referenced by CcZeroEndOfLastPage().

#define FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS   (0x02)
 

Definition at line 265 of file fsrtl.h.

Referenced by FsRtlInsertFilterContext(), FsRtlLookupFilterContextInternal(), and FsRtlRemoveFilterContext().

#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX   (0x08)
 

Definition at line 221 of file fsrtl.h.

Referenced by FsRtlAcquireFileForModWrite().

#define FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH   (0x10)
 

Definition at line 222 of file fsrtl.h.

Referenced by FsRtlAcquireFileForModWrite().

#define FSRTL_FLAG_ADVANCED_HEADER   (0x40)
 

Definition at line 236 of file fsrtl.h.

Referenced by CcCopyWrite(), and CcZeroEndOfLastPage().

#define FSRTL_FLAG_EOF_ADVANCE_ACTIVE   (0x80)
 

Definition at line 243 of file fsrtl.h.

#define FSRTL_FLAG_FILE_LENGTH_CHANGED   (0x02)
 

Definition at line 210 of file fsrtl.h.

#define FSRTL_FLAG_FILE_MODIFIED   (0x01)
 

Definition at line 209 of file fsrtl.h.

#define FSRTL_FLAG_LIMIT_MODIFIED_PAGES   (0x04)
 

Definition at line 211 of file fsrtl.h.

Referenced by CcCanIWrite(), CcDeferWrite(), and CcSetDirtyPageThreshold().

#define FSRTL_FLAG_USER_MAPPED_FILE   (0x20)
 

Definition at line 229 of file fsrtl.h.

Referenced by CcFlushCache(), and CcZeroEndOfLastPage().

#define FSRTL_FSP_TOP_LEVEL_IRP   0x01
 

Definition at line 282 of file fsrtl.h.

Referenced by FsRtlStackOverflowRead(), MiRemoveUnusedSegments(), and MmCreateSection().

#define FSRTL_HPFS_LEGAL   0x02
 

Definition at line 936 of file fsrtl.h.

#define FSRTL_MAX_TOP_LEVEL_IRP_FLAG   0x04
 

Definition at line 286 of file fsrtl.h.

#define FSRTL_MOD_WRITE_TOP_LEVEL_IRP   0x03
 

Definition at line 284 of file fsrtl.h.

#define FSRTL_NTFS_LEGAL   0x04
 

Definition at line 937 of file fsrtl.h.

#define FSRTL_NTFS_STREAM_LEGAL   (FSRTL_NTFS_LEGAL | FSRTL_OLE_LEGAL)
 

Definition at line 940 of file fsrtl.h.

#define FSRTL_OLE_LEGAL   0x10
 

Definition at line 939 of file fsrtl.h.

#define FSRTL_VOLUME_DISMOUNT   1
 

Definition at line 1421 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), and UdfDismountVolume().

#define FSRTL_VOLUME_DISMOUNT_FAILED   2
 

Definition at line 1422 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), and UdfDismountVolume().

#define FSRTL_VOLUME_LOCK   3
 

Definition at line 1423 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), and UdfLockVolume().

#define FSRTL_VOLUME_LOCK_FAILED   4
 

Definition at line 1424 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), and UdfLockVolume().

#define FSRTL_VOLUME_MOUNT   6
 

Definition at line 1426 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), UdfMountVolume(), and UdfVerifyVolume().

#define FSRTL_VOLUME_UNLOCK   5
 

Definition at line 1425 of file fsrtl.h.

Referenced by FsRtlNotifyVolumeEvent(), UdfCommonCleanup(), and UdfUnlockVolume().

#define FSRTL_WILD_CHARACTER   0x08
 

Definition at line 938 of file fsrtl.h.

#define FsRtlAllocatePoolWithQuotaTag PoolType,
NumberOfBytes,
Tag   ) 
 

Value:

ExAllocatePoolWithQuotaTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ Tag)

Definition at line 1107 of file fsrtl.h.

#define FsRtlAllocatePoolWithTag PoolType,
NumberOfBytes,
Tag   ) 
 

Value:

ExAllocatePoolWithTag((POOL_TYPE)((PoolType) | POOL_RAISE_IF_ALLOCATION_FAILURE), \ NumberOfBytes, \ Tag)

Definition at line 1101 of file fsrtl.h.

Referenced by CcAllocateObcb(), CcExtendVacbArray(), CcInitializeVacbs(), FsRtlFindInTunnelCache(), UdfAllocateTable(), UdfCreatePcb(), UdfDetermineVolumeBounding(), UdfEnumerateIndex(), UdfFindAnchorVolumeDescriptor(), UdfFindDirEntry(), UdfFindFileSetDescriptor(), UdfFindVolumeDescriptors(), UdfInitializeCrc16(), UdfInitializeEnumeration(), UdfInitializePcb(), UdfInsertPrefix(), UdfLoadSparingTables(), UdfLookupDirEntryPostProcessing(), UdfNormalizeFileNames(), UdfPrepareBuffers(), UdfRecognizeVolume(), UdfStoreVolumeDescriptorIfPrevailing(), UdfUpdateDirNames(), and UdfUpdateVcbPhase0().

#define FsRtlAreThereCurrentFileLocks FL   ) 
 

Value:

( \ ((FL)->FastIoIsQuestionable))

Definition at line 807 of file fsrtl.h.

Referenced by UdfFastUnlockSingle(), and UdfOplockRequest().

#define FsRtlCompleteRequest IRP,
STATUS   ) 
 

Value:

{ \ (IRP)->IoStatus.Status = (STATUS); \ IoCompleteRequest( (IRP), IO_DISK_INCREMENT ); \ }

Definition at line 1745 of file fsrtl.h.

Referenced by FsRtlAcknowledgeOplockBreak(), FsRtlCancelExclusiveIrp(), FsRtlCancelNotify(), FsRtlCompleteLockIrpReal(), FsRtlNotifyCompleteIrp(), FsRtlNotifyCompletion(), FsRtlNotifyFullChangeDirectory(), FsRtlOpBatchBreakClosePending(), FsRtlOplockBreakNotify(), FsRtlOplockBreakToII(), FsRtlOplockBreakToNone(), FsRtlOplockCleanup(), FsRtlOplockFsctrl(), FsRtlProcessFileLock(), FsRtlRemoveAndCompleteIrp(), FsRtlRequestExclusiveOplock(), FsRtlRequestOplockII(), and FsRtlUninitializeOplock().

 
#define FsRtlEnterFileSystem  ) 
 

Value:

Definition at line 1772 of file fsrtl.h.

Referenced by FsRtlAcquireFileExclusive(), FsRtlAcquireFileForCcFlush(), FsRtlCancelNotify(), FsRtlCopyRead(), FsRtlCopyWrite(), FsRtlMdlReadDev(), FsRtlPrepareMdlWriteDev(), UdfFastLock(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfFsdDispatch(), UdfFspClose(), and UdfFspDispatch().

 
#define FsRtlExitFileSystem  ) 
 

Value:

Definition at line 1795 of file fsrtl.h.

Referenced by FsRtlCancelNotify(), FsRtlCopyRead(), FsRtlCopyWrite(), FsRtlMdlReadDev(), FsRtlPrepareMdlWriteDev(), FsRtlReleaseFile(), FsRtlReleaseFileForCcFlush(), UdfFastLock(), UdfFastQueryBasicInfo(), UdfFastQueryNetworkInfo(), UdfFastQueryStdInfo(), UdfFastUnlockAll(), UdfFastUnlockAllByKey(), UdfFastUnlockSingle(), UdfFsdDispatch(), UdfFspClose(), and UdfFspDispatch().

#define FsRtlFastLock A1,
A2,
A3,
A4,
A5,
A6,
A7,
A8,
A9,
A10,
A11   ) 
 

Value:

( \ FsRtlPrivateLock( A1, /* FileLock */ \ A2, /* FileObject */ \ A3, /* FileOffset */ \ A4, /* Length */ \ A5, /* ProcessId */ \ A6, /* Key */ \ A7, /* FailImmediately */ \ A8, /* ExclusiveLock */ \ A9, /* Iosb */ \ NULL, /* Irp */ \ A10, /* Context */ \ A11 /* AlreadySynchronized */ ) \ )

Definition at line 785 of file fsrtl.h.

Referenced by UdfFastLock().

#define FsRtlIsAnsiCharacterLegal C,
FLAGS   ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), TRUE, FALSE, (FLAGS)) \ )

Definition at line 988 of file fsrtl.h.

#define FsRtlIsAnsiCharacterLegalFat C,
WILD_OK   ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_FAT_LEGAL) \ )

Definition at line 954 of file fsrtl.h.

Referenced by FsRtlIsFatDbcsLegal().

#define FsRtlIsAnsiCharacterLegalHpfs C,
WILD_OK   ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_HPFS_LEGAL) \ )

Definition at line 962 of file fsrtl.h.

Referenced by FsRtlIsHpfsDbcsLegal(), and UdfIsCharacterLegal().

#define FsRtlIsAnsiCharacterLegalNtfs C,
WILD_OK   ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_LEGAL) \ )

Definition at line 970 of file fsrtl.h.

#define FsRtlIsAnsiCharacterLegalNtfsStream C,
WILD_OK   ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), TRUE, (WILD_OK), FSRTL_NTFS_STREAM_LEGAL) \ )

Definition at line 979 of file fsrtl.h.

#define FsRtlIsAnsiCharacterWild  ) 
 

Value:

( \ FsRtlTestAnsiCharacter((C), FALSE, FALSE, FSRTL_WILD_CHARACTER) \ )

Definition at line 946 of file fsrtl.h.

Referenced by FsRtlDoesDbcsContainWildCards().

#define FsRtlIsLeadDbcsCharacter DBCS_CHAR   ) 
 

Value:

( \ (BOOLEAN)((UCHAR)(DBCS_CHAR) < 0x80 ? FALSE : \ (NLS_MB_CODE_PAGE_TAG && \ (NLS_OEM_LEAD_BYTE_INFO[(UCHAR)(DBCS_CHAR)] != 0))) \ )

Definition at line 1033 of file fsrtl.h.

Referenced by FsRtlDissectDbcs(), FsRtlDoesDbcsContainWildCards(), FsRtlIsDbcsInExpression(), FsRtlIsFatDbcsLegal(), and FsRtlIsHpfsDbcsLegal().

#define FsRtlIsUnicodeCharacterWild  ) 
 

Value:

( \ (((C) >= 0x40) ? FALSE : FlagOn( LEGAL_ANSI_CHARACTER_ARRAY[(C)], \ FSRTL_WILD_CHARACTER ) ) \ )

Definition at line 1538 of file fsrtl.h.

Referenced by FsRtlDoesNameContainWildCards().

#define FsRtlLookupFilterContext fo,
oid,
iid   ) 
 

Value:

(( (fo)->FsContext \ && ( ((PFSRTL_COMMON_FCB_HEADER)(fo)->FsContext)->Flags2 & \ FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS ) \ && !IsListEmpty( (PLIST_ENTRY) \ &((PFSRTL_COMMON_FCB_HEADER)(fo)->FsContext)->FilterContexts ) \ ) ? FsRtlLookupFilterContextInternal(fo, oid, iid) \ : NULL)

Definition at line 1682 of file fsrtl.h.

 
#define FsRtlSetTopLevelIrpForModWriter  ) 
 

Value:

{ \ IoSetTopLevelIrp((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP); \ }

Definition at line 465 of file fsrtl.h.

Referenced by MiMappedPageWriter().

#define FsRtlTestAnsiCharacter C,
DEFAULT_RET,
WILD_OK,
FLAGS   ) 
 

Value:

( \ ((SCHAR)(C) < 0) ? DEFAULT_RET : \ FlagOn( LEGAL_ANSI_CHARACTER_ARRAY[(C)], \ (FLAGS) | \ ((WILD_OK) ? FSRTL_WILD_CHARACTER : 0) ) \ )

Definition at line 997 of file fsrtl.h.

#define LEGAL_ANSI_CHARACTER_ARRAY   FsRtlLegalAnsiCharacterArray
 

Definition at line 921 of file fsrtl.h.

#define NLS_MB_CODE_PAGE_TAG   NlsMbOemCodePageTag
 

Definition at line 922 of file fsrtl.h.

#define NLS_OEM_LEAD_BYTE_INFO   NlsOemLeadByteInfo
 

Definition at line 923 of file fsrtl.h.


Typedef Documentation

typedef struct _EOF_WAIT_BLOCK EOF_WAIT_BLOCK
 

typedef enum _FAST_IO_POSSIBLE FAST_IO_POSSIBLE
 

typedef struct _FILE_LOCK FILE_LOCK
 

Referenced by FsRtlInitializeFileLocks().

typedef struct _FILE_LOCK_INFO FILE_LOCK_INFO
 

typedef struct _FSRTL_ADVANCED_FCB_HEADER FSRTL_ADVANCED_FCB_HEADER
 

typedef struct _FSRTL_AUXILIARY_BUFFER FSRTL_AUXILIARY_BUFFER
 

typedef struct _FSRTL_COMMON_FCB_HEADER FSRTL_COMMON_FCB_HEADER
 

typedef enum _FSRTL_COMPARISON_RESULT FSRTL_COMPARISON_RESULT
 

Referenced by UdfFindNameLink(), UdfFullCompareNames(), and UdfInsertNameLink().

typedef struct _FSRTL_FILTER_CONTEXT FSRTL_FILTER_CONTEXT
 

Referenced by FsRtlLookupFilterContextInternal().

typedef struct _LARGE_MCB LARGE_MCB
 

typedef ULONG LBN
 

Definition at line 29 of file fsrtl.h.

Referenced by FsRtlAddLargeMcbEntry(), FsRtlLookupLargeMcbEntry(), FsRtlRemoveMcbEntryPrivate(), FsRtlSplitLargeMcb(), UdfAddVmcbMapping(), and UdfRemoveVmcbMapping().

typedef struct _MCB MCB
 

Referenced by main().

typedef PVOID OPLOCK
 

Definition at line 1355 of file fsrtl.h.

typedef BOOLEAN(* PCHECK_FOR_TRAVERSE_ACCESS)(IN PVOID NotifyContext, IN PVOID TargetContext, IN PSECURITY_SUBJECT_CONTEXT SubjectContext)
 

Definition at line 1446 of file fsrtl.h.

typedef NTSTATUS(* PCOMPLETE_LOCK_IRP_ROUTINE)(IN PVOID Context, IN PIRP Irp)
 

Definition at line 591 of file fsrtl.h.

Referenced by FsRtlCompleteLockIrpReal().

typedef EOF_WAIT_BLOCK* PEOF_WAIT_BLOCK
 

Definition at line 300 of file fsrtl.h.

typedef FILE_LOCK* PFILE_LOCK
 

Definition at line 641 of file fsrtl.h.

Referenced by UdfCreateFileLock().

typedef FILE_LOCK_INFO* PFILE_LOCK_INFO
 

Definition at line 579 of file fsrtl.h.

typedef FSRTL_ADVANCED_FCB_HEADER* PFSRTL_ADVANCED_FCB_HEADER
 

Definition at line 202 of file fsrtl.h.

Referenced by CcCopyWrite().

typedef FSRTL_AUXILIARY_BUFFER* PFSRTL_AUXILIARY_BUFFER
 

Definition at line 442 of file fsrtl.h.

typedef FSRTL_COMMON_FCB_HEADER* PFSRTL_COMMON_FCB_HEADER
 

Definition at line 147 of file fsrtl.h.

Referenced by CcFlushCache().

typedef struct _FSRTL_FILTER_CONTEXT * PFSRTL_FILTER_CONTEXT
 

Referenced by FsRtlInsertFilterContext().

typedef VOID(* PFSRTL_STACK_OVERFLOW_ROUTINE)(IN PVOID Context, IN PKEVENT Event)
 

Definition at line 1582 of file fsrtl.h.

typedef LARGE_MCB* PLARGE_MCB
 

Definition at line 1140 of file fsrtl.h.

Referenced by UdfResetVmcb().

typedef LBN* PLBN
 

Definition at line 30 of file fsrtl.h.

typedef MCB* PMCB
 

Definition at line 1251 of file fsrtl.h.

typedef PVOID PNOTIFY_SYNC
 

Definition at line 1443 of file fsrtl.h.

Referenced by FsRtlCancelNotify(), and FsRtlNotifyInitializeSync().

typedef PVOID * POPLOCK
 

Definition at line 1355 of file fsrtl.h.

typedef VOID(* POPLOCK_FS_PREPOST_IRP)(IN PVOID Context, IN PIRP Irp)
 

Definition at line 1366 of file fsrtl.h.

typedef VOID(* POPLOCK_WAIT_COMPLETE_ROUTINE)(IN PVOID Context, IN PIRP Irp)
 

Definition at line 1359 of file fsrtl.h.

typedef * PTUNNEL
 

typedef VOID(* PUNLOCK_ROUTINE)(IN PVOID Context, IN PFILE_LOCK_INFO FileLockInfo)
 

Definition at line 596 of file fsrtl.h.

Referenced by FsRtlInitializeFileLock().

typedef VBN* PVBN
 

Definition at line 33 of file fsrtl.h.

typedef ULONG VBN
 

Definition at line 32 of file fsrtl.h.

Referenced by FsRtlAddLargeMcbEntry(), FsRtlRemoveLargeMcbEntry(), FsRtlSplitLargeMcb(), FsRtlTruncateLargeMcb(), and UdfAddVmcbMapping().


Enumeration Type Documentation

enum _FAST_IO_POSSIBLE
 

Enumeration values:
FastIoIsNotPossible 
FastIoIsPossible 
FastIoIsQuestionable 

Definition at line 58 of file fsrtl.h.

enum _FSRTL_COMPARISON_RESULT
 

Enumeration values:
LessThan 
EqualTo 
GreaterThan 

Definition at line 900 of file fsrtl.h.

00900 { 00901 LessThan = -1, 00902 EqualTo = 0, 00903 GreaterThan = 1 00904 } FSRTL_COMPARISON_RESULT;


Function Documentation

NTKERNELAPI VOID FsRtlAcquireFileExclusive IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 2555 of file fastio.c.

References _FAST_IO_DISPATCH::AcquireFileForNtCreateSection, _DEVICE_OBJECT::DriverObject, ExAcquireResourceExclusive, _DRIVER_OBJECT::FastIoDispatch, FsRtlEnterFileSystem, Header, IoGetBaseFileSystemDeviceObject(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, and TRUE.

Referenced by CcWriteBehind(), CcZeroEndOfLastPage(), and MmCreateSection().

02561 : 02562 02563 This routine is used by NtCreateSection to pre-acquire file system 02564 resources in order to avoid deadlocks. If there is a FastIo entry 02565 for AcquireFileForNtCreateSection then that routine will be called. 02566 Otherwise, we will simply acquire the main file resource exclusive. 02567 If there is no main resource then we acquire nothing and return 02568 FALSE. In the cases that we acquire a resource, we also set the 02569 TopLevelIrp field in the thread local storage to indicate to file 02570 systems beneath us that we have acquired file system resources. 02571 02572 Arguments: 02573 02574 FileObject - Pointer to the file object being written. 02575 02576 Return Value: 02577 02578 NONE 02579 02580 --*/ 02581 02582 { 02583 PDEVICE_OBJECT DeviceObject; 02584 PFAST_IO_DISPATCH FastIoDispatch; 02585 PFSRTL_COMMON_FCB_HEADER Header; 02586 02587 PAGED_CODE(); 02588 02589 // 02590 // First see if we have to call the file system. 02591 // 02592 02593 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02594 02595 if ((FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch) && 02596 (FastIoDispatch->SizeOfFastIoDispatch > 02597 FIELD_OFFSET( FAST_IO_DISPATCH, AcquireFileForNtCreateSection )) && 02598 (FastIoDispatch->AcquireFileForNtCreateSection != NULL)) { 02599 02600 FsRtlEnterFileSystem(); 02601 FastIoDispatch->AcquireFileForNtCreateSection( FileObject ); 02602 02603 return; 02604 } 02605 02606 // 02607 // If there is a main file resource, acquire that. 02608 // 02609 02610 if ((Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext) && 02611 (Header->Resource != NULL)) { 02612 02613 FsRtlEnterFileSystem(); 02614 ExAcquireResourceExclusive( Header->Resource, TRUE ); 02615 02616 return; 02617 } 02618 02619 // 02620 // Nothing to acquire. 02621 // 02622 02623 return; 02624 }

NTKERNELAPI VOID FsRtlAcquireFileForCcFlush IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 2402 of file fastio.c.

References _FAST_IO_DISPATCH::AcquireForCcFlush, ASSERT, _DEVICE_OBJECT::DriverObject, ExAcquireResourceExclusive, ExAcquireResourceShared, ExIsResourceAcquiredShared, _DRIVER_OBJECT::FastIoDispatch, FsRtlEnterFileSystem, Header, IoGetBaseFileSystemDeviceObject(), NTSTATUS(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, Status, and TRUE.

Referenced by MiRemoveUnusedSegments(), MmFlushSection(), and MmFlushVirtualMemory().

02408 : 02409 02410 This routine acquires a file system resource prior to a call to CcFlush. 02411 02412 Arguments: 02413 02414 FileObject - Pointer to the file object being written. 02415 02416 Return Value: 02417 02418 None. 02419 02420 --*/ 02421 02422 { 02423 PDEVICE_OBJECT DeviceObject; 02424 PFAST_IO_DISPATCH FastIoDispatch; 02425 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; 02426 02427 PAGED_CODE(); 02428 02429 // 02430 // First see if we have to call the file system. Note that in the case 02431 // of layered file systems, the layered file system might have the 02432 // dispatch routine, but the file system on which it is layered on may 02433 // not. In that case, the layered file system will return 02434 // STATUS_INVALID_DEVICE_REQUEST. 02435 // 02436 02437 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02438 02439 FsRtlEnterFileSystem(); 02440 02441 if ((FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch) && 02442 (FastIoDispatch->SizeOfFastIoDispatch > 02443 FIELD_OFFSET( FAST_IO_DISPATCH, AcquireForCcFlush )) && 02444 (FastIoDispatch->AcquireForCcFlush != NULL)) { 02445 02446 Status = FastIoDispatch->AcquireForCcFlush( FileObject, DeviceObject ); 02447 02448 } 02449 02450 02451 ASSERT( (Status == STATUS_SUCCESS) || (Status == STATUS_INVALID_DEVICE_REQUEST) ); 02452 02453 if (Status == STATUS_INVALID_DEVICE_REQUEST) { 02454 02455 PFSRTL_COMMON_FCB_HEADER Header = FileObject->FsContext; 02456 02457 // 02458 // If not already owned get the main resource exclusive because me may 02459 // extend ValidDataLength. Otherwise acquire it one more time recursively. 02460 // 02461 02462 if (Header->Resource != NULL) { 02463 if (!ExIsResourceAcquiredShared(Header->Resource)) { 02464 ExAcquireResourceExclusive( Header->Resource, TRUE ); 02465 } else { 02466 ExAcquireResourceShared( Header->Resource, TRUE ); 02467 } 02468 } 02469 02470 // 02471 // Also get the paging I/O resource ahead of any MM resources. 02472 // 02473 02474 if (Header->PagingIoResource != NULL) { 02475 ExAcquireResourceShared( Header->PagingIoResource, TRUE ); 02476 } 02477 } 02478 }

NTKERNELAPI BOOLEAN FsRtlAcquireFileForModWrite IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  StartingOffset,
OUT PERESOURCE ResourceToRelease
 

Definition at line 2064 of file fastio.c.

References AcquireExclusive, _FAST_IO_DISPATCH::AcquireForModWrite, _DEVICE_OBJECT::DriverObject, ExAcquireResourceExclusive, ExAcquireSharedWaitForExclusive(), ExConvertExclusiveToShared, ExReleaseResource, FALSE, _DRIVER_OBJECT::FastIoDispatch, FlagOn, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH, Header, IoGetBaseFileSystemDeviceObject(), NTSTATUS(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, Status, and TRUE.

Referenced by MiGatherMappedPages(), and MiMappedPageWriter().

02072 : 02073 02074 This routine decides which file system resource the modified page 02075 writer should acquire and acquires it if possible. Wait is always 02076 specified as FALSE. We pass back the resource Mm has to release 02077 when the write completes. 02078 02079 Arguments: 02080 02081 FileObject - Pointer to the file object being written. 02082 02083 EndingOffset - The offset of the last byte being written + 1. 02084 02085 ByteCount - Length of data in bytes. 02086 02087 ResourceToRelease - Returns the resource to release. Not defined if 02088 FALSE is returned. 02089 02090 Return Value: 02091 02092 FALSE - The resource could not be acquired without waiting. 02093 02094 TRUE - The returned resource has been acquired. 02095 02096 --*/ 02097 02098 { 02099 PFSRTL_COMMON_FCB_HEADER Header; 02100 PERESOURCE ResourceAcquired; 02101 PDEVICE_OBJECT DeviceObject; 02102 PFAST_IO_DISPATCH FastIoDispatch; 02103 02104 BOOLEAN AcquireExclusive; 02105 02106 PAGED_CODE(); 02107 02108 Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 02109 02110 // 02111 // First see if we have to call the file system. 02112 // 02113 02114 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02115 02116 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 02117 if ((FastIoDispatch->SizeOfFastIoDispatch > 02118 FIELD_OFFSET( FAST_IO_DISPATCH, AcquireForModWrite )) && 02119 (FastIoDispatch->AcquireForModWrite != NULL)) { 02120 02121 NTSTATUS Status; 02122 02123 Status = FastIoDispatch->AcquireForModWrite(FileObject, 02124 EndingOffset, 02125 ResourceToRelease, 02126 DeviceObject); 02127 02128 if (Status == STATUS_SUCCESS) { 02129 return( TRUE ); 02130 } else if (Status == STATUS_CANT_WAIT) { 02131 return( FALSE ); 02132 } else { 02133 02134 // 02135 // Fall through. When dealing with layered file systems, it might 02136 // be the case that the layered file system has the above dispatch 02137 // routine, but the FS it is layered on top of does not. In that 02138 // case, the layered file system will return an error code other 02139 // than STATUS_SUCCESS or STATUS_CANT_WAIT, and we simply handle 02140 // it as if the file system did not have the dispatch routine to 02141 // begin with. 02142 // 02143 02144 NOTHING; 02145 } 02146 } 02147 02148 // 02149 // We follow the following rules to determine which resource 02150 // to acquire. We use the flags in the common header. These 02151 // flags can't change once we have acquired any resource. 02152 // This means we can do an unsafe test and optimisticly 02153 // acquire a resource. At that point we can test the bits 02154 // to see if we have what we want. 02155 // 02156 // 0 - If there is no main resource, acquire nothing. 02157 // 02158 // 1 - Acquire the main resource exclusively if the 02159 // ACQUIRE_MAIN_RSRC_EX flag is set or we are extending 02160 // valid data. 02161 // 02162 // 2 - Acquire the main resource shared if there is 02163 // no paging io resource or the 02164 // ACQUIRE_MAIN_RSRC_SH flag is set. 02165 // 02166 // 3 - Otherwise acquire the paging io resource shared. 02167 // 02168 02169 if (Header->Resource == NULL) { 02170 02171 *ResourceToRelease = NULL; 02172 02173 return TRUE; 02174 } 02175 02176 if (FlagOn( Header->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX ) || 02177 (EndingOffset->QuadPart > Header->ValidDataLength.QuadPart && 02178 Header->ValidDataLength.QuadPart != Header->FileSize.QuadPart)) { 02179 02180 ResourceAcquired = Header->Resource; 02181 AcquireExclusive = TRUE; 02182 02183 } else if (FlagOn( Header->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH ) || 02184 Header->PagingIoResource == NULL) { 02185 02186 ResourceAcquired = Header->Resource; 02187 AcquireExclusive = FALSE; 02188 02189 } else { 02190 02191 ResourceAcquired = Header->PagingIoResource; 02192 AcquireExclusive = FALSE; 02193 } 02194 02195 // 02196 // Perform the following in a loop in case we need to back and 02197 // check the state of the resource acquisition. In most cases 02198 // the initial checks will succeed and we can proceed immediately. 02199 // We have to worry about the two FsRtl bits changing but 02200 // if there is no paging io resource before there won't ever be 02201 // one. 02202 // 02203 02204 while (TRUE) { 02205 02206 // 02207 // Now acquire the desired resource. 02208 // 02209 02210 if (AcquireExclusive) { 02211 02212 if (!ExAcquireResourceExclusive( ResourceAcquired, FALSE )) { 02213 02214 return FALSE; 02215 } 02216 02217 } else if (!ExAcquireSharedWaitForExclusive( ResourceAcquired, FALSE )) { 02218 02219 return FALSE; 02220 } 02221 02222 // 02223 // If the valid data length is changing or the exclusive bit is 02224 // set and we don't have the main resource exclusive then 02225 // release the current resource and acquire the main resource 02226 // exclusively and move to the top of the loop. 02227 // 02228 02229 if (FlagOn( Header->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_EX ) || 02230 (EndingOffset->QuadPart > Header->ValidDataLength.QuadPart && 02231 Header->ValidDataLength.QuadPart != Header->FileSize.QuadPart)) { 02232 02233 // 02234 // If we don't have the main resource exclusively then 02235 // release the current resource and attempt to acquire 02236 // the main resource exclusively. 02237 // 02238 02239 if (!AcquireExclusive) { 02240 02241 ExReleaseResource( ResourceAcquired ); 02242 AcquireExclusive = TRUE; 02243 ResourceAcquired = Header->Resource; 02244 continue; 02245 } 02246 02247 // 02248 // We have the correct resource. Exit the loop. 02249 // 02250 02251 // 02252 // If we should be acquiring the main resource shared then move 02253 // to acquire the correct resource and proceed to the top of the loop. 02254 // 02255 02256 } else if (FlagOn( Header->Flags, FSRTL_FLAG_ACQUIRE_MAIN_RSRC_SH )) { 02257 02258 // 02259 // If we have the main resource exclusively then downgrade to 02260 // shared and exit the loop. 02261 // 02262 02263 if (AcquireExclusive) { 02264 02265 ExConvertExclusiveToShared( ResourceAcquired ); 02266 02267 // 02268 // If we have the paging io resource then give up this resource 02269 // and acquire the main resource exclusively. This is going 02270 // at it with a large hammer but is guaranteed to be resolved 02271 // in the next pass through the loop. 02272 // 02273 02274 } else if (ResourceAcquired != Header->Resource) { 02275 02276 ExReleaseResource( ResourceAcquired ); 02277 ResourceAcquired = Header->Resource; 02278 AcquireExclusive = TRUE; 02279 continue; 02280 } 02281 02282 // 02283 // We have the correct resource. Exit the loop. 02284 // 02285 02286 // 02287 // At this point we should have the paging Io resource shared 02288 // if it exists. If not then acquire it shared and release the 02289 // other resource and exit the loop. 02290 // 02291 02292 } else if (Header->PagingIoResource != NULL 02293 && ResourceAcquired != Header->PagingIoResource) { 02294 02295 ResourceAcquired = NULL; 02296 02297 if (ExAcquireSharedWaitForExclusive( Header->PagingIoResource, FALSE )) { 02298 02299 ResourceAcquired = Header->PagingIoResource; 02300 } 02301 02302 ExReleaseResource( Header->Resource ); 02303 02304 if (ResourceAcquired == NULL) { 02305 02306 return FALSE; 02307 } 02308 02309 // 02310 // We now have the correct resource. Exit the loop. 02311 // 02312 02313 // 02314 // We should have the main resource shared. If we don't then 02315 // degrade our lock to shared access. 02316 // 02317 02318 } else if (AcquireExclusive) { 02319 02320 ExConvertExclusiveToShared( ResourceAcquired ); 02321 02322 // 02323 // We now have the correct resource. Exit the loop. 02324 // 02325 } 02326 02327 // 02328 // We have the correct resource. Exit the loop. 02329 // 02330 02331 break; 02332 } 02333 02334 *ResourceToRelease = ResourceAcquired; 02335 02336 return TRUE; 02337 }

NTKERNELAPI BOOLEAN FsRtlAddLargeMcbEntry IN PLARGE_MCB  Mcb,
IN LONGLONG  Vbn,
IN LONGLONG  Lbn,
IN LONGLONG  SectorCount
 

Definition at line 977 of file largemcb.c.

References ASSERT, ASSERTMSG, Dbg, DebugTrace, EndingLbn, EndingVbn, FALSE, _NONOPAQUE_MCB::FastMutex, FsRtlAddLargeEntry(), FsRtlFindLargeIndex(), FsRtlRemoveLargeEntry(), Index, LBN, _NONOPAQUE_MCB::Mapping, NextStartingLbn, NextStartingVbn, PAGED_CODE, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, PreviousEndingLbn, PreviousEndingVbn, StartingLbn, StartingVbn, TRUE, try_return, UNUSED_LBN, and VBN.

Referenced by FsRtlAddMcbEntry(), UdfInitializeAllocations(), UdfLoadSparingTables(), and UdfUpdateVcbPhase1().

00986 : 00987 00988 This routine is used to add a new mapping of VBNs to LBNs to an existing 00989 Mcb. The information added will map 00990 00991 Vbn to Lbn, 00992 00993 Vbn+1 to Lbn+1,... 00994 00995 Vbn+(SectorCount-1) to Lbn+(SectorCount-1). 00996 00997 The mapping for the VBNs must not already exist in the Mcb. If the 00998 mapping continues a previous run, then this routine will actually coalesce 00999 them into 1 run. 01000 01001 If pool is not available to store the information this routine will raise a 01002 status value indicating insufficient resources. 01003 01004 An input Lbn value of zero is illegal (i.e., the Mcb structure will never 01005 map a Vbn to a zero Lbn value). 01006 01007 Arguments: 01008 01009 OpaqueMcb - Supplies the Mcb in which to add the new mapping. 01010 01011 Vbn - Supplies the starting Vbn of the new mapping run to add to the Mcb. 01012 01013 Lbn - Supplies the starting Lbn of the new mapping run to add to the Mcb. 01014 01015 SectorCount - Supplies the size of the new mapping run (in sectors). 01016 01017 Return Value: 01018 01019 BOOLEAN - TRUE if the mapping was added successfully (i.e., the new 01020 Vbns did not collide with existing Vbns), and FALSE otherwise. If 01021 FALSE is returned then the Mcb is not changed. 01022 01023 --*/ 01024 01025 { 01026 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 01027 01028 VBN Vbn = ((ULONG)LargeVbn); 01029 LBN Lbn = ((ULONG)LargeLbn); 01030 ULONG SectorCount = ((ULONG)LargeSectorCount); 01031 01032 ULONG Index; 01033 01034 VBN LastVbn; 01035 01036 BOOLEAN Result; 01037 01038 ASSERTMSG("LargeInteger not supported yet ", ((PLARGE_INTEGER)&LargeVbn)->HighPart == 0); 01039 ASSERTMSG("LargeInteger not supported yet ", ((PLARGE_INTEGER)&LargeLbn)->HighPart == 0); 01040 ASSERTMSG("LargeInteger not supported yet ", ((PLARGE_INTEGER)&LargeSectorCount)->HighPart == 0); 01041 01042 PAGED_CODE(); 01043 01044 DebugTrace(+1, Dbg, "FsRtlAddLargeMcbEntry, Mcb = %08lx\n", Mcb ); 01045 DebugTrace( 0, Dbg, " Vbn = %08lx\n", Vbn ); 01046 DebugTrace( 0, Dbg, " Lbn = %08lx\n", Lbn ); 01047 DebugTrace( 0, Dbg, " SectorCount = %08lx\n", SectorCount ); 01048 01049 ExAcquireFastMutex( Mcb->FastMutex ); 01050 01051 try { 01052 01053 if (FsRtlFindLargeIndex(Mcb, Vbn, &Index)) { 01054 01055 ULONG EndVbn = Vbn + SectorCount - 1; 01056 ULONG EndIndex; 01057 01058 // 01059 // First check the case where we are adding to an existing mcb run 01060 // and if so then we will modify the insertion to complete the run 01061 // 01062 // --ExistingRun--| ==becomes==> --ExistingRun--| 01063 // |--NewRun--| |---| 01064 // 01065 // --ExistingRun----| ==becomes==> a noop 01066 // |--NewRun--| 01067 // 01068 01069 if (StartingLbn(Mcb, Index) != UNUSED_LBN) { 01070 01071 // 01072 // Check that the Lbn's line up between the new and existing run 01073 // 01074 01075 if (Lbn != (StartingLbn(Mcb, Index) + (Vbn - StartingVbn(Mcb, Index)))) { 01076 01077 // 01078 // Let our caller know we couldn't insert the run. 01079 // 01080 01081 try_return(Result = FALSE); 01082 } 01083 01084 // 01085 // Check if the new run is contained in the existing run 01086 // 01087 01088 if (EndVbn <= EndingVbn(Mcb, Index)) { 01089 01090 // 01091 // Do nothing because the run is contained within the existing run 01092 // 01093 01094 try_return(Result = TRUE); 01095 } 01096 01097 // 01098 // Otherwise we will simply trim off the request for the new run 01099 // to not overlap with the existing run 01100 // 01101 01102 Vbn = NextStartingVbn(Mcb, Index); 01103 Lbn = EndingLbn(Mcb, Index) + 1; 01104 01105 ASSERT(EndVbn >= Vbn); 01106 01107 SectorCount = EndVbn - Vbn + 1; 01108 01109 // 01110 // At this point the new run start in a hole, now check that if 01111 // crosses into a non hole and if so then adjust new run to fit 01112 // in the hole 01113 // 01114 // 01115 // |--ExistingRun-- ==becomes==> |--ExistingRun-- 01116 // |--NewRun--| |--New| 01117 // 01118 01119 } else if (FsRtlFindLargeIndex(Mcb, EndVbn, &EndIndex) && (Index == (EndIndex-1))) { 01120 01121 // 01122 // Check that the Lbn's line up in the overlap 01123 // 01124 01125 if (StartingLbn(Mcb, EndIndex) != Lbn + (StartingVbn(Mcb, EndIndex) - Vbn)) { 01126 01127 // 01128 // Let our caller know we couldn't insert the run. 01129 // 01130 01131 try_return(Result = FALSE); 01132 } 01133 01134 // 01135 // Truncate the sector count to go up to but not include 01136 // the existing run 01137 // 01138 01139 SectorCount = StartingVbn(Mcb, EndIndex) - Vbn; 01140 } 01141 } 01142 01143 // 01144 // Find the index for the starting Vbn of our new run, if there isn't 01145 // a hole found then index will be set to paircount. 01146 // 01147 01148 if (((Index = Mcb->PairCount) == 0) || 01149 (PreviousEndingVbn(Mcb,Index)+1 <= Vbn) || 01150 !FsRtlFindLargeIndex(Mcb, Vbn, &Index)) { 01151 01152 // 01153 // We didn't find a mapping, therefore this new mapping must 01154 // go on at the end of the current mapping. 01155 // 01156 // See if we can just grow the last mapping in the current mcb. 01157 // We can grow the last entry if (1) the Vbns follow on, and (2) 01158 // the Lbns follow on. We can only grow the last mapping if the 01159 // index is not 0. 01160 // 01161 01162 if ((Index != 0) && 01163 (PreviousEndingVbn(Mcb,Index) + 1 == Vbn) && 01164 (PreviousEndingLbn(Mcb,Index) + 1 == Lbn)) { 01165 01166 // 01167 // --LastRun--|---NewRun--| 01168 // 01169 01170 // 01171 // Extend the last run in the mcb 01172 // 01173 01174 DebugTrace( 0, Dbg, "Continuing last run\n", 0); 01175 01176 (Mcb->Mapping)[Mcb->PairCount-1].NextVbn += SectorCount; 01177 01178 try_return (Result = TRUE); 01179 } 01180 01181 // 01182 // We couldn't grow the last mapping, now check to see if 01183 // this is a continuation of the last Vbn (i.e., there isn't 01184 // going to be a hole in the mapping). Or if this is the first 01185 // run in the mapping 01186 // 01187 01188 if ((Vbn == 0) || 01189 (PreviousEndingVbn(Mcb,Index) + 1 == Vbn)) { 01190 01191 // 01192 // --LastRun--||---NewRun--| 01193 // 01194 // 0:|--NewRun--| 01195 // 01196 01197 // 01198 // We only need to add one more run to the mcb, so make sure 01199 // there is enough room for one. 01200 // 01201 01202 DebugTrace( 0, Dbg, "Adding new contiguous last run\n", 0); 01203 01204 FsRtlAddLargeEntry( Mcb, Index, 1 ); 01205 01206 // 01207 // Add the new mapping 01208 // 01209 01210 (Mcb->Mapping)[Index].Lbn = Lbn; 01211 (Mcb->Mapping)[Index].NextVbn = Vbn + SectorCount; 01212 01213 try_return (Result = TRUE); 01214 } 01215 01216 // 01217 // If we reach this point then there is going to be a hole in the 01218 // mapping. and the mapping gets appended to the end of the current 01219 // allocation. So need to make room for two more runs in the mcb. 01220 // 01221 01222 // 01223 // --LastRun--| hole |---NewRun--| 01224 // 01225 // 0: hole |--NewRun--| 01226 // 01227 01228 DebugTrace( 0, Dbg, "Adding new noncontiguous last run\n", 0); 01229 01230 FsRtlAddLargeEntry( Mcb, Index, 2 ); 01231 01232 // 01233 // Add the hole 01234 // 01235 01236 (Mcb->Mapping)[Index].Lbn = (LBN)UNUSED_LBN; 01237 (Mcb->Mapping)[Index].NextVbn = Vbn; 01238 01239 // 01240 // Add the new mapping 01241 // 01242 01243 (Mcb->Mapping)[Index+1].Lbn = Lbn; 01244 (Mcb->Mapping)[Index+1].NextVbn = Vbn + SectorCount; 01245 01246 try_return (Result = TRUE); 01247 } 01248 01249 // 01250 // We found an index for the Vbn therefore we must be trying 01251 // to fill up a hole in the mcb. So first we need to check to make 01252 // sure there really is a hole to be filled 01253 // 01254 01255 LastVbn = Vbn + SectorCount - 1; 01256 01257 if ((StartingLbn(Mcb,Index) == UNUSED_LBN) && 01258 (StartingVbn(Mcb,Index) <= Vbn) && (LastVbn <= EndingVbn(Mcb,Index))) { 01259 01260 // 01261 // The mapping fits in this hole, but now here are the following 01262 // cases we must consider for the new mapping 01263 // 01264 01265 if ((StartingVbn(Mcb,Index) < Vbn) && (LastVbn < EndingVbn(Mcb,Index))) { 01266 01267 // Leaves a hole are both ends 01268 // 01269 // --PreviousRun--| hole |--NewRun--| hole |--FollowingRun-- 01270 // 01271 // 0: hole |--NewRun--| hole |--FollowingRun-- 01272 // 01273 01274 DebugTrace( 0, Dbg, "Hole at both ends\n", 0); 01275 01276 // 01277 // Make room for two more entries. The NextVbn field of the 01278 // one we're shifting remains valid. 01279 // 01280 01281 FsRtlAddLargeEntry( Mcb, Index, 2 ); 01282 01283 // 01284 // Add the first hole 01285 // 01286 01287 (Mcb->Mapping)[Index].Lbn = (LBN)UNUSED_LBN; 01288 (Mcb->Mapping)[Index].NextVbn = Vbn; 01289 01290 // 01291 // Add the new mapping 01292 // 01293 01294 (Mcb->Mapping)[Index+1].Lbn = Lbn; 01295 (Mcb->Mapping)[Index+1].NextVbn = Vbn + SectorCount; 01296 01297 // 01298 // The second hole is already set up by the add entry call, because 01299 // that call just shift over the original hole to that slot 01300 // 01301 01302 try_return (Result = TRUE); 01303 } 01304 01305 if ((StartingVbn(Mcb,Index) == Vbn) && (LastVbn < EndingVbn(Mcb,Index))) { 01306 01307 if (PreviousEndingLbn(Mcb,Index) + 1 == Lbn) { 01308 01309 // 01310 // Leaves a hole at the rear, and continues the earlier run 01311 // 01312 // --PreviousRun--|--NewRun--| hole |--FollowingRun-- 01313 // 01314 01315 DebugTrace( 0, Dbg, "Hole at rear and continue\n", 0); 01316 01317 // 01318 // We just need to extend the previous run 01319 // 01320 01321 (Mcb->Mapping)[Index-1].NextVbn += SectorCount; 01322 01323 try_return (Result = TRUE); 01324 01325 } else { 01326 01327 // 01328 // Leaves a hole at the rear, and does not continue the 01329 // earlier run. As occurs if index is zero. 01330 // 01331 // --PreviousRun--||--NewRun--| hole |--FollowingRun-- 01332 // 01333 // 0:|--NewRun--| hole |--FollowingRun-- 01334 // 01335 01336 DebugTrace( 0, Dbg, "Hole at rear and not continue\n", 0); 01337 01338 // 01339 // Make room for one more entry. The NextVbn field of the 01340 // one we're shifting remains valid. 01341 // 01342 01343 FsRtlAddLargeEntry( Mcb, Index, 1 ); 01344 01345 // 01346 // Add the new mapping 01347 // 01348 01349 (Mcb->Mapping)[Index].Lbn = Lbn; 01350 (Mcb->Mapping)[Index].NextVbn = Vbn + SectorCount; 01351 01352 // 01353 // The hole is already set up by the add entry call, because 01354 // that call just shift over the original hole to that slot 01355 // 01356 01357 try_return (Result = TRUE); 01358 } 01359 } 01360 01361 if ((StartingVbn(Mcb,Index) < Vbn) && (LastVbn == EndingVbn(Mcb,Index))) { 01362 01363 if (NextStartingLbn(Mcb,Index) == Lbn + SectorCount) { 01364 01365 // 01366 // Leaves a hole at the front, and continues the following run 01367 // 01368 // --PreviousRun--| hole |--NewRun--|--FollowingRun-- 01369 // 01370 // 0: hole |--NewRun--|--FollowingRun-- 01371 // 01372 01373 DebugTrace( 0, Dbg, "Hole at front and continue\n", 0); 01374 01375 // 01376 // We just need to extend the following run 01377 // 01378 01379 (Mcb->Mapping)[Index].NextVbn = Vbn; 01380 (Mcb->Mapping)[Index+1].Lbn = Lbn; 01381 01382 try_return (Result = TRUE); 01383 01384 } else { 01385 01386 // 01387 // Leaves a hole at the front, and does not continue the following 01388 // run 01389 // 01390 // --PreviousRun--| hole |--NewRun--||--FollowingRun-- 01391 // 01392 // 0: hole |--NewRun--||--FollowingRun-- 01393 // 01394 01395 DebugTrace( 0, Dbg, "Hole at front and not continue\n", 0); 01396 01397 // 01398 // Make room for one more entry. The NextVbn field of the 01399 // one we're shifting remains valid. 01400 // 01401 01402 FsRtlAddLargeEntry( Mcb, Index, 1 ); 01403 01404 // 01405 // Add the hole 01406 // 01407 01408 (Mcb->Mapping)[Index].Lbn = (LBN)UNUSED_LBN; 01409 (Mcb->Mapping)[Index].NextVbn = Vbn; 01410 01411 // 01412 // Add the new mapping 01413 // 01414 01415 (Mcb->Mapping)[Index+1].Lbn = Lbn; 01416 01417 try_return (Result = TRUE); 01418 } 01419 01420 } 01421 01422 if ((PreviousEndingLbn(Mcb,Index) + 1 == Lbn) && 01423 (NextStartingLbn(Mcb,Index) == Lbn + SectorCount)) { 01424 01425 // 01426 // Leaves no holes, and continues both runs 01427 // 01428 // --PreviousRun--|--NewRun--|--FollowingRun-- 01429 // 01430 01431 DebugTrace( 0, Dbg, "No holes, and continues both runs\n", 0); 01432 01433 // 01434 // We need to collapse the current index and the following index 01435 // but first we copy the NextVbn of the follwing run into 01436 // the NextVbn field of the previous run to so it all becomes 01437 // one run 01438 // 01439 01440 (Mcb->Mapping)[Index-1].NextVbn = (Mcb->Mapping)[Index+1].NextVbn; 01441 01442 FsRtlRemoveLargeEntry( Mcb, Index, 2 ); 01443 01444 try_return (Result = TRUE); 01445 } 01446 01447 if (NextStartingLbn(Mcb,Index) == Lbn + SectorCount) { 01448 01449 // 01450 // Leaves no holes, and continues only following run 01451 // 01452 // --PreviousRun--||--NewRun--|--FollowingRun-- 01453 // 01454 // 0:|--NewRun--|--FollowingRun-- 01455 // 01456 01457 DebugTrace( 0, Dbg, "No holes, and continues following\n", 0); 01458 01459 // 01460 // This index is going away so we need to stretch the 01461 // following run to meet up with the previous run 01462 // 01463 01464 (Mcb->Mapping)[Index+1].Lbn = Lbn; 01465 01466 FsRtlRemoveLargeEntry( Mcb, Index, 1 ); 01467 01468 try_return (Result = TRUE); 01469 } 01470 01471 if (PreviousEndingLbn(Mcb,Index) + 1 == Lbn) { 01472 01473 // 01474 // Leaves no holes, and continues only earlier run 01475 // 01476 // --PreviousRun--|--NewRun--||--FollowingRun-- 01477 // 01478 01479 DebugTrace( 0, Dbg, "No holes, and continues earlier\n", 0); 01480 01481 // 01482 // This index is going away so we need to stretch the 01483 // previous run to meet up with the following run 01484 // 01485 01486 (Mcb->Mapping)[Index-1].NextVbn = (Mcb->Mapping)[Index].NextVbn; 01487 01488 FsRtlRemoveLargeEntry( Mcb, Index, 1 ); 01489 01490 try_return (Result = TRUE); 01491 } 01492 01493 // 01494 // Leaves no holes, and continues neither run 01495 // 01496 // --PreviousRun--||--NewRun--||--FollowingRun-- 01497 // 01498 // 0:|--NewRun--||--FollowingRun-- 01499 // 01500 01501 DebugTrace( 0, Dbg, "No holes, and continues none\n", 0); 01502 01503 (Mcb->Mapping)[Index].Lbn = Lbn; 01504 01505 try_return (Result = TRUE); 01506 } 01507 01508 // 01509 // We tried to overwrite an existing mapping so we'll have to 01510 // tell our caller that it's not possible 01511 // 01512 01513 Result = FALSE; 01514 01515 try_exit: NOTHING; 01516 } finally { 01517 01518 ExReleaseFastMutex( Mcb->FastMutex ); 01519 01520 DebugTrace(-1, Dbg, "FsRtlAddLargeMcbEntry -> %08lx\n", Result ); 01521 } 01522 01523 return Result; 01524 }

NTKERNELAPI BOOLEAN FsRtlAddMcbEntry IN PMCB  Mcb,
IN VBN  Vbn,
IN LBN  Lbn,
IN ULONG  SectorCount
 

Definition at line 375 of file largemcb.c.

References FsRtlAddLargeMcbEntry(), and PAGED_CODE.

Referenced by UdfAddVmcbMapping().

00382 { 00383 PAGED_CODE(); 00384 00385 return FsRtlAddLargeMcbEntry( (PLARGE_MCB)Mcb, 00386 (LONGLONG)(Vbn), 00387 (LONGLONG)(Lbn), 00388 (LONGLONG)(SectorCount) ); 00389 }

NTKERNELAPI VOID FsRtlAddToTunnelCache IN TUNNEL Cache,
IN ULONGLONG  DirectoryKey,
IN UNICODE_STRING *  ShortName,
IN UNICODE_STRING *  LongName,
IN BOOLEAN  KeyByShortName,
IN ULONG  DataLength,
IN VOID *  Data
 

PFILE_LOCK FsRtlAllocateFileLock IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine  OPTIONAL,
IN PUNLOCK_ROUTINE UnlockRoutine  OPTIONAL
 

Definition at line 1141 of file filelock.c.

References ExAllocateFromPagedLookasideList(), FsRtlFileLockLookasideList, FsRtlInitializeFileLock(), and NULL.

Referenced by UdfCreateFileLock().

01146 { 01147 PFILE_LOCK FileLock; 01148 01149 FileLock = ExAllocateFromPagedLookasideList( &FsRtlFileLockLookasideList ); 01150 01151 if (FileLock != NULL) { 01152 01153 FsRtlInitializeFileLock( FileLock, 01154 CompleteLockIrpRoutine, 01155 UnlockRoutine ); 01156 } 01157 01158 return FileLock; 01159 }

NTKERNELAPI PERESOURCE FsRtlAllocateResource  ) 
 

Definition at line 293 of file fsrtlpc.c.

References FSRTL_NUMBER_OF_RESOURCES, FsRtlPagingIoResources, FsRtlPagingIoResourceSelector, and PAGED_CODE.

00298 : 00299 00300 This routine is used to allocate a resource from the FsRtl pool. 00301 00302 Arguments: 00303 00304 Return Value: 00305 00306 PERESOURCE - A pointer to the provided resource. 00307 00308 --*/ 00309 00310 { 00311 PAGED_CODE(); 00312 00313 return &FsRtlPagingIoResources[ FsRtlPagingIoResourceSelector++ % 00314 FSRTL_NUMBER_OF_RESOURCES]; 00315 }

NTKERNELAPI BOOLEAN FsRtlAreNamesEqual PCUNICODE_STRING  ConstantNameA,
PCUNICODE_STRING  ConstantNameB,
IN BOOLEAN  IgnoreCase,
IN PCWCH UpcaseTable  OPTIONAL
 

Definition at line 288 of file name.c.

References ExRaiseStatus(), FALSE, Index, NT_SUCCESS, NTSTATUS(), PAGED_CODE, RtlFreeUnicodeString(), RtlUpcaseUnicodeString(), Status, and TRUE.

00297 : 00298 00299 This routine simple returns whether the two names are exactly equal. 00300 If the two names are known to be constant, this routine is much 00301 faster than FsRtlIsNameInExpression. 00302 00303 Arguments: 00304 00305 ConstantNameA - Constant name. 00306 00307 ConstantNameB - Constant name. 00308 00309 IgnoreCase - TRUE if the Names should be Upcased before comparing. 00310 00311 UpcaseTable - If supplied, use this table for case insensitive compares, 00312 otherwise, use the default system upcase table. 00313 00314 Return Value: 00315 00316 BOOLEAN - TRUE if the two names are lexically equal. 00317 00318 --*/ 00319 00320 { 00321 ULONG Index; 00322 ULONG NameLength; 00323 BOOLEAN FreeStrings = FALSE; 00324 00325 UNICODE_STRING LocalNameA; 00326 UNICODE_STRING LocalNameB; 00327 00328 PAGED_CODE(); 00329 00330 // 00331 // If the names aren't even the same size, then return FALSE right away. 00332 // 00333 00334 if ( ConstantNameA->Length != ConstantNameB->Length ) { 00335 00336 return FALSE; 00337 } 00338 00339 NameLength = ConstantNameA->Length / sizeof(WCHAR); 00340 00341 // 00342 // If we weren't given an upcase table, we have to upcase the names 00343 // ourselves. 00344 // 00345 00346 if ( IgnoreCase && !ARGUMENT_PRESENT(UpcaseTable) ) { 00347 00348 NTSTATUS Status; 00349 00350 Status = RtlUpcaseUnicodeString( &LocalNameA, ConstantNameA, TRUE ); 00351 00352 if ( !NT_SUCCESS(Status) ) { 00353 00354 ExRaiseStatus( Status ); 00355 } 00356 00357 Status = RtlUpcaseUnicodeString( &LocalNameB, ConstantNameB, TRUE ); 00358 00359 if ( !NT_SUCCESS(Status) ) { 00360 00361 RtlFreeUnicodeString( &LocalNameA ); 00362 00363 ExRaiseStatus( Status ); 00364 } 00365 00366 ConstantNameA = &LocalNameA; 00367 ConstantNameB = &LocalNameB; 00368 00369 IgnoreCase = FALSE; 00370 FreeStrings = TRUE; 00371 } 00372 00373 // 00374 // Do either case sensitive or insensitive compare. 00375 // 00376 00377 if ( !IgnoreCase ) { 00378 00379 BOOLEAN BytesEqual; 00380 00381 BytesEqual = (BOOLEAN) RtlEqualMemory( ConstantNameA->Buffer, 00382 ConstantNameB->Buffer, 00383 ConstantNameA->Length ); 00384 00385 if ( FreeStrings ) { 00386 00387 RtlFreeUnicodeString( &LocalNameA ); 00388 RtlFreeUnicodeString( &LocalNameB ); 00389 } 00390 00391 return BytesEqual; 00392 00393 } else { 00394 00395 for (Index = 0; Index < NameLength; Index += 1) { 00396 00397 if ( UpcaseTable[ConstantNameA->Buffer[Index]] != 00398 UpcaseTable[ConstantNameB->Buffer[Index]] ) { 00399 00400 return FALSE; 00401 } 00402 } 00403 00404 return TRUE; 00405 } 00406 }

NTKERNELAPI NTSTATUS FsRtlBalanceReads IN PDEVICE_OBJECT  TargetDevice  ) 
 

Definition at line 31 of file faulttol.c.

References ASSERT, Event(), Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, Irp, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, and Status.

00037 : 00038 00039 This routine signals a device driver that it is now OK to start 00040 balancing reads from a mirrored drive. This is typically called 00041 after the file system determines that a volume is clean. 00042 00043 Arguments: 00044 00045 TargetDevice - Supplies the device to start balanced read from. 00046 00047 Return Value: 00048 00049 NTSTATUS - The result of the operation. This will be 00050 STATUS_INVALID_DEVICE_REQUEST is the volume is not a mirror. 00051 00052 --*/ 00053 00054 { 00055 PIRP Irp; 00056 KEVENT Event; 00057 IO_STATUS_BLOCK Iosb; 00058 NTSTATUS Status; 00059 00060 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 00061 00062 Irp = IoBuildDeviceIoControlRequest( FT_BALANCED_READ_MODE, 00063 TargetDevice, 00064 NULL, 00065 0, 00066 NULL, 00067 0, 00068 FALSE, 00069 &Event, 00070 &Iosb ); 00071 00072 if ( Irp == NULL ) { 00073 00074 return STATUS_INSUFFICIENT_RESOURCES; 00075 } 00076 00077 Status = IoCallDriver( TargetDevice, Irp ); 00078 00079 00080 if (Status == STATUS_PENDING) { 00081 Status = KeWaitForSingleObject( &Event, 00082 Executive, 00083 KernelMode, 00084 FALSE, 00085 NULL ); 00086 00087 ASSERT( Status == STATUS_SUCCESS ); 00088 00089 Status = Iosb.Status; 00090 } 00091 00092 return Status; 00093 }

NTKERNELAPI BOOLEAN FsRtlCheckLockForReadAccess IN PFILE_LOCK  FileLock,
IN PIRP  Irp
 

Definition at line 1315 of file filelock.c.

References Dbg, DebugTrace, _LOCK_QUEUE::ExclusiveLockTree, _IO_STACK_LOCATION::FileObject, FsRtlFastCheckLockForRead(), IoGetCurrentIrpStackLocation, IoGetRequestorProcess(), Irp, Key, _LOCK_INFO::LockQueue, _LOCK_INFO::LowestLockOffset, NULL, _IO_STACK_LOCATION::Parameters, PLOCK_INFO, and TRUE.

Referenced by UdfCommonRead().

01322 : 01323 01324 This routine checks to see if the caller has read access to the 01325 range indicated in the IRP due to file locks. This call does not 01326 complete the Irp it only uses it to get the lock information and read 01327 information. The IRP must be for a read operation. 01328 01329 Arguments: 01330 01331 FileLock - Supplies the File Lock to check. 01332 01333 Irp - Supplies the Irp being processed. 01334 01335 Return Value: 01336 01337 BOOLEAN - TRUE if the indicated user/request has read access to the 01338 entire specified byte range, and FALSE otherwise 01339 01340 --*/ 01341 01342 { 01343 BOOLEAN Result; 01344 01345 PIO_STACK_LOCATION IrpSp; 01346 01347 PLOCK_INFO LockInfo; 01348 LARGE_INTEGER StartingByte; 01349 LARGE_INTEGER Length; 01350 ULONG Key; 01351 PFILE_OBJECT FileObject; 01352 PVOID ProcessId; 01353 LARGE_INTEGER BeyondLastByte; 01354 01355 DebugTrace(+1, Dbg, "FsRtlCheckLockForReadAccess, FileLock = %08lx\n", FileLock); 01356 01357 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 01358 DebugTrace(-1, Dbg, "FsRtlCheckLockForReadAccess (No current lock info) -> TRUE\n", 0); 01359 return TRUE; 01360 } 01361 01362 // 01363 // Do a really fast test to see if there are any exclusive locks to start with 01364 // 01365 01366 if (LockInfo->LockQueue.ExclusiveLockTree == NULL) { 01367 DebugTrace(-1, Dbg, "FsRtlCheckLockForReadAccess (No current locks) -> TRUE\n", 0); 01368 return TRUE; 01369 } 01370 01371 // 01372 // Get the read offset and compare it to the lowest existing lock. 01373 // 01374 01375 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 01376 01377 StartingByte = IrpSp->Parameters.Read.ByteOffset; 01378 (ULONGLONG)Length.QuadPart = (ULONGLONG)IrpSp->Parameters.Read.Length; 01379 01380 (ULONGLONG)BeyondLastByte.QuadPart = (ULONGLONG)StartingByte.QuadPart + Length.LowPart; 01381 if ( (ULONGLONG)BeyondLastByte.QuadPart <= (ULONGLONG)LockInfo->LowestLockOffset ) { 01382 DebugTrace(-1, Dbg, "FsRtlCheckLockForReadAccess (Below lowest lock) -> TRUE\n", 0); 01383 return TRUE; 01384 } 01385 01386 // 01387 // Get remaining parameters. 01388 // 01389 01390 Key = IrpSp->Parameters.Read.Key; 01391 FileObject = IrpSp->FileObject; 01392 ProcessId = IoGetRequestorProcess( Irp ); 01393 01394 // 01395 // Call our private work routine to do the real check 01396 // 01397 01398 Result = FsRtlFastCheckLockForRead( FileLock, 01399 &StartingByte, 01400 &Length, 01401 Key, 01402 FileObject, 01403 ProcessId ); 01404 01405 // 01406 // And return to our caller 01407 // 01408 01409 DebugTrace(-1, Dbg, "FsRtlCheckLockForReadAccess -> %08lx\n", Result); 01410 01411 return Result; 01412 }

NTKERNELAPI BOOLEAN FsRtlCheckLockForWriteAccess IN PFILE_LOCK  FileLock,
IN PIRP  Irp
 

Definition at line 1416 of file filelock.c.

References Dbg, DebugTrace, _LOCK_QUEUE::ExclusiveLockTree, _IO_STACK_LOCATION::FileObject, FsRtlFastCheckLockForWrite(), IoGetCurrentIrpStackLocation, IoGetRequestorProcess(), Irp, Key, _LOCK_INFO::LockQueue, _LOCK_INFO::LowestLockOffset, NULL, _IO_STACK_LOCATION::Parameters, PLOCK_INFO, _LOCK_QUEUE::SharedLockTree, and TRUE.

01423 : 01424 01425 This routine checks to see if the caller has write access to the 01426 indicated range due to file locks. This call does not complete the 01427 Irp it only uses it to get the lock information and write information. 01428 The IRP must be for a write operation. 01429 01430 Arguments: 01431 01432 FileLock - Supplies the File Lock to check. 01433 01434 Irp - Supplies the Irp being processed. 01435 01436 Return Value: 01437 01438 BOOLEAN - TRUE if the indicated user/request has write access to the 01439 entire specified byte range, and FALSE otherwise 01440 01441 --*/ 01442 01443 { 01444 BOOLEAN Result; 01445 01446 PIO_STACK_LOCATION IrpSp; 01447 01448 PLOCK_INFO LockInfo; 01449 LARGE_INTEGER StartingByte; 01450 LARGE_INTEGER Length; 01451 ULONG Key; 01452 PFILE_OBJECT FileObject; 01453 PVOID ProcessId; 01454 LARGE_INTEGER BeyondLastByte; 01455 01456 DebugTrace(+1, Dbg, "FsRtlCheckLockForWriteAccess, FileLock = %08lx\n", FileLock); 01457 01458 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 01459 DebugTrace(-1, Dbg, "FsRtlCheckLockForWriteAccess (No current lock info) -> TRUE\n", 0); 01460 return TRUE; 01461 } 01462 01463 // 01464 // Do a really fast test to see if there are any locks to start with 01465 // 01466 01467 if (LockInfo->LockQueue.ExclusiveLockTree == NULL && LockInfo->LockQueue.SharedLockTree == NULL) { 01468 DebugTrace(-1, Dbg, "FsRtlCheckLockForWriteAccess (No current locks) -> TRUE\n", 0); 01469 return TRUE; 01470 } 01471 01472 // 01473 // Get the write offset and compare it to the lowest existing lock. 01474 // 01475 01476 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 01477 01478 StartingByte = IrpSp->Parameters.Write.ByteOffset; 01479 (ULONGLONG)Length.QuadPart = (ULONGLONG)IrpSp->Parameters.Write.Length; 01480 01481 (ULONGLONG)BeyondLastByte.QuadPart = (ULONGLONG)StartingByte.QuadPart + Length.LowPart; 01482 if ( (ULONGLONG)BeyondLastByte.QuadPart <= (ULONGLONG)LockInfo->LowestLockOffset ) { 01483 DebugTrace(-1, Dbg, "FsRtlCheckLockForWriteAccess (Below lowest lock) -> TRUE\n", 0); 01484 return TRUE; 01485 } 01486 01487 // 01488 // Get remaining parameters. 01489 // 01490 01491 Key = IrpSp->Parameters.Write.Key; 01492 FileObject = IrpSp->FileObject; 01493 ProcessId = IoGetRequestorProcess( Irp ); 01494 01495 // 01496 // Call our private work routine to do the real work 01497 // 01498 01499 Result = FsRtlFastCheckLockForWrite( FileLock, 01500 &StartingByte, 01501 &Length, 01502 Key, 01503 FileObject, 01504 ProcessId ); 01505 01506 // 01507 // And return to our caller 01508 // 01509 01510 DebugTrace(-1, Dbg, "FsRtlCheckLockForWriteAccess -> %08lx\n", Result); 01511 01512 return Result; 01513 }

NTKERNELAPI NTSTATUS FsRtlCheckOplock IN POPLOCK  Oplock,
IN PIRP  Irp,
IN PVOID  Context,
IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine  OPTIONAL,
IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine  OPTIONAL
 

Definition at line 823 of file oplock.c.

References BATCH_OPLOCK, Dbg, DebugTrace, FALSE, _IO_STACK_LOCATION::FileObject, _NONOPAQUE_OPLOCK::FileObject, FILTER_OPLOCK, FILTER_OPLOCK_VALID_FLAGS, FlagOn, _IRP::Flags, FsRtlOplockBreakToII(), FsRtlOplockBreakToNone(), FsRtlOplockCleanup(), IoGetCurrentIrpStackLocation, Irp, IRP_MJ_CLEANUP, IRP_MJ_CREATE, IRP_MJ_FILE_SYSTEM_CONTROL, IRP_MJ_FLUSH_BUFFERS, IRP_MJ_LOCK_CONTROL, IRP_MJ_READ, IRP_MJ_SET_INFORMATION, IRP_MJ_WRITE, IRP_PAGING_IO, _IO_STACK_LOCATION::MajorFunction, NoOplocksHeld, NTSTATUS(), NULL, OPLOCK_STATE, OplockIIGranted, _NONOPAQUE_OPLOCK::OplockState, _IO_STACK_LOCATION::Parameters, PNONOPAQUE_OPLOCK, Status, and TRUE.

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

00833 : 00834 00835 This routine is called as a support routine from a file system. 00836 It is used to synchronize I/O requests with the current Oplock 00837 state of a file. If the I/O operation will cause the Oplock to 00838 break, that action is initiated. If the operation cannot continue 00839 until the Oplock break is complete, STATUS_PENDING is returned and 00840 the caller supplied routine is called. 00841 00842 Arguments: 00843 00844 Oplock - Supplies a pointer to the non-opaque oplock structure for 00845 this file. 00846 00847 Irp - Supplies a pointer to the Irp which declares the requested 00848 operation. 00849 00850 Context - This value is passed as a parameter to the completion routine. 00851 00852 CompletionRoutine - This is the routine which is called if this 00853 Irp must wait for an Oplock to break. This 00854 is a synchronous operation if not specified 00855 and we block in this thread waiting on 00856 an event. 00857 00858 PostIrpRoutine - This is the routine to call before we put anything 00859 on our waiting Irp queue. 00860 00861 Return Value: 00862 00863 STATUS_SUCCESS if we can complete the operation on exiting this thread. 00864 STATUS_PENDING if we return here but hold the Irp. 00865 STATUS_CANCELLED if the Irp is cancelled before we return. 00866 00867 --*/ 00868 00869 { 00870 NTSTATUS Status = STATUS_SUCCESS; 00871 PNONOPAQUE_OPLOCK ThisOplock = *Oplock; 00872 00873 PIO_STACK_LOCATION IrpSp; 00874 00875 DebugTrace( +1, Dbg, "FsRtlCheckOplock: Entered\n", 0 ); 00876 DebugTrace( 0, Dbg, "Oplock -> %08lx\n", Oplock ); 00877 DebugTrace( 0, Dbg, "Irp -> %08lx\n", Irp ); 00878 00879 // 00880 // If there is no oplock structure or this is system I/O, we allow 00881 // the operation to continue. Otherwise we check the major function code. 00882 // 00883 00884 if ((ThisOplock != NULL) && 00885 !FlagOn( Irp->Flags, IRP_PAGING_IO )) { 00886 00887 OPLOCK_STATE OplockState; 00888 PFILE_OBJECT OplockFileObject; 00889 00890 BOOLEAN BreakToII; 00891 BOOLEAN BreakToNone; 00892 00893 ULONG CreateDisposition; 00894 00895 // 00896 // Capture the file object first and then the oplock state to perform 00897 // the unsafe checks below. We capture the file object first in case 00898 // there is an exclusive oplock break in progress. Otherwise the oplock 00899 // state may indicate break in progress but it could complete by 00900 // the time we snap the file object. 00901 // 00902 00903 OplockFileObject = ThisOplock->FileObject; 00904 OplockState = ThisOplock->OplockState; 00905 00906 // 00907 // Examine the Irp for the appropriate action provided there are 00908 // current oplocks on the file. 00909 // 00910 00911 if (OplockState != NoOplocksHeld) { 00912 00913 BreakToII = FALSE; 00914 BreakToNone = FALSE; 00915 00916 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00917 00918 // 00919 // Determine whether we are going to BreakToII or BreakToNone. 00920 // 00921 00922 switch (IrpSp->MajorFunction) { 00923 00924 case IRP_MJ_CREATE : 00925 00926 // 00927 // If we are opening for attribute access only, we 00928 // return status success. Always break the oplock if this caller 00929 // wants a filter oplock. 00930 // 00931 00932 if (!FlagOn( IrpSp->Parameters.Create.SecurityContext->DesiredAccess, 00933 ~(FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | SYNCHRONIZE) ) && 00934 !FlagOn( IrpSp->Parameters.Create.Options, FILE_RESERVE_OPFILTER )) { 00935 00936 break; 00937 } 00938 00939 // 00940 // If there is a filter oplock granted and this create iS reading 00941 // the file then don't break the oplock as long as we share 00942 // for reads. 00943 // 00944 00945 if (FlagOn( OplockState, FILTER_OPLOCK ) && 00946 !FlagOn( IrpSp->Parameters.Create.SecurityContext->DesiredAccess, 00947 ~FILTER_OPLOCK_VALID_FLAGS ) && 00948 FlagOn( IrpSp->Parameters.Create.ShareAccess, FILE_SHARE_READ )) { 00949 00950 break; 00951 } 00952 00953 // 00954 // We we are superseding or overwriting, then break to none. 00955 // 00956 00957 CreateDisposition = (IrpSp->Parameters.Create.Options >> 24) & 0x000000ff; 00958 00959 if ((CreateDisposition == FILE_SUPERSEDE) || 00960 (CreateDisposition == FILE_OVERWRITE) || 00961 (CreateDisposition == FILE_OVERWRITE_IF) || 00962 FlagOn( IrpSp->Parameters.Create.Options, FILE_RESERVE_OPFILTER )) { 00963 00964 BreakToNone = TRUE; 00965 00966 } else { 00967 00968 BreakToII = TRUE; 00969 } 00970 00971 break; 00972 00973 case IRP_MJ_READ : 00974 00975 // 00976 // If a filter oplock has been granted then do nothing. 00977 // We will assume the oplock will have been broken 00978 // if this create needed to do that. 00979 // 00980 00981 if (!FlagOn( OplockState, FILTER_OPLOCK )) { 00982 00983 BreakToII = TRUE; 00984 } 00985 00986 break; 00987 00988 case IRP_MJ_FLUSH_BUFFERS : 00989 00990 BreakToII = TRUE; 00991 break; 00992 00993 case IRP_MJ_CLEANUP : 00994 00995 FsRtlOplockCleanup( (PNONOPAQUE_OPLOCK) *Oplock, 00996 IrpSp ); 00997 00998 break; 00999 01000 case IRP_MJ_LOCK_CONTROL : 01001 01002 // 01003 // If a filter oplock has been granted then do nothing. 01004 // We will assume the oplock will have been broken 01005 // if this create needed to do that. 01006 // 01007 01008 if (FlagOn( OplockState, FILTER_OPLOCK )) { 01009 01010 break; 01011 } 01012 01013 case IRP_MJ_WRITE : 01014 01015 BreakToNone = TRUE; 01016 break; 01017 01018 case IRP_MJ_SET_INFORMATION : 01019 01020 // 01021 // We are only interested in calls that shrink the file size 01022 // or breaking batch oplocks for the rename case. 01023 // 01024 01025 switch (IrpSp->Parameters.SetFile.FileInformationClass) { 01026 01027 case FileEndOfFileInformation : 01028 01029 // 01030 // Break immediately if this is the lazy writer callback. 01031 // 01032 01033 if (IrpSp->Parameters.SetFile.AdvanceOnly) { 01034 01035 break; 01036 } 01037 01038 case FileAllocationInformation : 01039 01040 BreakToNone = TRUE; 01041 break; 01042 01043 case FileRenameInformation : 01044 case FileLinkInformation : 01045 01046 if (FlagOn( OplockState, BATCH_OPLOCK | FILTER_OPLOCK )) { 01047 01048 BreakToNone = TRUE; 01049 } 01050 01051 break; 01052 } 01053 01054 case IRP_MJ_FILE_SYSTEM_CONTROL : 01055 01056 // 01057 // We need to break to none if this is a zeroing operation. 01058 // 01059 01060 if (IrpSp->Parameters.FileSystemControl.FsControlCode == FSCTL_SET_ZERO_DATA) { 01061 01062 BreakToNone = TRUE; 01063 } 01064 } 01065 01066 if (BreakToII) { 01067 01068 // 01069 // If there are no outstanding oplocks or level II oplocks are held, 01070 // we can return immediately. If the first two tests fail then there 01071 // is an exclusive oplock. If the file objects match we allow the 01072 // operation to continue. 01073 // 01074 01075 if ((OplockState != OplockIIGranted) && 01076 (OplockFileObject != IrpSp->FileObject)) { 01077 01078 Status = FsRtlOplockBreakToII( (PNONOPAQUE_OPLOCK) *Oplock, 01079 IrpSp, 01080 Irp, 01081 Context, 01082 CompletionRoutine, 01083 PostIrpRoutine ); 01084 } 01085 01086 } else if (BreakToNone) { 01087 01088 // 01089 // If there are no oplocks, we can return immediately. 01090 // Otherwise if there is no level 2 oplock and this file 01091 // object matches the owning file object then this write is 01092 // on behalf of the owner of the oplock. 01093 // 01094 01095 if ((OplockState == OplockIIGranted) || 01096 (OplockFileObject != IrpSp->FileObject)) { 01097 01098 Status = FsRtlOplockBreakToNone( (PNONOPAQUE_OPLOCK) *Oplock, 01099 IrpSp, 01100 Irp, 01101 Context, 01102 CompletionRoutine, 01103 PostIrpRoutine ); 01104 } 01105 } 01106 } 01107 } 01108 01109 DebugTrace( -1, Dbg, "FsRtlCheckOplock: Exit -> %08lx\n", Status ); 01110 01111 return Status; 01112 }

NTKERNELAPI BOOLEAN FsRtlCopyRead IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
OUT PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 54 of file fastio.c.

References ASSERT, Buffer, CcCopyRead(), CcFastCopyRead(), CcFastReadNotPossible, CcFastReadNoWait, CcFastReadResourceMiss, CcFastReadWait, COMPUTE_PAGES_SPANNED, _DEVICE_OBJECT::DriverObject, ExAcquireResourceShared, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, ExReleaseResource, FALSE, _FAST_IO_DISPATCH::FastIoCheckIfPossible, _DRIVER_OBJECT::FastIoDispatch, FastIoIsNotPossible, FastIoIsQuestionable, FO_FILE_FAST_IO_READ, FSRTL_FAST_IO_TOP_LEVEL_IRP, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlIsNtstatusExpected(), Header, HOT_STATISTIC, IoGetRelatedDeviceObject(), NULL, PAGED_CODE, PFAST_IO_DISPATCH, PsGetCurrentThread, Status, TRUE, and VOID().

Referenced by UdfInitializeGlobalData().

00067 : 00068 00069 This routine does a fast cached read bypassing the usual file system 00070 entry routine (i.e., without the Irp). It is used to do a copy read 00071 of a cached file object. For a complete description of the arguments 00072 see CcCopyRead. 00073 00074 Arguments: 00075 00076 FileObject - Pointer to the file object being read. 00077 00078 FileOffset - Byte offset in file for desired data. 00079 00080 Length - Length of desired data in bytes. 00081 00082 Wait - FALSE if caller may not block, TRUE otherwise 00083 00084 Buffer - Pointer to output buffer to which data should be copied. 00085 00086 IoStatus - Pointer to standard I/O status block to receive the status 00087 for the transfer. 00088 00089 Return Value: 00090 00091 FALSE - if Wait was supplied as FALSE and the data was not delivered, or 00092 if there is an I/O error. 00093 00094 TRUE - if the data is being delivered 00095 00096 --*/ 00097 00098 { 00099 PFSRTL_COMMON_FCB_HEADER Header; 00100 BOOLEAN Status = TRUE; 00101 ULONG PageCount = COMPUTE_PAGES_SPANNED( FileOffset->QuadPart, Length ); 00102 LARGE_INTEGER BeyondLastByte; 00103 PDEVICE_OBJECT targetVdo; 00104 00105 PAGED_CODE(); 00106 00107 // 00108 // Special case a read of zero length 00109 // 00110 00111 if (Length != 0) { 00112 00113 // 00114 // Check for overflow. Returning false here will re-route this request through the 00115 // IRP based path, but this isn't performance critical. 00116 // 00117 00118 if (MAXLONGLONG - FileOffset->QuadPart < (LONGLONG)Length) { 00119 00120 IoStatus->Status = STATUS_INVALID_PARAMETER; 00121 IoStatus->Information = 0; 00122 00123 return FALSE; 00124 } 00125 00126 BeyondLastByte.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 00127 Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 00128 00129 // 00130 // Enter the file system 00131 // 00132 00133 FsRtlEnterFileSystem(); 00134 00135 // 00136 // Increment performance counters and get the resource 00137 // 00138 00139 if (Wait) { 00140 00141 HOT_STATISTIC(CcFastReadWait) += 1; 00142 00143 // 00144 // Acquired shared on the common fcb header 00145 // 00146 00147 (VOID)ExAcquireResourceShared( Header->Resource, TRUE ); 00148 00149 } else { 00150 00151 HOT_STATISTIC(CcFastReadNoWait) += 1; 00152 00153 // 00154 // Acquired shared on the common fcb header, and return if we 00155 // don't get it 00156 // 00157 00158 if (!ExAcquireResourceShared( Header->Resource, FALSE )) { 00159 00160 FsRtlExitFileSystem(); 00161 00162 CcFastReadResourceMiss += 1; 00163 00164 return FALSE; 00165 } 00166 } 00167 00168 // 00169 // Now that the File is acquired shared, we can safely test if it 00170 // is really cached and if we can do fast i/o and if not, then 00171 // release the fcb and return. 00172 // 00173 00174 if ((FileObject->PrivateCacheMap == NULL) || 00175 (Header->IsFastIoPossible == FastIoIsNotPossible)) { 00176 00177 ExReleaseResource( Header->Resource ); 00178 FsRtlExitFileSystem(); 00179 00180 HOT_STATISTIC(CcFastReadNotPossible) += 1; 00181 00182 return FALSE; 00183 } 00184 00185 // 00186 // Check if fast I/O is questionable and if so then go ask the 00187 // file system the answer 00188 // 00189 00190 if (Header->IsFastIoPossible == FastIoIsQuestionable) { 00191 00192 PFAST_IO_DISPATCH FastIoDispatch; 00193 00194 ASSERT(!KeIsExecutingDpc()); 00195 00196 targetVdo = IoGetRelatedDeviceObject( FileObject ); 00197 FastIoDispatch = targetVdo->DriverObject->FastIoDispatch; 00198 00199 00200 // 00201 // All file systems that set "Is Questionable" had better support 00202 // fast I/O 00203 // 00204 00205 ASSERT(FastIoDispatch != NULL); 00206 ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); 00207 00208 // 00209 // Call the file system to check for fast I/O. If the answer is 00210 // anything other than GoForIt then we cannot take the fast I/O 00211 // path. 00212 // 00213 00214 if (!FastIoDispatch->FastIoCheckIfPossible( FileObject, 00215 FileOffset, 00216 Length, 00217 Wait, 00218 LockKey, 00219 TRUE, // read operation 00220 IoStatus, 00221 targetVdo )) { 00222 00223 // 00224 // Fast I/O is not possible so release the Fcb and return. 00225 // 00226 00227 ExReleaseResource( Header->Resource ); 00228 FsRtlExitFileSystem(); 00229 00230 HOT_STATISTIC(CcFastReadNotPossible) += 1; 00231 00232 return FALSE; 00233 } 00234 } 00235 00236 // 00237 // Check for read past file size. 00238 // 00239 00240 if ( BeyondLastByte.QuadPart > Header->FileSize.QuadPart ) { 00241 00242 if ( FileOffset->QuadPart >= Header->FileSize.QuadPart ) { 00243 IoStatus->Status = STATUS_END_OF_FILE; 00244 IoStatus->Information = 0; 00245 00246 ExReleaseResource( Header->Resource ); 00247 FsRtlExitFileSystem(); 00248 00249 return TRUE; 00250 } 00251 00252 Length = (ULONG)( Header->FileSize.QuadPart - FileOffset->QuadPart ); 00253 } 00254 00255 // 00256 // We can do fast i/o so call the cc routine to do the work and then 00257 // release the fcb when we've done. If for whatever reason the 00258 // copy read fails, then return FALSE to our caller. 00259 // 00260 // Also mark this as the top level "Irp" so that lower file system 00261 // levels will not attempt a pop-up 00262 // 00263 00264 PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; 00265 00266 try { 00267 00268 if (Wait && ((BeyondLastByte.HighPart | Header->FileSize.HighPart) == 0)) { 00269 00270 CcFastCopyRead( FileObject, 00271 FileOffset->LowPart, 00272 Length, 00273 PageCount, 00274 Buffer, 00275 IoStatus ); 00276 00277 FileObject->Flags |= FO_FILE_FAST_IO_READ; 00278 00279 ASSERT( (IoStatus->Status == STATUS_END_OF_FILE) || 00280 ((FileOffset->LowPart + IoStatus->Information) <= Header->FileSize.LowPart)); 00281 00282 } else { 00283 00284 Status = CcCopyRead( FileObject, 00285 FileOffset, 00286 Length, 00287 Wait, 00288 Buffer, 00289 IoStatus ); 00290 00291 FileObject->Flags |= FO_FILE_FAST_IO_READ; 00292 00293 ASSERT( !Status || (IoStatus->Status == STATUS_END_OF_FILE) || 00294 ((LONGLONG)(FileOffset->QuadPart + IoStatus->Information) <= Header->FileSize.QuadPart)); 00295 } 00296 00297 if (Status) { 00298 00299 FileObject->CurrentByteOffset.QuadPart = FileOffset->QuadPart + IoStatus->Information; 00300 } 00301 00302 } except( FsRtlIsNtstatusExpected(GetExceptionCode()) 00303 ? EXCEPTION_EXECUTE_HANDLER 00304 : EXCEPTION_CONTINUE_SEARCH ) { 00305 00306 Status = FALSE; 00307 } 00308 00309 PsGetCurrentThread()->TopLevelIrp = 0; 00310 00311 ExReleaseResource( Header->Resource ); 00312 FsRtlExitFileSystem(); 00313 return Status; 00314 00315 } else { 00316 00317 // 00318 // A zero length transfer was requested. 00319 // 00320 00321 IoStatus->Status = STATUS_SUCCESS; 00322 IoStatus->Information = 0; 00323 00324 return TRUE; 00325 } 00326 }

NTKERNELAPI BOOLEAN FsRtlCopyWrite IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN BOOLEAN  Wait,
IN ULONG  LockKey,
IN PVOID  Buffer,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 330 of file fastio.c.

References ASSERT, Buffer, CcCanIWrite(), CcCopyWrite(), CcCopyWriteWontFlush, CcFastCopyWrite(), CcGetFileSizePointer, CcZeroData(), _DEVICE_OBJECT::DriverObject, ExAcquireResourceExclusive, ExAcquireResourceShared, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, ExReleaseResource, FALSE, _FAST_IO_DISPATCH::FastIoCheckIfPossible, _DRIVER_OBJECT::FastIoDispatch, FastIoIsNotPossible, FastIoIsQuestionable, FlagOn, FO_FILE_MODIFIED, FO_FILE_SIZE_CHANGED, FO_WRITE_THROUGH, FSRTL_FAST_IO_TOP_LEVEL_IRP, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlIsNtstatusExpected(), Header, IoGetRelatedDeviceObject(), NULL, Offset, PAGED_CODE, PsGetCurrentThread, Status, TRUE, and VOID().

00343 : 00344 00345 This routine does a fast cached write bypassing the usual file system 00346 entry routine (i.e., without the Irp). It is used to do a copy write 00347 of a cached file object. For a complete description of the arguments 00348 see CcCopyWrite. 00349 00350 Arguments: 00351 00352 FileObject - Pointer to the file object being write. 00353 00354 FileOffset - Byte offset in file for desired data. 00355 00356 Length - Length of desired data in bytes. 00357 00358 Wait - FALSE if caller may not block, TRUE otherwise 00359 00360 Buffer - Pointer to output buffer to which data should be copied. 00361 00362 IoStatus - Pointer to standard I/O status block to receive the status 00363 for the transfer. 00364 00365 Return Value: 00366 00367 FALSE - if Wait was supplied as FALSE and the data was not delivered, or 00368 if there is an I/O error. 00369 00370 TRUE - if the data is being delivered 00371 00372 --*/ 00373 00374 { 00375 PFSRTL_COMMON_FCB_HEADER Header; 00376 BOOLEAN AcquiredShared = FALSE; 00377 BOOLEAN Status = TRUE; 00378 BOOLEAN FileSizeChanged = FALSE; 00379 BOOLEAN WriteToEndOfFile = (BOOLEAN)((FileOffset->LowPart == FILE_WRITE_TO_END_OF_FILE) && 00380 (FileOffset->HighPart == -1)); 00381 00382 PAGED_CODE(); 00383 00384 // 00385 // Get a real pointer to the common fcb header 00386 // 00387 00388 Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 00389 00390 // 00391 // Do we need to verify the volume? If so, we must go to the file 00392 // system. Also return FALSE if FileObject is write through, the 00393 // File System must do that. 00394 // 00395 00396 if (CcCanIWrite( FileObject, Length, Wait, FALSE ) && 00397 !FlagOn(FileObject->Flags, FO_WRITE_THROUGH) && 00398 CcCopyWriteWontFlush(FileObject, FileOffset, Length)) { 00399 00400 // 00401 // Assume our transfer will work 00402 // 00403 00404 IoStatus->Status = STATUS_SUCCESS; 00405 IoStatus->Information = Length; 00406 00407 // 00408 // Special case the zero byte length 00409 // 00410 00411 if (Length != 0) { 00412 00413 // 00414 // Enter the file system 00415 // 00416 00417 FsRtlEnterFileSystem(); 00418 00419 // 00420 // Split into separate paths for increased performance. First 00421 // we have the faster path which only supports Wait == TRUE and 00422 // 32 bits. We will make an unsafe test on whether the fast path 00423 // is ok, then just return FALSE later if we were wrong. This 00424 // should virtually never happen. 00425 // 00426 // IMPORTANT NOTE: It is very important that any changes made to 00427 // this path also be applied to the 64-bit path 00428 // which is the else of this test! 00429 // 00430 00431 if (Wait && (Header->AllocationSize.HighPart == 0)) { 00432 00433 ULONG Offset, NewFileSize; 00434 ULONG OldFileSize; 00435 ULONG OldValidDataLength; 00436 BOOLEAN Wrapped; 00437 00438 // 00439 // Make our best guess on whether we need the file exclusive 00440 // or shared. Note that we do not check FileOffset->HighPart 00441 // until below. 00442 // 00443 00444 NewFileSize = FileOffset->LowPart + Length; 00445 00446 if (WriteToEndOfFile || (NewFileSize > Header->ValidDataLength.LowPart)) { 00447 00448 // 00449 // Acquired shared on the common fcb header 00450 // 00451 00452 ExAcquireResourceExclusive( Header->Resource, TRUE ); 00453 00454 } else { 00455 00456 // 00457 // Acquired shared on the common fcb header 00458 // 00459 00460 ExAcquireResourceShared( Header->Resource, TRUE ); 00461 00462 AcquiredShared = TRUE; 00463 } 00464 00465 // 00466 // We have the fcb shared now check if we can do fast i/o 00467 // and if the file space is allocated, and if not then 00468 // release the fcb and return. 00469 // 00470 00471 if (WriteToEndOfFile) { 00472 00473 Offset = Header->FileSize.LowPart; 00474 NewFileSize = Header->FileSize.LowPart + Length; 00475 Wrapped = NewFileSize < Header->FileSize.LowPart; 00476 00477 } else { 00478 00479 Offset = FileOffset->LowPart; 00480 NewFileSize = FileOffset->LowPart + Length; 00481 Wrapped = (NewFileSize < FileOffset->LowPart) || (FileOffset->HighPart != 0); 00482 } 00483 00484 // 00485 // Now that the File is acquired shared, we can safely test 00486 // if it is really cached and if we can do fast i/o and we 00487 // do not have to extend. If not then release the fcb and 00488 // return. 00489 // 00490 // Get out if we have too much to zero. This case is not important 00491 // for performance, and a file system supporting sparseness may have 00492 // a way to do this more efficiently. 00493 // 00494 00495 if ((FileObject->PrivateCacheMap == NULL) || 00496 (Header->IsFastIoPossible == FastIoIsNotPossible) || 00497 (NewFileSize > Header->AllocationSize.LowPart) || 00498 (Offset >= (Header->ValidDataLength.LowPart + 0x2000)) || 00499 (Header->AllocationSize.HighPart != 0) || Wrapped) { 00500 00501 ExReleaseResource( Header->Resource ); 00502 FsRtlExitFileSystem(); 00503 00504 return FALSE; 00505 } 00506 00507 // 00508 // If we will be extending ValidDataLength, we will have to 00509 // get the Fcb exclusive, and make sure that FastIo is still 00510 // possible. We should only execute this block of code very 00511 // rarely, when the unsafe test for ValidDataLength failed 00512 // above. 00513 // 00514 00515 if (AcquiredShared && (NewFileSize > Header->ValidDataLength.LowPart)) { 00516 00517 ExReleaseResource( Header->Resource ); 00518 00519 ExAcquireResourceExclusive( Header->Resource, TRUE ); 00520 00521 // 00522 // If writing to end of file, we must recalculate new size. 00523 // 00524 00525 if (WriteToEndOfFile) { 00526 00527 Offset = Header->FileSize.LowPart; 00528 NewFileSize = Header->FileSize.LowPart + Length; 00529 Wrapped = NewFileSize < Header->FileSize.LowPart; 00530 } 00531 00532 if ((FileObject->PrivateCacheMap == NULL) || 00533 (Header->IsFastIoPossible == FastIoIsNotPossible) || 00534 (NewFileSize > Header->AllocationSize.LowPart) || 00535 (Header->AllocationSize.HighPart != 0) || Wrapped) { 00536 00537 ExReleaseResource( Header->Resource ); 00538 FsRtlExitFileSystem(); 00539 00540 return FALSE; 00541 } 00542 } 00543 00544 // 00545 // Check if fast I/O is questionable and if so then go ask 00546 // the file system the answer 00547 // 00548 00549 if (Header->IsFastIoPossible == FastIoIsQuestionable) { 00550 00551 PDEVICE_OBJECT targetVdo = IoGetRelatedDeviceObject( FileObject ); 00552 PFAST_IO_DISPATCH FastIoDispatch = targetVdo->DriverObject->FastIoDispatch; 00553 IO_STATUS_BLOCK IoStatus; 00554 00555 // 00556 // All file system then set "Is Questionable" had better 00557 // support fast I/O 00558 // 00559 00560 ASSERT(FastIoDispatch != NULL); 00561 ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); 00562 00563 // 00564 // Call the file system to check for fast I/O. If the 00565 // answer is anything other than GoForIt then we cannot 00566 // take the fast I/O path. 00567 // 00568 00569 ASSERT(FILE_WRITE_TO_END_OF_FILE == 0xffffffff); 00570 00571 if (!FastIoDispatch->FastIoCheckIfPossible( FileObject, 00572 FileOffset->QuadPart != (LONGLONG)-1 ? 00573 FileOffset : &Header->FileSize, 00574 Length, 00575 TRUE, 00576 LockKey, 00577 FALSE, // write operation 00578 &IoStatus, 00579 targetVdo )) { 00580 00581 // 00582 // Fast I/O is not possible so release the Fcb and 00583 // return. 00584 // 00585 00586 ExReleaseResource( Header->Resource ); 00587 FsRtlExitFileSystem(); 00588 00589 return FALSE; 00590 } 00591 } 00592 00593 // 00594 // Now see if we will change FileSize. We have to do it now 00595 // so that our reads are not nooped. 00596 // 00597 00598 if (NewFileSize > Header->FileSize.LowPart) { 00599 00600 FileSizeChanged = TRUE; 00601 OldFileSize = Header->FileSize.LowPart; 00602 OldValidDataLength = Header->ValidDataLength.LowPart; 00603 Header->FileSize.LowPart = NewFileSize; 00604 } 00605 00606 // 00607 // We can do fast i/o so call the cc routine to do the work 00608 // and then release the fcb when we've done. If for whatever 00609 // reason the copy write fails, then return FALSE to our 00610 // caller. 00611 // 00612 // Also mark this as the top level "Irp" so that lower file 00613 // system levels will not attempt a pop-up 00614 // 00615 00616 PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; 00617 00618 try { 00619 00620 // 00621 // See if we have to do some zeroing 00622 // 00623 00624 if (Offset > Header->ValidDataLength.LowPart) { 00625 00626 LARGE_INTEGER ZeroEnd; 00627 00628 ZeroEnd.LowPart = Offset; 00629 ZeroEnd.HighPart = 0; 00630 00631 CcZeroData( FileObject, 00632 &Header->ValidDataLength, 00633 &ZeroEnd, 00634 TRUE ); 00635 } 00636 00637 CcFastCopyWrite( FileObject, 00638 Offset, 00639 Length, 00640 Buffer ); 00641 00642 } except( FsRtlIsNtstatusExpected(GetExceptionCode()) 00643 ? EXCEPTION_EXECUTE_HANDLER 00644 : EXCEPTION_CONTINUE_SEARCH ) { 00645 00646 Status = FALSE; 00647 } 00648 00649 PsGetCurrentThread()->TopLevelIrp = 0; 00650 00651 // 00652 // If we succeeded, see if we have to update FileSize or 00653 // ValidDataLength. 00654 // 00655 00656 if (Status) { 00657 00658 // 00659 // In the case of ValidDataLength, we really have to 00660 // check again since we did not do this when we acquired 00661 // the resource exclusive. 00662 // 00663 00664 if (NewFileSize > Header->ValidDataLength.LowPart) { 00665 00666 Header->ValidDataLength.LowPart = NewFileSize; 00667 } 00668 00669 // 00670 // Set this handle as having modified the file 00671 // 00672 00673 FileObject->Flags |= FO_FILE_MODIFIED; 00674 00675 if (FileSizeChanged) { 00676 00677 CcGetFileSizePointer(FileObject)->LowPart = NewFileSize; 00678 00679 FileObject->Flags |= FO_FILE_SIZE_CHANGED; 00680 } 00681 00682 // 00683 // Also update the file position pointer 00684 // 00685 00686 FileObject->CurrentByteOffset.LowPart = Offset + Length; 00687 FileObject->CurrentByteOffset.HighPart = 0; 00688 00689 // 00690 // If we did not succeed, then we must restore the original 00691 // FileSize while holding the PagingIoResource exclusive if 00692 // it exists. 00693 // 00694 00695 } else if (FileSizeChanged) { 00696 00697 if ( Header->PagingIoResource != NULL ) { 00698 00699 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 00700 Header->FileSize.LowPart = OldFileSize; 00701 Header->ValidDataLength.LowPart = OldValidDataLength; 00702 ExReleaseResource( Header->PagingIoResource ); 00703 00704 } else { 00705 00706 Header->FileSize.LowPart = OldFileSize; 00707 Header->ValidDataLength.LowPart = OldValidDataLength; 00708 } 00709 } 00710 00711 // 00712 // Here is the 64-bit or no-wait path. 00713 // 00714 00715 } else { 00716 00717 LARGE_INTEGER Offset, NewFileSize; 00718 LARGE_INTEGER OldFileSize; 00719 LARGE_INTEGER OldValidDataLength; 00720 00721 ASSERT(!KeIsExecutingDpc()); 00722 00723 // 00724 // Make our best guess on whether we need the file exclusive 00725 // or shared. 00726 // 00727 00728 NewFileSize.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 00729 00730 if (WriteToEndOfFile || (NewFileSize.QuadPart > Header->ValidDataLength.QuadPart)) { 00731 00732 // 00733 // Acquired shared on the common fcb header, and return 00734 // if we don't get it. 00735 // 00736 00737 if (!ExAcquireResourceExclusive( Header->Resource, Wait )) { 00738 00739 FsRtlExitFileSystem(); 00740 00741 return FALSE; 00742 } 00743 00744 } else { 00745 00746 // 00747 // Acquired shared on the common fcb header, and return 00748 // if we don't get it. 00749 // 00750 00751 if (!ExAcquireResourceShared( Header->Resource, Wait )) { 00752 00753 FsRtlExitFileSystem(); 00754 00755 return FALSE; 00756 } 00757 00758 AcquiredShared = TRUE; 00759 } 00760 00761 00762 // 00763 // We have the fcb shared now check if we can do fast i/o 00764 // and if the file space is allocated, and if not then 00765 // release the fcb and return. 00766 // 00767 00768 if (WriteToEndOfFile) { 00769 00770 Offset = Header->FileSize; 00771 NewFileSize.QuadPart = Header->FileSize.QuadPart + (LONGLONG)Length; 00772 00773 } else { 00774 00775 Offset = *FileOffset; 00776 NewFileSize.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 00777 } 00778 00779 // 00780 // Now that the File is acquired shared, we can safely test 00781 // if it is really cached and if we can do fast i/o and we 00782 // do not have to extend. If not then release the fcb and 00783 // return. 00784 // 00785 // Get out if we are about to zero too much as well, as commented above. 00786 // Likewise, for NewFileSizes that exceed MAXLONGLONG. 00787 // 00788 00789 if ((FileObject->PrivateCacheMap == NULL) || 00790 (Header->IsFastIoPossible == FastIoIsNotPossible) || 00791 (Offset.QuadPart >= (Header->ValidDataLength.QuadPart + 0x2000)) || 00792 (MAXLONGLONG - Offset.QuadPart < (LONGLONG)Length) || 00793 (NewFileSize.QuadPart > Header->AllocationSize.QuadPart) ) { 00794 00795 ExReleaseResource( Header->Resource ); 00796 FsRtlExitFileSystem(); 00797 00798 return FALSE; 00799 } 00800 00801 // 00802 // If we will be extending ValidDataLength, we will have to 00803 // get the Fcb exclusive, and make sure that FastIo is still 00804 // possible. We should only execute this block of code very 00805 // rarely, when the unsafe test for ValidDataLength failed 00806 // above. 00807 // 00808 00809 if (AcquiredShared && ( NewFileSize.QuadPart > Header->ValidDataLength.QuadPart )) { 00810 00811 ExReleaseResource( Header->Resource ); 00812 00813 if (!ExAcquireResourceExclusive( Header->Resource, Wait )) { 00814 00815 FsRtlExitFileSystem(); 00816 00817 return FALSE; 00818 } 00819 00820 // 00821 // If writing to end of file, we must recalculate new size. 00822 // 00823 00824 if (WriteToEndOfFile) { 00825 00826 Offset = Header->FileSize; 00827 NewFileSize.QuadPart = Header->FileSize.QuadPart + (LONGLONG)Length; 00828 } 00829 00830 if ((FileObject->PrivateCacheMap == NULL) || 00831 (Header->IsFastIoPossible == FastIoIsNotPossible) || 00832 ( NewFileSize.QuadPart > Header->AllocationSize.QuadPart ) ) { 00833 00834 ExReleaseResource( Header->Resource ); 00835 FsRtlExitFileSystem(); 00836 00837 return FALSE; 00838 } 00839 } 00840 00841 // 00842 // Check if fast I/O is questionable and if so then go ask 00843 // the file system the answer 00844 // 00845 00846 if (Header->IsFastIoPossible == FastIoIsQuestionable) { 00847 00848 PFAST_IO_DISPATCH FastIoDispatch = IoGetRelatedDeviceObject( FileObject )->DriverObject->FastIoDispatch; 00849 IO_STATUS_BLOCK IoStatus; 00850 00851 // 00852 // All file system then set "Is Questionable" had better 00853 // support fast I/O 00854 // 00855 00856 ASSERT(FastIoDispatch != NULL); 00857 ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); 00858 00859 // 00860 // Call the file system to check for fast I/O. If the 00861 // answer is anything other than GoForIt then we cannot 00862 // take the fast I/O path. 00863 // 00864 00865 ASSERT(FILE_WRITE_TO_END_OF_FILE == 0xffffffff); 00866 00867 if (!FastIoDispatch->FastIoCheckIfPossible( FileObject, 00868 FileOffset->QuadPart != (LONGLONG)-1 ? 00869 FileOffset : &Header->FileSize, 00870 Length, 00871 Wait, 00872 LockKey, 00873 FALSE, // write operation 00874 &IoStatus, 00875 DeviceObject )) { 00876 00877 // 00878 // Fast I/O is not possible so release the Fcb and 00879 // return. 00880 // 00881 00882 ExReleaseResource( Header->Resource ); 00883 FsRtlExitFileSystem(); 00884 00885 return FALSE; 00886 } 00887 } 00888 00889 // 00890 // Now see if we will change FileSize. We have to do it now 00891 // so that our reads are not nooped. 00892 // 00893 00894 if ( NewFileSize.QuadPart > Header->FileSize.QuadPart ) { 00895 00896 FileSizeChanged = TRUE; 00897 OldFileSize = Header->FileSize; 00898 OldValidDataLength = Header->ValidDataLength; 00899 00900 // 00901 // Deal with an extremely rare pathalogical case here the 00902 // file size wraps. 00903 // 00904 00905 if ( (Header->FileSize.HighPart != NewFileSize.HighPart) && 00906 (Header->PagingIoResource != NULL) ) { 00907 00908 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 00909 Header->FileSize = NewFileSize; 00910 ExReleaseResource( Header->PagingIoResource ); 00911 00912 } else { 00913 00914 Header->FileSize = NewFileSize; 00915 } 00916 } 00917 00918 // 00919 // We can do fast i/o so call the cc routine to do the work 00920 // and then release the fcb when we've done. If for whatever 00921 // reason the copy write fails, then return FALSE to our 00922 // caller. 00923 // 00924 // Also mark this as the top level "Irp" so that lower file 00925 // system levels will not attempt a pop-up 00926 // 00927 00928 PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; 00929 00930 try { 00931 00932 // 00933 // See if we have to do some zeroing 00934 // 00935 00936 if ( Offset.QuadPart > Header->ValidDataLength.QuadPart ) { 00937 00938 Status = CcZeroData( FileObject, 00939 &Header->ValidDataLength, 00940 &Offset, 00941 Wait ); 00942 } 00943 00944 if (Status) { 00945 00946 Status = CcCopyWrite( FileObject, 00947 &Offset, 00948 Length, 00949 Wait, 00950 Buffer ); 00951 } 00952 00953 } except( FsRtlIsNtstatusExpected(GetExceptionCode()) 00954 ? EXCEPTION_EXECUTE_HANDLER 00955 : EXCEPTION_CONTINUE_SEARCH ) { 00956 00957 Status = FALSE; 00958 } 00959 00960 PsGetCurrentThread()->TopLevelIrp = 0; 00961 00962 // 00963 // If we succeeded, see if we have to update FileSize or 00964 // ValidDataLength. 00965 // 00966 00967 if (Status) { 00968 00969 // 00970 // In the case of ValidDataLength, we really have to 00971 // check again since we did not do this when we acquired 00972 // the resource exclusive. 00973 // 00974 00975 if ( NewFileSize.QuadPart > Header->ValidDataLength.QuadPart ) { 00976 00977 // 00978 // Deal with an extremely rare pathalogical case here 00979 // the ValidDataLength wraps. 00980 // 00981 00982 if ( (Header->ValidDataLength.HighPart != NewFileSize.HighPart) && 00983 (Header->PagingIoResource != NULL) ) { 00984 00985 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 00986 Header->ValidDataLength = NewFileSize; 00987 ExReleaseResource( Header->PagingIoResource ); 00988 00989 } else { 00990 00991 Header->ValidDataLength = NewFileSize; 00992 } 00993 } 00994 00995 // 00996 // Set this handle as having modified the file 00997 // 00998 00999 FileObject->Flags |= FO_FILE_MODIFIED; 01000 01001 if (FileSizeChanged) { 01002 01003 *CcGetFileSizePointer(FileObject) = NewFileSize; 01004 01005 FileObject->Flags |= FO_FILE_SIZE_CHANGED; 01006 } 01007 01008 // 01009 // Also update the current file position pointer 01010 // 01011 01012 FileObject->CurrentByteOffset.QuadPart = Offset.QuadPart + Length; 01013 01014 // 01015 // If we did not succeed, then we must restore the original 01016 // FileSize while holding the PagingIoResource exclusive if 01017 // it exists. 01018 // 01019 01020 } else if (FileSizeChanged) { 01021 01022 if ( Header->PagingIoResource != NULL ) { 01023 01024 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 01025 Header->FileSize = OldFileSize; 01026 Header->ValidDataLength = OldValidDataLength; 01027 ExReleaseResource( Header->PagingIoResource ); 01028 01029 } else { 01030 01031 Header->FileSize = OldFileSize; 01032 Header->ValidDataLength = OldValidDataLength; 01033 } 01034 } 01035 01036 } 01037 01038 ExReleaseResource( Header->Resource ); 01039 FsRtlExitFileSystem(); 01040 01041 return Status; 01042 01043 } else { 01044 01045 // 01046 // A zero length transfer was requested. 01047 // 01048 01049 return TRUE; 01050 } 01051 01052 } else { 01053 01054 // 01055 // The volume must be verified or the file is write through. 01056 // 01057 01058 return FALSE; 01059 } 01060 }

NTKERNELAPI BOOLEAN FsRtlCurrentBatchOplock IN POPLOCK  Oplock  ) 
 

Definition at line 1169 of file oplock.c.

References BATCH_OPLOCK, Dbg, DebugTrace, FALSE, FILTER_OPLOCK, FlagOn, NULL, PAGED_CODE, PNONOPAQUE_OPLOCK, and TRUE.

Referenced by UdfCompleteFcbOpen().

01175 : 01176 01177 This routines indicates whether there are current outstanding 01178 batch oplocks. 01179 01180 Arguments: 01181 01182 OpLock - Supplies the oplock being queried 01183 01184 Return Value: 01185 01186 BOOLEAN - TRUE if there are outstanding batch oplocks and FALSE otherwise 01187 01188 --*/ 01189 01190 { 01191 BOOLEAN BatchOplocks = FALSE; 01192 01193 PAGED_CODE(); 01194 01195 DebugTrace(+1, Dbg, "FsRtlCurrentBatchOplock: Oplock -> %08lx\n", *Oplock); 01196 01197 // 01198 // There are not any current oplocks if the variable is null or 01199 // the state is no oplocks held. We check whether there are batch 01200 // oplocks or filter oplocks which have not been broken. 01201 // 01202 01203 if ((*Oplock != NULL) && 01204 FlagOn( ((PNONOPAQUE_OPLOCK) *Oplock)->OplockState, 01205 BATCH_OPLOCK | FILTER_OPLOCK )) { 01206 01207 BatchOplocks = TRUE; 01208 } 01209 01210 DebugTrace(-1, Dbg, "FsRtlCurrentBatchOplock: Exit -> %08lx\n", BatchOplocks); 01211 01212 return BatchOplocks; 01213 }

NTKERNELAPI VOID FsRtlDeleteKeyFromTunnelCache IN TUNNEL Cache,
IN ULONGLONG  DirectoryKey
 

NTKERNELAPI VOID FsRtlDeleteTunnelCache IN TUNNEL Cache  ) 
 

NTKERNELAPI VOID FsRtlDeregisterUncProvider IN HANDLE  Handle  ) 
 

Definition at line 418 of file unc.c.

References ASSERT, Executive, ExFreePool(), FALSE, FsRtlpDRD, FsRtlpRedirs, FsRtlpSetSymbolicLink(), FsRtlpUncSemaphore, Handle, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PAGED_CODE.

00424 : 00425 00426 This routine deregisters a redir as a UNC provider. 00427 00428 Arguments: 00429 00430 Handle - A handle to the Multiple UNC router, returned by the 00431 registration call. 00432 00433 Return Value: 00434 00435 None. 00436 00437 --*/ 00438 00439 { 00440 NTSTATUS status; 00441 00442 PAGED_CODE(); 00443 00444 if( Handle == (HANDLE)-1 || Handle == NULL ) 00445 return; 00446 00447 status = ZwClose( Handle ); 00448 00449 if( !NT_SUCCESS( status ) ) { 00450 return; 00451 } 00452 00453 KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL ); 00454 00455 ASSERT( FsRtlpRedirs > 0 ); 00456 00457 if( Handle == FsRtlpDRD.ReturnedHandle ) { 00458 00459 // 00460 // The first redir in the system is closing. Release the state we saved 00461 // for it, and pass the close on to the MUP if necessary 00462 // 00463 00464 if( FsRtlpDRD.RedirDevName.Buffer != NULL ) { 00465 ExFreePool( FsRtlpDRD.RedirDevName.Buffer ); 00466 FsRtlpDRD.RedirDevName.Buffer = NULL; 00467 } 00468 00469 if( FsRtlpDRD.MupHandle != (HANDLE)-1 ) { 00470 ZwClose( FsRtlpDRD.MupHandle ); 00471 FsRtlpDRD.MupHandle = (HANDLE)-1; 00472 } 00473 00474 FsRtlpDRD.ReturnedHandle = (HANDLE)-1; 00475 00476 } 00477 00478 if( --FsRtlpRedirs == 0 ) { 00479 FsRtlpSetSymbolicLink( (PUNICODE_STRING)NULL ); 00480 } 00481 00482 KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE ); 00483 }

NTKERNELAPI VOID FsRtlDissectDbcs IN ANSI_STRING  InputName,
OUT PANSI_STRING  FirstPart,
OUT PANSI_STRING  RemainingPart
 

Definition at line 542 of file dbcsname.c.

References FsRtlIsLeadDbcsCharacter, NULL, PAGED_CODE, and USHORT.

Referenced by FsRtlIsFatDbcsLegal(), and FsRtlIsHpfsDbcsLegal().

00550 : 00551 00552 This routine takes an input Dbcs string and dissects it into two 00553 substrings. The first output string contains the name that appears at 00554 the beginning of the input string, the second output string contains the 00555 remainder of the input string. 00556 00557 In the input string backslashes are used to separate names. The input 00558 string must not start with a backslash. Both output strings will not 00559 begin with a backslash. 00560 00561 If the input string does not contain any names then both output strings 00562 are empty. If the input string contains only one name then the first 00563 output string contains the name and the second string is empty. 00564 00565 Note that both output strings use the same string buffer memory of the 00566 input string. 00567 00568 Example of its results are: 00569 00570 //. . InputString FirstPart RemainingPart 00571 // 00572 //. . empty empty empty 00573 // 00574 //. . A A empty 00575 // 00576 //. . A\B\C\D\E A B\C\D\E 00577 // 00578 //. . *A? *A? empty 00579 // 00580 //. . \A A empty 00581 // 00582 //. . A[,] A[,] empty 00583 // 00584 //. . A\\B+;\C A \B+;\C 00585 00586 Arguments: 00587 00588 InputName - Supplies the input string being dissected 00589 00590 Is8dot3 - Indicates if the first part of the input name must be 8.3 00591 or can be long file name. 00592 00593 FirstPart - Receives the first name in the input string 00594 00595 RemainingPart - Receives the remaining part of the input string 00596 00597 Return Value: 00598 00599 NONE 00600 00601 --*/ 00602 00603 { 00604 ULONG i = 0; 00605 ULONG PathLength; 00606 ULONG FirstNameStart; 00607 00608 PAGED_CODE(); 00609 00610 // 00611 // Make both output strings empty for now 00612 // 00613 00614 FirstName->Length = 0; 00615 FirstName->MaximumLength = 0; 00616 FirstName->Buffer = NULL; 00617 00618 RemainingName->Length = 0; 00619 RemainingName->MaximumLength = 0; 00620 RemainingName->Buffer = NULL; 00621 00622 PathLength = Path.Length; 00623 00624 // 00625 // Check for an empty input string 00626 // 00627 00628 if (PathLength == 0) { 00629 00630 return; 00631 } 00632 00633 // 00634 // Skip over a starting backslash, and make sure there is more. 00635 // 00636 00637 if ( Path.Buffer[0] == '\\' ) { 00638 00639 i = 1; 00640 } 00641 00642 // 00643 // Now run down the input string until we hit a backslash or the end 00644 // of the string, remembering where we started; 00645 // 00646 00647 for ( FirstNameStart = i; 00648 (i < PathLength) && (Path.Buffer[i] != '\\'); 00649 i += 1 ) { 00650 00651 // 00652 // If this is the first byte of a Dbcs character, skip over the 00653 // next byte as well. 00654 // 00655 00656 if ( FsRtlIsLeadDbcsCharacter( Path.Buffer[i] ) ) { 00657 00658 i += 1; 00659 } 00660 } 00661 00662 // 00663 // At this point all characters up to (but not including) i are 00664 // in the first part. So setup the first name 00665 // 00666 00667 FirstName->Length = (USHORT)(i - FirstNameStart); 00668 FirstName->MaximumLength = FirstName->Length; 00669 FirstName->Buffer = &Path.Buffer[FirstNameStart]; 00670 00671 // 00672 // Now the remaining part needs a string only if the first part didn't 00673 // exhaust the entire input string. We know that if anything is left 00674 // that is must start with a backslash. Note that if there is only 00675 // a trailing backslash, the length will get correctly set to zero. 00676 // 00677 00678 if (i < PathLength) { 00679 00680 RemainingName->Length = (USHORT)(PathLength - (i + 1)); 00681 RemainingName->MaximumLength = RemainingName->Length; 00682 RemainingName->Buffer = &Path.Buffer[i + 1]; 00683 } 00684 00685 // 00686 // And return to our caller 00687 // 00688 00689 return; 00690 }

NTKERNELAPI VOID FsRtlDissectName IN UNICODE_STRING  Path,
OUT PUNICODE_STRING  FirstName,
OUT PUNICODE_STRING  RemainingName
 

Definition at line 93 of file name.c.

References L, NULL, PAGED_CODE, and USHORT.

00101 : 00102 00103 This routine cracks a path. It picks off the first element in the 00104 given path name and provides both it and the remaining part. A path 00105 is a set of file names separated by backslashes. If a name begins 00106 with a backslash, the FirstName is the string immediately following 00107 the backslash. Here are some examples: 00108 00109 Path FirstName RemainingName 00110 ---- --------- ------------- 00111 empty empty empty 00112 00113 \ empty empty 00114 00115 A A empty 00116 00117 \A A empty 00118 00119 A\B\C\D\E A B\C\D\E 00120 00121 *A? *A? empty 00122 00123 00124 Note that both output strings use the same string buffer memory of the 00125 input string, and are not necessarily null terminated. 00126 00127 Also, this routine makes no judgement as to the legality of each 00128 file name componant. This must be done separatly when each file name 00129 is extracted. 00130 00131 Arguments: 00132 00133 Path - The full path name to crack. 00134 00135 FirstName - The first name in the path. Don't allocate a buffer for 00136 this string. 00137 00138 RemainingName - The rest of the path. Don't allocate a buffer for this 00139 string. 00140 00141 Return Value: 00142 00143 None. 00144 00145 --*/ 00146 00147 { 00148 ULONG i = 0; 00149 ULONG PathLength; 00150 ULONG FirstNameStart; 00151 00152 PAGED_CODE(); 00153 00154 // 00155 // Make both output strings empty for now 00156 // 00157 00158 FirstName->Length = 0; 00159 FirstName->MaximumLength = 0; 00160 FirstName->Buffer = NULL; 00161 00162 RemainingName->Length = 0; 00163 RemainingName->MaximumLength = 0; 00164 RemainingName->Buffer = NULL; 00165 00166 PathLength = Path.Length / sizeof(WCHAR); 00167 00168 // 00169 // Check for an empty input string 00170 // 00171 00172 if (PathLength == 0) { 00173 00174 return; 00175 } 00176 00177 // 00178 // Skip over a starting backslash, and make sure there is more. 00179 // 00180 00181 if ( Path.Buffer[0] == L'\\' ) { 00182 00183 i = 1; 00184 } 00185 00186 // 00187 // Now run down the input string until we hit a backslash or the end 00188 // of the string, remembering where we started; 00189 // 00190 00191 for ( FirstNameStart = i; 00192 (i < PathLength) && (Path.Buffer[i] != L'\\'); 00193 i += 1 ) { 00194 00195 NOTHING; 00196 } 00197 00198 // 00199 // At this point all characters up to (but not including) i are 00200 // in the first part. So setup the first name 00201 // 00202 00203 FirstName->Length = (USHORT)((i - FirstNameStart) * sizeof(WCHAR)); 00204 FirstName->MaximumLength = FirstName->Length; 00205 FirstName->Buffer = &Path.Buffer[FirstNameStart]; 00206 00207 // 00208 // Now the remaining part needs a string only if the first part didn't 00209 // exhaust the entire input string. We know that if anything is left 00210 // that is must start with a backslash. Note that if there is only 00211 // a trailing backslash, the length will get correctly set to zero. 00212 // 00213 00214 if (i < PathLength) { 00215 00216 RemainingName->Length = (USHORT)((PathLength - (i + 1)) * sizeof(WCHAR)); 00217 RemainingName->MaximumLength = RemainingName->Length; 00218 RemainingName->Buffer = &Path.Buffer[i + 1]; 00219 } 00220 00221 // 00222 // And return to our caller 00223 // 00224 00225 return; 00226 }

NTKERNELAPI BOOLEAN FsRtlDoesDbcsContainWildCards IN PANSI_STRING  Name  ) 
 

Definition at line 694 of file dbcsname.c.

References FALSE, FsRtlIsAnsiCharacterWild, FsRtlIsLeadDbcsCharacter, Name, PAGED_CODE, and TRUE.

Referenced by FsRtlIsDbcsInExpression(), and FsRtlIsFatDbcsLegal().

00700 : 00701 00702 This routine checks if the input Dbcs name contains any wild card 00703 characters (i.e., *, ?, ANSI_DOS_STAR, or ANSI_DOS_QM). 00704 00705 Arguments: 00706 00707 Name - Supplies the name to examine 00708 00709 Return Value: 00710 00711 BOOLEAN - TRUE if the input name contains any wildcard characters and 00712 FALSE otherwise. 00713 00714 --*/ 00715 00716 { 00717 CLONG i; 00718 00719 PAGED_CODE(); 00720 00721 // 00722 // Check each character in the name to see if it's a wildcard 00723 // character 00724 // 00725 00726 for (i = 0; i < Name->Length; i += 1) { 00727 00728 // 00729 // check for dbcs character because we'll just skip over those 00730 // 00731 00732 if (FsRtlIsLeadDbcsCharacter( Name->Buffer[i] )) { 00733 00734 i += 1; 00735 00736 // 00737 // else check for a wild card character 00738 // 00739 00740 } else if (FsRtlIsAnsiCharacterWild( Name->Buffer[i] )) { 00741 00742 // 00743 // Tell caller that this name contains wild cards 00744 // 00745 00746 return TRUE; 00747 } 00748 } 00749 00750 // 00751 // No wildcard characters were found, so return to our caller 00752 // 00753 00754 return FALSE; 00755 }

NTKERNELAPI BOOLEAN FsRtlDoesNameContainWildCards IN PUNICODE_STRING  Name  ) 
 

Definition at line 229 of file name.c.

References FALSE, FsRtlIsUnicodeCharacterWild, L, Name, PAGED_CODE, PUSHORT, and TRUE.

Referenced by FsRtlIsNameInExpressionPrivate(), UdfInitializeEnumeration(), and UdfNormalizeFileNames().

00235 : 00236 00237 This routine simply scans the input Name string looking for any Nt 00238 wild card characters. 00239 00240 Arguments: 00241 00242 Name - The string to check. 00243 00244 Return Value: 00245 00246 BOOLEAN - TRUE if one or more wild card characters was found. 00247 00248 --*/ 00249 { 00250 PUSHORT p; 00251 00252 PAGED_CODE(); 00253 00254 // 00255 // Check each character in the name to see if it's a wildcard 00256 // character. 00257 // 00258 00259 if( Name->Length ) { 00260 for( p = Name->Buffer + (Name->Length / sizeof(WCHAR)) - 1; 00261 p >= Name->Buffer && *p != L'\\' ; 00262 p-- ) { 00263 00264 // 00265 // check for a wild card character 00266 // 00267 00268 if (FsRtlIsUnicodeCharacterWild( *p )) { 00269 00270 // 00271 // Tell caller that this name contains wild cards 00272 // 00273 00274 return TRUE; 00275 } 00276 } 00277 } 00278 00279 // 00280 // No wildcard characters were found, so return to our caller 00281 // 00282 00283 return FALSE; 00284 }

NTKERNELAPI BOOLEAN FsRtlFastCheckLockForRead IN PFILE_LOCK  FileLock,
IN PLARGE_INTEGER  StartingByte,
IN PLARGE_INTEGER  Length,
IN ULONG  Key,
IN PFILE_OBJECT  FileObject,
IN PVOID  ProcessId
 

Definition at line 2582 of file filelock.c.

References Dbg, DebugTrace, _FILE_LOCK_INFO::EndingByte, _LOCK_QUEUE::ExclusiveLockTree, FsRtlCheckNoExclusiveConflict(), FsRtlReacquireLockQueue, FsRtlReleaseLockQueue, Key, _FILE_LOCK_INFO::Key, _LOCK_INFO::LockQueue, _LOCK_INFO::LowestLockOffset, NULL, PLOCK_INFO, PLOCK_QUEUE, _FILE_LOCK_INFO::ProcessId, _FILE_LOCK_INFO::StartingByte, Status, and TRUE.

Referenced by FsRtlCheckLockForReadAccess().

02593 : 02594 02595 This routine checks to see if the caller has read access to the 02596 indicated range due to file locks. 02597 02598 Arguments: 02599 02600 FileLock - Supplies the File Lock to check 02601 02602 StartingByte - Supplies the first byte (zero based) to check 02603 02604 Length - Supplies the length, in bytes, to check 02605 02606 Key - Supplies the to use in the check 02607 02608 FileObject - Supplies the file object to use in the check 02609 02610 ProcessId - Supplies the Process Id to use in the check 02611 02612 Return Value: 02613 02614 BOOLEAN - TRUE if the indicated user/request has read access to the 02615 entire specified byte range, and FALSE otherwise 02616 02617 --*/ 02618 02619 { 02620 LARGE_INTEGER Starting; 02621 LARGE_INTEGER Ending; 02622 02623 PLOCK_INFO LockInfo; 02624 PLOCK_QUEUE LockQueue; 02625 KIRQL OldIrql; 02626 PFILE_LOCK_INFO LastLock; 02627 BOOLEAN Status; 02628 02629 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 02630 02631 // 02632 // No lock information on this FileLock 02633 // 02634 02635 DebugTrace(0, Dbg, "FsRtlFastCheckLockForRead, No lock info\n", 0); 02636 return TRUE; 02637 } 02638 02639 // 02640 // If there isn't an exclusive lock then we can immediately grant access 02641 // 02642 02643 if (LockInfo->LockQueue.ExclusiveLockTree == NULL) { 02644 DebugTrace(0, Dbg, "FsRtlFastCheckLockForRead, No exlocks present\n", 0); 02645 return TRUE; 02646 } 02647 02648 // 02649 // If length is zero then automatically give grant access 02650 // 02651 02652 if ((ULONGLONG)Length->QuadPart == 0) { 02653 02654 DebugTrace(0, Dbg, "FsRtlFastCheckLockForRead, Length == 0\n", 0); 02655 return TRUE; 02656 } 02657 02658 // 02659 // Get our starting and ending byte position 02660 // 02661 02662 Starting = *StartingByte; 02663 (ULONGLONG)Ending.QuadPart = (ULONGLONG)Starting.QuadPart + (ULONGLONG)Length->QuadPart - 1; 02664 02665 // 02666 // Now check lock queue 02667 // 02668 02669 LockQueue = &LockInfo->LockQueue; 02670 02671 // 02672 // Grab the waiting lock queue spinlock to exclude anyone from messing 02673 // with the queue while we're using it 02674 // 02675 02676 FsRtlReacquireLockQueue(LockInfo, LockQueue, &OldIrql); 02677 02678 // 02679 // If the range ends below the lowest existing lock, this read is OK. 02680 // 02681 02682 if ( ((ULONGLONG)Ending.QuadPart < (ULONGLONG)LockInfo->LowestLockOffset) ) { 02683 DebugTrace(0, Dbg, "FsRtlFastCheckLockForRead (below lowest lock)\n", 0); 02684 02685 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02686 return TRUE; 02687 } 02688 02689 // 02690 // If the caller just locked this range, he can read it. 02691 // 02692 02693 LastLock = (PFILE_LOCK_INFO)FileObject->LastLock; 02694 if ((LastLock != NULL) && 02695 ((ULONGLONG)Starting.QuadPart >= (ULONGLONG)LastLock->StartingByte.QuadPart) && 02696 ((ULONGLONG)Ending.QuadPart <= (ULONGLONG)LastLock->EndingByte.QuadPart) && 02697 (LastLock->Key == Key) && 02698 (LastLock->ProcessId == ProcessId)) { 02699 02700 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02701 return TRUE; 02702 } 02703 02704 // 02705 // Check the exclusive locks for a conflict. It is impossible to have 02706 // a read conflict with any shared lock. 02707 // 02708 02709 Status = FsRtlCheckNoExclusiveConflict(LockQueue, &Starting, &Ending, Key, FileObject, ProcessId); 02710 02711 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02712 02713 return Status; 02714 }

NTKERNELAPI BOOLEAN FsRtlFastCheckLockForWrite IN PFILE_LOCK  FileLock,
IN PLARGE_INTEGER  StartingByte,
IN PLARGE_INTEGER  Length,
IN ULONG  Key,
IN PVOID  FileObject,
IN PVOID  ProcessId
 

Definition at line 2718 of file filelock.c.

References Dbg, DebugTrace, _FILE_LOCK_INFO::EndingByte, _FILE_LOCK_INFO::ExclusiveLock, _LOCK_QUEUE::ExclusiveLockTree, FsRtlCheckNoExclusiveConflict(), FsRtlCheckNoSharedConflict(), FsRtlReacquireLockQueue, FsRtlReleaseLockQueue, Key, _FILE_LOCK_INFO::Key, _LOCK_INFO::LockQueue, _LOCK_INFO::LowestLockOffset, NULL, PLOCK_INFO, PLOCK_QUEUE, _FILE_LOCK_INFO::ProcessId, _LOCK_QUEUE::SharedLockTree, _FILE_LOCK_INFO::StartingByte, Status, and TRUE.

Referenced by FsRtlCheckLockForWriteAccess().

02729 : 02730 02731 This routine checks to see if the caller has write access to the 02732 indicated range due to file locks 02733 02734 Arguments: 02735 02736 FileLock - Supplies the File Lock to check 02737 02738 StartingByte - Supplies the first byte (zero based) to check 02739 02740 Length - Supplies the length, in bytes, to check 02741 02742 Key - Supplies the to use in the check 02743 02744 FileObject - Supplies the file object to use in the check 02745 02746 ProcessId - Supplies the Process Id to use in the check 02747 02748 Return Value: 02749 02750 BOOLEAN - TRUE if the indicated user/request has write access to the 02751 entire specified byte range, and FALSE otherwise 02752 02753 --*/ 02754 02755 { 02756 LARGE_INTEGER Starting; 02757 LARGE_INTEGER Ending; 02758 02759 PLOCK_INFO LockInfo; 02760 PLOCK_QUEUE LockQueue; 02761 KIRQL OldIrql; 02762 PFILE_LOCK_INFO LastLock; 02763 BOOLEAN Status; 02764 02765 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 02766 02767 // 02768 // No lock information on this FileLock 02769 // 02770 02771 DebugTrace(0, Dbg, "FsRtlFastCheckLockForRead, No lock info\n", 0); 02772 return TRUE; 02773 } 02774 02775 // 02776 // If there isn't a lock then we can immediately grant access 02777 // 02778 02779 if (LockInfo->LockQueue.SharedLockTree == NULL && LockInfo->LockQueue.ExclusiveLockTree == NULL) { 02780 02781 DebugTrace(0, Dbg, "FsRtlFastCheckLockForWrite, No locks present\n", 0); 02782 return TRUE; 02783 } 02784 02785 // 02786 // If length is zero then automatically grant access 02787 // 02788 02789 if ((ULONGLONG)Length->QuadPart == 0) { 02790 02791 DebugTrace(0, Dbg, "FsRtlFastCheckLockForWrite, Length == 0\n", 0); 02792 return TRUE; 02793 } 02794 02795 // 02796 // Get our starting and ending byte position 02797 // 02798 02799 Starting = *StartingByte; 02800 (ULONGLONG)Ending.QuadPart = (ULONGLONG)Starting.QuadPart + (ULONGLONG)Length->QuadPart - 1; 02801 02802 // 02803 // Now check lock queue 02804 // 02805 02806 LockQueue = &LockInfo->LockQueue; 02807 02808 // 02809 // Grab the waiting lock queue spinlock to exclude anyone from messing 02810 // with the queue while we're using it 02811 // 02812 02813 FsRtlReacquireLockQueue(LockInfo, LockQueue, &OldIrql); 02814 02815 // 02816 // If the range ends below the lowest existing lock, this write is OK. 02817 // 02818 02819 if ( ((ULONGLONG)Ending.QuadPart < (ULONGLONG)LockInfo->LowestLockOffset) ) { 02820 02821 DebugTrace(0, Dbg, "FsRtlFastCheckLockForWrite (below lowest lock)\n", 0); 02822 02823 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02824 return TRUE; 02825 } 02826 02827 // 02828 // If the caller just locked this range exclusively, he can write it. 02829 // 02830 02831 LastLock = (PFILE_LOCK_INFO)((PFILE_OBJECT)FileObject)->LastLock; 02832 if ((LastLock != NULL) && 02833 ((ULONGLONG)Starting.QuadPart >= (ULONGLONG)LastLock->StartingByte.QuadPart) && 02834 ((ULONGLONG)Ending.QuadPart <= (ULONGLONG)LastLock->EndingByte.QuadPart) && 02835 (LastLock->Key == Key) && 02836 (LastLock->ProcessId == ProcessId) && 02837 LastLock->ExclusiveLock) { 02838 02839 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02840 return TRUE; 02841 } 02842 02843 // 02844 // Check the shared locks for overlap. Any overlap in the shared locks is fatal. 02845 // 02846 02847 Status = FsRtlCheckNoSharedConflict(LockQueue, &Starting, &Ending); 02848 02849 if (Status == TRUE) { 02850 02851 // 02852 // No overlap in the shared locks, so check the exclusive locks for overlap. 02853 // 02854 02855 Status = FsRtlCheckNoExclusiveConflict(LockQueue, &Starting, &Ending, Key, FileObject, ProcessId); 02856 } 02857 02858 FsRtlReleaseLockQueue(LockQueue, OldIrql); 02859 02860 return Status; 02861 }

NTKERNELAPI NTSTATUS FsRtlFastUnlockAll IN PFILE_LOCK  FileLock,
IN PFILE_OBJECT  FileObject,
IN PEPROCESS  ProcessId,
IN PVOID Context  OPTIONAL
 

Definition at line 3770 of file filelock.c.

References FALSE, and FsRtlPrivateFastUnlockAll().

Referenced by FsRtlProcessFileLock(), UdfCommonCleanup(), and UdfFastUnlockAll().

03779 : 03780 03781 This routine performs an Unlock all operation on the current locks 03782 associated with the specified file lock. Only those locks with 03783 a matching file object and process id are freed. 03784 03785 Arguments: 03786 03787 FileLock - Supplies the file lock being freed. 03788 03789 FileObject - Supplies the file object associated with the file lock 03790 03791 ProcessId - Supplies the Process Id assoicated with the locks to be 03792 freed 03793 03794 Context - Supplies an optional context to use when completing waiting 03795 lock irps. 03796 03797 Return Value: 03798 03799 None 03800 03801 --*/ 03802 03803 { 03804 return FsRtlPrivateFastUnlockAll( 03805 FileLock, 03806 FileObject, 03807 ProcessId, 03808 0, FALSE, // No Key 03809 Context ); 03810 }

NTKERNELAPI NTSTATUS FsRtlFastUnlockAllByKey IN PFILE_LOCK  FileLock,
IN PFILE_OBJECT  FileObject,
IN PEPROCESS  ProcessId,
IN ULONG  Key,
IN PVOID Context  OPTIONAL
 

Definition at line 3814 of file filelock.c.

References FsRtlPrivateFastUnlockAll(), Key, and TRUE.

Referenced by FsRtlProcessFileLock(), and UdfFastUnlockAllByKey().

03824 : 03825 03826 This routine performs an Unlock All by Key operation on the current locks 03827 associated with the specified file lock. Only those locks with 03828 a matching file object, process id, and key are freed. The input Irp 03829 is completed by this procedure 03830 03831 Arguments: 03832 03833 FileLock - Supplies the file lock being freed. 03834 03835 FileObject - Supplies the file object associated with the file lock 03836 03837 ProcessId - Supplies the Process Id assoicated with the locks to be 03838 freed 03839 03840 Key - Supplies the Key to use in this operation 03841 03842 Context - Supplies an optional context to use when completing waiting 03843 lock irps. 03844 03845 Return Value: 03846 03847 NTSTATUS - The return status for the operation. 03848 03849 --*/ 03850 03851 { 03852 return FsRtlPrivateFastUnlockAll( 03853 FileLock, 03854 FileObject, 03855 ProcessId, 03856 Key, TRUE, 03857 Context ); 03858 03859 }

NTKERNELAPI NTSTATUS FsRtlFastUnlockSingle IN PFILE_LOCK  FileLock,
IN PFILE_OBJECT  FileObject,
IN LARGE_INTEGER UNALIGNED *  FileOffset,
IN PLARGE_INTEGER  Length,
IN PEPROCESS  ProcessId,
IN ULONG  Key,
IN PVOID Context  OPTIONAL,
IN BOOLEAN  AlreadySynchronized
 

Definition at line 3241 of file filelock.c.

References FALSE, FsRtlFastUnlockSingleExclusive(), FsRtlFastUnlockSingleShared(), Key, NTSTATUS(), NULL, Status, and TRUE.

Referenced by FsRtlProcessFileLock(), and UdfFastUnlockSingle().

03254 : 03255 03256 This routine performs an Unlock Single operation on the current locks 03257 associated with the specified file lock. Only the lock with a matching 03258 file object, process id, key, and range is freed. 03259 03260 Arguments: 03261 03262 FileLock - Supplies the file lock being freed. 03263 03264 FileObject - Supplies the file object holding the locks 03265 03266 FileOffset - Supplies the offset to be unlocked 03267 03268 Length - Supplies the length in bytes to be unlocked 03269 03270 ProcessId - Supplies the process Id to use in this operation 03271 03272 Key - Supplies the key to use in this operation 03273 03274 Context - Optionally supplies context to use when completing Irps 03275 03276 AlreadySynchronized - Indicates that the caller has already synchronized 03277 access to the file lock so the fields in the file lock and 03278 be updated without further locking, but not the queues. 03279 03280 Return Value: 03281 03282 NTSTATUS - The completion status for this operation 03283 03284 --*/ 03285 03286 { 03287 NTSTATUS Status; 03288 03289 // 03290 // XXX AlreadySynchronized is obsolete. It was apparently added for the dead 03291 // XXX SoloLock code. 03292 // 03293 03294 if (FileLock->LockInformation == NULL) { 03295 03296 // 03297 // Fast exit - no locks are applied 03298 // 03299 03300 return STATUS_RANGE_NOT_LOCKED; 03301 } 03302 03303 Status = FsRtlFastUnlockSingleExclusive( FileLock->LockInformation, 03304 FileObject, 03305 FileOffset, 03306 Length, 03307 ProcessId, 03308 Key, 03309 Context, 03310 FALSE, 03311 TRUE ); 03312 03313 if (Status == STATUS_SUCCESS) { 03314 03315 // 03316 // Found and unlocked in the exclusive tree, so we're done 03317 // 03318 03319 return Status; 03320 } 03321 03322 Status = FsRtlFastUnlockSingleShared( FileLock->LockInformation, 03323 FileObject, 03324 FileOffset, 03325 Length, 03326 ProcessId, 03327 Key, 03328 Context, 03329 FALSE, 03330 TRUE ); 03331 03332 return Status; 03333 }

NTKERNELAPI BOOLEAN FsRtlFindInTunnelCache IN TUNNEL Cache,
IN ULONGLONG  DirectoryKey,
IN UNICODE_STRING *  Name,
OUT UNICODE_STRING *  ShortName,
OUT UNICODE_STRING *  LongName,
IN OUT ULONG *  DataLength,
OUT VOID *  Data
 

VOID FsRtlFreeFileLock IN PFILE_LOCK  FileLock  ) 
 

Definition at line 1162 of file filelock.c.

References ExFreeToPagedLookasideList(), FsRtlFileLockLookasideList, and FsRtlUninitializeFileLock().

Referenced by UdfDeleteFcb().

01165 { 01166 FsRtlUninitializeFileLock( FileLock ); 01167 01168 ExFreeToPagedLookasideList( &FsRtlFileLockLookasideList, FileLock ); 01169 }

NTSTATUS FsRtlGetFileSize IN PFILE_OBJECT  FileObject,
IN OUT PLARGE_INTEGER  FileSize
 

Definition at line 2691 of file fastio.c.

References _IRP::AssociatedIrp, _IO_STACK_LOCATION::DeviceObject, _DEVICE_OBJECT::DriverObject, Event(), Executive, FALSE, _DRIVER_OBJECT::FastIoDispatch, _FAST_IO_DISPATCH::FastIoQueryStandardInfo, _IO_STACK_LOCATION::FileObject, _IRP::Flags, IoAllocateIrp(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), Irp, IRP_MJ_QUERY_INFORMATION, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, Status, _IRP::Tail, TRUE, _IRP::UserEvent, and _IRP::UserIosb.

Referenced by MiCreateDataFileMap(), MiCreateImageFileMap(), MmCreateSection(), and MmExtendSection().

02698 : 02699 02700 This routine is used to call the File System to get the FileSize 02701 for a file. 02702 02703 It does this without acquiring the file object lock on synchronous file 02704 objects. This routine is therefore safe to call if you already own 02705 file system resources, while IoQueryFileInformation could (and does) 02706 lead to deadlocks. 02707 02708 Arguments: 02709 02710 FileObject - The file to query 02711 FileSize - Receives the file size. 02712 02713 Return Value: 02714 02715 NTSTATUS - The final I/O status of the operation. If the FileObject 02716 refers to a directory, STATUS_FILE_IS_A_DIRECTORY is returned. 02717 02718 --*/ 02719 { 02720 IO_STATUS_BLOCK IoStatus; 02721 PDEVICE_OBJECT DeviceObject; 02722 PFAST_IO_DISPATCH FastIoDispatch; 02723 FILE_STANDARD_INFORMATION FileInformation; 02724 02725 PAGED_CODE(); 02726 02727 // 02728 // Get the address of the target device object. 02729 // 02730 02731 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 02732 02733 // 02734 // Try the fast query call if it exists. 02735 // 02736 02737 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 02738 02739 if (FastIoDispatch && 02740 FastIoDispatch->FastIoQueryStandardInfo && 02741 FastIoDispatch->FastIoQueryStandardInfo( FileObject, 02742 TRUE, 02743 &FileInformation, 02744 &IoStatus, 02745 DeviceObject )) { 02746 // 02747 // Cool, it worked. 02748 // 02749 02750 } else { 02751 02752 // 02753 // Life's tough, take the long path. 02754 // 02755 02756 PIRP Irp; 02757 KEVENT Event; 02758 NTSTATUS Status; 02759 PIO_STACK_LOCATION IrpSp; 02760 02761 // 02762 // Initialize the event. 02763 // 02764 02765 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 02766 02767 // 02768 // Allocate an I/O Request Packet (IRP) for this in-page operation. 02769 // 02770 02771 Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); 02772 if (Irp == NULL) { 02773 02774 return STATUS_INSUFFICIENT_RESOURCES; 02775 } 02776 02777 // 02778 // Get a pointer to the first stack location in the packet. This location 02779 // will be used to pass the function codes and parameters to the first 02780 // driver. 02781 // 02782 02783 IrpSp = IoGetNextIrpStackLocation( Irp ); 02784 02785 // 02786 // Fill in the IRP according to this request, setting the flags to 02787 // just cause IO to set the event and deallocate the Irp. 02788 // 02789 02790 Irp->Flags = IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO; 02791 Irp->RequestorMode = KernelMode; 02792 Irp->UserIosb = &IoStatus; 02793 Irp->UserEvent = &Event; 02794 Irp->Tail.Overlay.OriginalFileObject = FileObject; 02795 Irp->Tail.Overlay.Thread = PsGetCurrentThread(); 02796 Irp->AssociatedIrp.SystemBuffer = &FileInformation; 02797 02798 // 02799 // Fill in the normal query parameters. 02800 // 02801 02802 IrpSp->MajorFunction = IRP_MJ_QUERY_INFORMATION; 02803 IrpSp->FileObject = FileObject; 02804 IrpSp->DeviceObject = DeviceObject; 02805 IrpSp->Parameters.SetFile.Length = sizeof(FILE_STANDARD_INFORMATION); 02806 IrpSp->Parameters.SetFile.FileInformationClass = FileStandardInformation; 02807 02808 // 02809 // Queue the packet to the appropriate driver based. This routine 02810 // should not raise. 02811 // 02812 02813 Status = IoCallDriver( DeviceObject, Irp ); 02814 02815 // 02816 // If pending is returned (which is a successful status), 02817 // we must wait for the request to complete. 02818 // 02819 02820 if (Status == STATUS_PENDING) { 02821 KeWaitForSingleObject( &Event, 02822 Executive, 02823 KernelMode, 02824 FALSE, 02825 (PLARGE_INTEGER)NULL); 02826 } 02827 02828 // 02829 // If we got an error back in Status, then the Iosb 02830 // was not written, so we will just copy the status 02831 // there, then test the final status after that. 02832 // 02833 02834 if (!NT_SUCCESS(Status)) { 02835 IoStatus.Status = Status; 02836 } 02837 } 02838 02839 // 02840 // If the call worked, check to make sure it wasn't a directory and 02841 // if not, fill in the FileSize parameter. 02842 // 02843 02844 if (NT_SUCCESS(IoStatus.Status)) { 02845 02846 if (FileInformation.Directory) { 02847 02848 // 02849 // Can't get file size for a directory. Return error. 02850 // 02851 02852 IoStatus.Status = STATUS_FILE_IS_A_DIRECTORY; 02853 02854 } else { 02855 02856 *FileSize = FileInformation.EndOfFile; 02857 } 02858 } 02859 02860 return IoStatus.Status; 02861 }

NTKERNELAPI PFILE_LOCK_INFO FsRtlGetNextFileLock IN PFILE_LOCK  FileLock,
IN BOOLEAN  Restart
 

Definition at line 1951 of file filelock.c.

References Dbg, DebugTrace, _FILE_LOCK_INFO::EndingByte, _FILE_LOCK_INFO::ExclusiveLock, _LOCK_QUEUE::ExclusiveLockTree, FALSE, _FILE_LOCK_INFO::FileObject, FsRtlAcquireLockQueue, FsRtlFindFirstOverlappingExclusiveNode(), FsRtlFindFirstOverlappingSharedNode(), FsRtlReleaseLockQueue, GreaterThan, _FILE_LOCK_INFO::Key, _FILE_LOCK_INFO::Length, _SH_LOCK::LockInfo, _EX_LOCK::LockInfo, _LOCK_INFO::LockQueue, _LOCKTREE_NODE::Locks, NULL, PEX_LOCK, PLOCK_INFO, PLOCKTREE_NODE, _FILE_LOCK_INFO::ProcessId, PSH_LOCK, RtlRealSuccessor(), _LOCK_QUEUE::SharedLockTree, _FILE_LOCK_INFO::StartingByte, and TRUE.

01958 : 01959 01960 This routine enumerates the individual file locks denoted by the input file lock 01961 variable. It returns a pointer to the file lock information stored for each lock. 01962 The caller is responsible for synchronizing call to this procedure and for not 01963 altering any of the data returned by this procedure. If the caller does not 01964 synchronize the enumeration will not be reliably complete. 01965 01966 The way a programmer will use this procedure to enumerate all of the locks 01967 is as follows: 01968 01969 for (p = FsRtlGetNextFileLock( FileLock, TRUE ); 01970 p != NULL; 01971 p = FsRtlGetNextFileLock( FileLock, FALSE )) { 01972 01973 // Process the lock information referenced by p 01974 } 01975 01976 Order is *not* guaranteed. 01977 01978 Arguments: 01979 01980 FileLock - Supplies the File Lock to enumerate. The current 01981 enumeration state is stored in the file lock variable so if multiple 01982 threads are enumerating the lock at the same time the results will 01983 be unpredictable. 01984 01985 Restart - Indicates if the enumeration is to start at the beginning of the 01986 file lock tree or if we are continuing from a previous call. 01987 01988 Return Value: 01989 01990 PFILE_LOCK_INFO - Either it returns a pointer to the next file lock 01991 record for the input file lock or it returns NULL if there 01992 are not more locks. 01993 01994 --*/ 01995 01996 { 01997 FILE_LOCK_INFO FileLockInfo; 01998 PVOID ContinuationPointer; 01999 PLOCK_INFO LockInfo; 02000 PLOCKTREE_NODE Node; 02001 PSINGLE_LIST_ENTRY Link; 02002 PRTL_SPLAY_LINKS SplayLinks, LastSplayLinks; 02003 PSH_LOCK ShLock; 02004 PEX_LOCK ExLock; 02005 BOOLEAN FoundReturnable, GreaterThan; 02006 KIRQL OldIrql; 02007 02008 DebugTrace(+1, Dbg, "FsRtlGetNextFileLock, FileLock = %08lx\n", FileLock); 02009 02010 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 02011 // 02012 // No lock information on this FileLock 02013 // 02014 02015 return NULL; 02016 } 02017 02018 FoundReturnable = FALSE; 02019 02020 // 02021 // Before getting the spinlock, copy pagable info onto stack 02022 // 02023 02024 FileLockInfo = FileLock->LastReturnedLockInfo; 02025 ContinuationPointer = FileLock->LastReturnedLock; 02026 02027 FsRtlAcquireLockQueue (&LockInfo->LockQueue, &OldIrql); 02028 02029 if (!Restart) { 02030 // 02031 // Given the last returned lock, find its current successor in the tree. 02032 // Previous implementations would reset the enumeration if the last returned 02033 // lock had been removed from the tree but I think we can be better in that 02034 // case since every other structure modifying event (add new locks, delete 02035 // other locks) would *not* have caused the reset. Possible minor performance 02036 // enhancement. 02037 // 02038 02039 // 02040 // Find the node which could contain the last returned lock. We enumerate the 02041 // exclusive lock tree, then the shared lock tree. Find the one we're enumerating. 02042 // 02043 02044 if (FileLockInfo.ExclusiveLock) { 02045 02046 // 02047 // Continue enumeration in the exclusive lock tree 02048 // 02049 02050 ExLock = NULL; 02051 02052 SplayLinks = FsRtlFindFirstOverlappingExclusiveNode( LockInfo->LockQueue.ExclusiveLockTree, 02053 &FileLockInfo.StartingByte, 02054 &FileLockInfo.EndingByte, 02055 &LastSplayLinks, 02056 &GreaterThan ); 02057 02058 if (SplayLinks == NULL) { 02059 02060 // 02061 // No overlapping nodes were found, try to find successor 02062 // 02063 02064 if (GreaterThan) { 02065 02066 // 02067 // Last node looked at was greater than the lock so it is 02068 // the place to pick up the enumeration 02069 // 02070 02071 SplayLinks = LastSplayLinks; 02072 02073 } else { 02074 02075 // 02076 // Last node looked at was less than the lock so grab its successor 02077 // 02078 02079 if (LastSplayLinks) { 02080 02081 SplayLinks = RtlRealSuccessor(LastSplayLinks); 02082 } 02083 } 02084 02085 } else { 02086 02087 // 02088 // Found an overlapping lock, see if it is the last returned 02089 // 02090 02091 for (; 02092 SplayLinks; 02093 SplayLinks = RtlRealSuccessor(SplayLinks)) { 02094 02095 ExLock = CONTAINING_RECORD( SplayLinks, EX_LOCK, Links ); 02096 02097 if (ContinuationPointer == ExLock && 02098 (ULONGLONG)FileLockInfo.StartingByte.QuadPart == (ULONGLONG)ExLock->LockInfo.StartingByte.QuadPart && 02099 (ULONGLONG)FileLockInfo.Length.QuadPart == (ULONGLONG)ExLock->LockInfo.Length.QuadPart && 02100 FileLockInfo.Key == ExLock->LockInfo.Key && 02101 FileLockInfo.FileObject == ExLock->LockInfo.FileObject && 02102 FileLockInfo.ProcessId == ExLock->LockInfo.ProcessId) { 02103 02104 // 02105 // Found last returned, dig up its successor 02106 // 02107 02108 SplayLinks = RtlRealSuccessor(SplayLinks); 02109 02110 // 02111 // Got the node cold, so we're done 02112 // 02113 02114 break; 02115 } 02116 02117 // 02118 // This lock overlapped and was not the last returned. In fact, since this lock would 02119 // have conflicted with the last returned we know it could not have been returned 02120 // before, so this should be returned to the caller. 02121 // 02122 // However, if it is a zero length lock we are looking for and a zero length lock we hit, 02123 // we are at the beginning of a run we need to inspect. If we cannot find the last lock 02124 // we returned, resume the enumeration at the beginning of the run. 02125 // 02126 02127 if (ExLock->LockInfo.Length.QuadPart != 0 || FileLockInfo.Length.QuadPart != 0) { 02128 02129 break; 02130 } 02131 02132 // 02133 // Keep wandering down the run 02134 // 02135 } 02136 } 02137 02138 // 02139 // Were we able to find a lock to return? 02140 // 02141 02142 if (SplayLinks == NULL) { 02143 02144 // 02145 // There aren't any more exclusive locks, fall over to the shared tree 02146 // 02147 02148 SplayLinks = LockInfo->LockQueue.SharedLockTree; 02149 02150 if (SplayLinks) { 02151 02152 while (RtlLeftChild(SplayLinks)) { 02153 02154 SplayLinks = RtlLeftChild(SplayLinks); 02155 } 02156 02157 Node = CONTAINING_RECORD(SplayLinks, LOCKTREE_NODE, Links); 02158 ShLock = CONTAINING_RECORD(Node->Locks.Next, SH_LOCK, Link); 02159 02160 FileLockInfo = ShLock->LockInfo; 02161 ContinuationPointer = ShLock; 02162 FoundReturnable = TRUE; 02163 } 02164 02165 } else { 02166 02167 // 02168 // This is the lock to return 02169 // 02170 02171 ExLock = CONTAINING_RECORD( SplayLinks, EX_LOCK, Links ); 02172 02173 FileLockInfo = ExLock->LockInfo; 02174 ContinuationPointer = ExLock; 02175 FoundReturnable = TRUE; 02176 } 02177 02178 } else { 02179 02180 // 02181 // Continue enumeration in the shared lock tree 02182 // 02183 02184 Node = NULL; 02185 02186 SplayLinks = FsRtlFindFirstOverlappingSharedNode( LockInfo->LockQueue.SharedLockTree, 02187 &FileLockInfo.StartingByte, 02188 &FileLockInfo.EndingByte, 02189 &LastSplayLinks, 02190 &GreaterThan ); 02191 02192 if (SplayLinks == NULL) { 02193 02194 // 02195 // No overlapping nodes were found 02196 // 02197 02198 if (GreaterThan) { 02199 02200 // 02201 // Last node looked at was greater than the lock so it is 02202 // the place to pick up the enumeration 02203 // 02204 02205 if (LastSplayLinks) { 02206 02207 SplayLinks = LastSplayLinks; 02208 Node = CONTAINING_RECORD( LastSplayLinks, LOCKTREE_NODE, Links ); 02209 } 02210 02211 } else { 02212 02213 // 02214 // Last node looked at was less than the lock so grab its successor 02215 // 02216 02217 if (LastSplayLinks) { 02218 02219 SplayLinks = RtlRealSuccessor(LastSplayLinks); 02220 02221 if (SplayLinks) { 02222 02223 Node = CONTAINING_RECORD( SplayLinks, LOCKTREE_NODE, Links ); 02224 } 02225 } 02226 } 02227 02228 } else { 02229 02230 // 02231 // Grab the node we found 02232 // 02233 02234 Node = CONTAINING_RECORD( SplayLinks, LOCKTREE_NODE, Links ); 02235 } 02236 02237 // 02238 // If we have a node to look at, it may still not contain the the last returned lock 02239 // if this isn't synchronized. 02240 // 02241 02242 if (Node != NULL) { 02243 02244 // 02245 // Walk down the locks at this node looking for the last returned lock 02246 // 02247 02248 for (Link = Node->Locks.Next; 02249 Link; 02250 Link = Link->Next) { 02251 02252 // 02253 // Get a pointer to the current lock record 02254 // 02255 02256 ShLock = CONTAINING_RECORD( Link, SH_LOCK, Link ); 02257 02258 // 02259 // See if it's a match 02260 // 02261 02262 if (ContinuationPointer == ShLock && 02263 (ULONGLONG)FileLockInfo.StartingByte.QuadPart == (ULONGLONG)ShLock->LockInfo.StartingByte.QuadPart && 02264 (ULONGLONG)FileLockInfo.Length.QuadPart == (ULONGLONG)ShLock->LockInfo.Length.QuadPart && 02265 FileLockInfo.Key == ShLock->LockInfo.Key && 02266 FileLockInfo.FileObject == ShLock->LockInfo.FileObject && 02267 FileLockInfo.ProcessId == ShLock->LockInfo.ProcessId) { 02268 02269 Link = Link->Next; 02270 break; 02271 } 02272 02273 // 02274 // See if we passed by its slot 02275 // 02276 02277 if ((ULONGLONG)FileLockInfo.StartingByte.QuadPart < (ULONGLONG)ShLock->LockInfo.StartingByte.QuadPart) { 02278 02279 break; 02280 } 02281 } 02282 02283 if (Link == NULL) { 02284 02285 // 02286 // This node doesn't contain the successor, so move 02287 // up to the successor node in the tree and return the 02288 // first lock. If we're actually at the end of the tree 02289 // we just fall off the end correctly. 02290 // 02291 02292 SplayLinks = RtlRealSuccessor(SplayLinks); 02293 02294 if (SplayLinks) { 02295 02296 Node = CONTAINING_RECORD( SplayLinks, LOCKTREE_NODE, Links ); 02297 02298 Link = Node->Locks.Next; 02299 } 02300 } 02301 02302 if (Link) { 02303 02304 // 02305 // Found a Lock to return, copy it to the stack 02306 // 02307 02308 ShLock = CONTAINING_RECORD( Link, SH_LOCK, Link ); 02309 02310 FileLockInfo = ShLock->LockInfo; 02311 ContinuationPointer = ShLock; 02312 FoundReturnable = TRUE; 02313 } 02314 02315 } 02316 } 02317 02318 } else { 02319 02320 // 02321 // Restarting the enumeration. Find leftmost node in the exclusive tree and hand back 02322 // the first lock, falling over to the shared if no exlcusive locks are applied 02323 // 02324 02325 if (LockInfo->LockQueue.ExclusiveLockTree) { 02326 02327 SplayLinks = LockInfo->LockQueue.ExclusiveLockTree; 02328 02329 while (RtlLeftChild(SplayLinks) != NULL) { 02330 02331 SplayLinks = RtlLeftChild(SplayLinks); 02332 } 02333 02334 ExLock = CONTAINING_RECORD( SplayLinks, EX_LOCK, Links ); 02335 02336 FileLockInfo = ExLock->LockInfo; 02337 ContinuationPointer = ExLock; 02338 FoundReturnable = TRUE; 02339 02340 } else { 02341 02342 if (LockInfo->LockQueue.SharedLockTree) { 02343 02344 SplayLinks = LockInfo->LockQueue.SharedLockTree; 02345 02346 while (RtlLeftChild(SplayLinks) != NULL) { 02347 02348 SplayLinks = RtlLeftChild(SplayLinks); 02349 } 02350 02351 Node = CONTAINING_RECORD( SplayLinks, LOCKTREE_NODE, Links ); 02352 ShLock = CONTAINING_RECORD( Node->Locks.Next, SH_LOCK, Link ); 02353 02354 FileLockInfo = ShLock->LockInfo; 02355 ContinuationPointer = ShLock; 02356 FoundReturnable = TRUE; 02357 } 02358 } 02359 } 02360 02361 // 02362 // Release all the lock queues 02363 // 02364 02365 FsRtlReleaseLockQueue (&LockInfo->LockQueue, OldIrql); 02366 02367 if (!FoundReturnable) { 02368 02369 // 02370 // No returnable lock was found, end of list 02371 // 02372 02373 return NULL; 02374 } 02375 02376 // 02377 // Update current enum location information 02378 // 02379 02380 FileLock->LastReturnedLockInfo = FileLockInfo; 02381 FileLock->LastReturnedLock = ContinuationPointer; 02382 02383 // 02384 // Return lock record to caller 02385 // 02386 02387 return &FileLock->LastReturnedLockInfo; 02388 }

NTKERNELAPI BOOLEAN FsRtlGetNextLargeMcbEntry IN PLARGE_MCB  Mcb,
IN ULONG  RunIndex,
OUT PLONGLONG  Vbn,
OUT PLONGLONG  Lbn,
OUT PLONGLONG  SectorCount
 

Definition at line 1970 of file largemcb.c.

References Dbg, DebugTrace, FALSE, _NONOPAQUE_MCB::FastMutex, PAGED_CODE, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, SectorsWithinRun, StartingLbn, StartingVbn, TRUE, try_return, and UNUSED_LBN.

Referenced by FsRtlGetNextMcbEntry().

01980 : 01981 01982 This routine returns to its caller the Vbn, Lbn, and SectorCount for 01983 distinct runs mapped by an Mcb. Holes are counted as runs. For example, 01984 to construct to print out all of the runs in a a file is: 01985 01986 //. . for (i = 0; FsRtlGetNextLargeMcbEntry(Mcb,i,&Vbn,&Lbn,&Count); i++) { 01987 // 01988 //. . // print out vbn, lbn, and count 01989 // 01990 //. . } 01991 01992 Arguments: 01993 01994 OpaqueMcb - Supplies the Mcb being examined. 01995 01996 RunIndex - Supplies the index of the run (zero based) to return to the 01997 caller. 01998 01999 Vbn - Receives the starting Vbn of the returned run, or zero if the 02000 run does not exist. 02001 02002 Lbn - Recieves the starting Lbn of the returned run, or zero if the 02003 run does not exist. 02004 02005 SectorCount - Receives the number of sectors within the returned run, 02006 or zero if the run does not exist. 02007 02008 Return Value: 02009 02010 BOOLEAN - TRUE if the specified run (i.e., RunIndex) exists in the Mcb, 02011 and FALSE otherwise. If FALSE is returned then the Vbn, Lbn, and 02012 SectorCount parameters receive zero. 02013 02014 --*/ 02015 02016 { 02017 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 02018 02019 BOOLEAN Result; 02020 02021 PAGED_CODE(); 02022 02023 DebugTrace(+1, Dbg, "FsRtlGetNextLargeMcbEntry, Mcb = %08lx\n", Mcb ); 02024 DebugTrace( 0, Dbg, " RunIndex = %08lx\n", RunIndex ); 02025 02026 ExAcquireFastMutex( Mcb->FastMutex ); 02027 02028 try { 02029 02030 // 02031 // Make sure the run index is within range 02032 // 02033 02034 if (RunIndex >= Mcb->PairCount) { 02035 02036 try_return (Result = FALSE); 02037 } 02038 02039 // 02040 // Set the return variables 02041 // 02042 02043 *((PULONG)LargeVbn) = StartingVbn(Mcb,RunIndex); 02044 *((PULONG)LargeLbn) = StartingLbn(Mcb,RunIndex); 02045 *((PULONG)LargeSectorCount) = SectorsWithinRun(Mcb,RunIndex); 02046 02047 Result = TRUE; 02048 02049 try_exit: NOTHING; 02050 } finally { 02051 02052 ExReleaseFastMutex( Mcb->FastMutex ); 02053 02054 DebugTrace(-1, Dbg, "FsRtlGetNextLargeMcbEntry -> %08lx\n", Result ); 02055 } 02056 02057 ((PLARGE_INTEGER)LargeVbn)->HighPart = (*((PULONG)LargeVbn) == UNUSED_LBN ? UNUSED_LBN : 0); 02058 ((PLARGE_INTEGER)LargeLbn)->HighPart = (*((PULONG)LargeLbn) == UNUSED_LBN ? UNUSED_LBN : 0); 02059 ((PLARGE_INTEGER)LargeSectorCount)->HighPart = 0; 02060 02061 return Result; 02062 }

NTKERNELAPI BOOLEAN FsRtlGetNextMcbEntry IN PMCB  Mcb,
IN ULONG  RunIndex,
OUT PVBN  Vbn,
OUT PLBN  Lbn,
OUT PULONG  SectorCount
 

Definition at line 490 of file largemcb.c.

References FsRtlGetNextLargeMcbEntry(), and PAGED_CODE.

00498 { 00499 BOOLEAN Results; 00500 LONGLONG LiVbn; 00501 LONGLONG LiLbn; 00502 LONGLONG LiSectorCount; 00503 00504 PAGED_CODE(); 00505 00506 Results = FsRtlGetNextLargeMcbEntry( (PLARGE_MCB)Mcb, 00507 RunIndex, 00508 &LiVbn, 00509 &LiLbn, 00510 &LiSectorCount ); 00511 00512 *Vbn = ((ULONG)LiVbn); 00513 *Lbn = (((ULONG)LiLbn) == -1 ? 0 : ((ULONG)LiLbn)); 00514 *SectorCount = ((ULONG)LiSectorCount); 00515 00516 return Results; 00517 }

NTKERNELAPI VOID FsRtlInitializeFileLock IN PFILE_LOCK  FileLock,
IN PCOMPLETE_LOCK_IRP_ROUTINE CompleteLockIrpRoutine  OPTIONAL,
IN PUNLOCK_ROUTINE UnlockRoutine  OPTIONAL
 

Definition at line 829 of file filelock.c.

References Dbg, DebugTrace, FALSE, NULL, and PUNLOCK_ROUTINE.

Referenced by FsRtlAllocateFileLock().

00837 : 00838 00839 This routine initializes a new FILE_LOCK structure. The caller must 00840 supply the memory for the structure. This call must precede all other 00841 calls that utilize the FILE_LOCK variable. 00842 00843 Arguments: 00844 00845 FileLock - Supplies a pointer to the FILE_LOCK structure to 00846 initialize. 00847 00848 CompleteLockIrpRoutine - Optionally supplies an alternate routine to 00849 call for completing IRPs. FsRtlProcessFileLock by default will 00850 call IoCompleteRequest to finish up an IRP; however if the caller 00851 want to process the completion itself then it needs to specify 00852 a completion routine here. This routine will then be called in 00853 place of IoCompleteRequest. 00854 00855 UnlockRoutine - Optionally supplies a routine to call when removing 00856 a lock. 00857 00858 Return Value: 00859 00860 None. 00861 00862 --*/ 00863 00864 { 00865 DebugTrace(+1, Dbg, "FsRtlInitializeFileLock, FileLock = %08lx\n", FileLock); 00866 00867 // 00868 // Clear non-paged pool pointer 00869 // 00870 00871 FileLock->LockInformation = NULL; 00872 FileLock->CompleteLockIrpRoutine = CompleteLockIrpRoutine; 00873 FileLock->UnlockRoutine = UnlockRoutine; 00874 00875 FileLock->FastIoIsQuestionable = FALSE; 00876 00877 // 00878 // and return to our caller 00879 // 00880 00881 DebugTrace(-1, Dbg, "FsRtlInitializeFileLock -> VOID\n", 0 ); 00882 00883 return; 00884 }

NTKERNELAPI VOID FsRtlInitializeLargeMcb IN PLARGE_MCB  Mcb,
IN POOL_TYPE  PoolType
 

Definition at line 572 of file largemcb.c.

References Dbg, DebugTrace, ExInitializeFastMutex, _NONOPAQUE_MCB::FastMutex, FsRtlAllocateFastMutex, FsRtlAllocateFirstMapping, FsRtlFreeFastMutex, FsRtlpAllocatePool, INITIAL_MAXIMUM_PAIR_COUNT, _NONOPAQUE_MCB::Mapping, _NONOPAQUE_MCB::MaximumPairCount, NULL, PagedPool, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, and _NONOPAQUE_MCB::PoolType.

Referenced by FsRtlInitializeMcb(), UdfInitializeFcbMcb(), and UdfLoadSparingTables().

00579 : 00580 00581 This routine initializes a new Mcb structure. The caller must 00582 supply the memory for the Mcb structure. This call must precede all 00583 other calls that set/query the Mcb structure. 00584 00585 If pool is not available this routine will raise a status value 00586 indicating insufficient resources. 00587 00588 Arguments: 00589 00590 OpaqueMcb - Supplies a pointer to the Mcb structure to initialize. 00591 00592 PoolType - Supplies the pool type to use when allocating additional 00593 internal Mcb memory. 00594 00595 Return Value: 00596 00597 None. 00598 00599 --*/ 00600 00601 { 00602 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 00603 00604 DebugTrace(+1, Dbg, "FsRtlInitializeLargeMcb, Mcb = %08lx\n", Mcb ); 00605 00606 // 00607 // Preset the following fields to null so we know to deallocate them 00608 // during an abnormal termination 00609 // 00610 00611 Mcb->FastMutex = NULL; 00612 Mcb->Mapping = NULL; 00613 00614 try { 00615 00616 // 00617 // Initialize the fields in the Mcb 00618 // 00619 00620 Mcb->FastMutex = FsRtlAllocateFastMutex(); 00621 00622 ExInitializeFastMutex( Mcb->FastMutex ); 00623 00624 Mcb->PairCount = 0; 00625 Mcb->PoolType = PoolType; 00626 00627 // 00628 // Allocate a new buffer an initial size is one that will hold 00629 // 16 runs 00630 // 00631 00632 if (PoolType == PagedPool) { 00633 00634 Mcb->Mapping = FsRtlAllocateFirstMapping(); 00635 00636 } else { 00637 00638 Mcb->Mapping = FsRtlpAllocatePool( Mcb->PoolType, sizeof(MAPPING) * INITIAL_MAXIMUM_PAIR_COUNT ); 00639 } 00640 00641 //**** RtlZeroMemory( Mcb->Mapping, sizeof(MAPPING) * INITIAL_MAXIMUM_PAIR_COUNT ); 00642 00643 Mcb->MaximumPairCount = INITIAL_MAXIMUM_PAIR_COUNT; 00644 00645 } finally { 00646 00647 // 00648 // If this is an abnormal termination then we need to deallocate 00649 // the FastMutex and/or mapping (but once the mapping is allocated, 00650 // we can't raise). 00651 // 00652 00653 if (AbnormalTermination()) { 00654 00655 if (Mcb->FastMutex != NULL) { FsRtlFreeFastMutex( Mcb->FastMutex ); } 00656 } 00657 00658 DebugTrace(-1, Dbg, "FsRtlInitializeLargeMcb -> VOID\n", 0 ); 00659 } 00660 00661 // 00662 // And return to our caller 00663 // 00664 00665 return; 00666 }

NTKERNELAPI VOID FsRtlInitializeMcb IN PMCB  Mcb,
IN POOL_TYPE  PoolType
 

Definition at line 334 of file largemcb.c.

References FsRtlInitializeLargeMcb(), and PAGED_CODE.

Referenced by UdfInitializeVmcb().

00338 { 00339 PAGED_CODE(); 00340 00341 FsRtlInitializeLargeMcb( (PLARGE_MCB)Mcb, 00342 PoolType ); 00343 00344 return; 00345 }

NTKERNELAPI VOID FsRtlInitializeOplock IN OUT POPLOCK  Oplock  ) 
 

Definition at line 373 of file oplock.c.

References Dbg, DebugTrace, and PAGED_CODE.

00379 : 00380 00381 This routine initializes a new OPLOCK structure. This call must 00382 precede any other call to this entry point with this OPLOCK 00383 structure. In addition, this routine will have exclusive access 00384 to the Oplock structure. 00385 00386 Arguments: 00387 00388 Oplock - Supplies the address of an opaque OPLOCK structure. 00389 00390 Return Value: 00391 00392 None. 00393 00394 --*/ 00395 00396 { 00397 UNREFERENCED_PARAMETER( Oplock ); 00398 00399 PAGED_CODE(); 00400 00401 DebugTrace(+1, Dbg, "FsRtlInitializeOplock: Oplock -> %08lx\n", *Oplock ); 00402 00403 // 00404 // No action is taken at this time. 00405 // 00406 00407 DebugTrace(-1, Dbg, "FsRtlInitializeOplock: Exit\n", 0); 00408 return; 00409 }

NTKERNELAPI VOID FsRtlInitializeTunnelCache IN TUNNEL Cache  ) 
 

NTKERNELAPI BOOLEAN FsRtlInitSystem  ) 
 

Definition at line 215 of file fsrtlpc.c.

References COMPATIBILITY_MODE_VALUE_NAME, ExInitializeResource, FALSE, FSRTL_NUMBER_OF_RESOURCES, FsRtlAllocatePool, FsRtlGetCompatibilityModeValue(), FsRtlInitializeFileLocks(), FsRtlInitializeLargeMcbs(), FsRtlInitializeTunnels(), FsRtlInitializeWorkerThread(), FsRtlPagingIoResources, FsRtlpUncSemaphore, FsRtlSafeExtensions, KeInitializeSemaphore(), NonPagedPool, NT_SUCCESS, PAGED_CODE, TRUE, and ValueName.

00217 { 00218 ULONG i; 00219 00220 ULONG Value; 00221 UNICODE_STRING ValueName; 00222 00223 extern KSEMAPHORE FsRtlpUncSemaphore; 00224 00225 PAGED_CODE(); 00226 00227 // 00228 // Allocate and initialize all the paging Io resources 00229 // 00230 00231 FsRtlPagingIoResources = FsRtlAllocatePool( NonPagedPool, 00232 FSRTL_NUMBER_OF_RESOURCES * 00233 sizeof(ERESOURCE) ); 00234 00235 for (i=0; i < FSRTL_NUMBER_OF_RESOURCES; i++) { 00236 00237 ExInitializeResource( &FsRtlPagingIoResources[i] ); 00238 } 00239 00240 // 00241 // Initialize the global tunneling structures. 00242 // 00243 00244 FsRtlInitializeTunnels(); 00245 00246 // 00247 // Initialize the global filelock structures. 00248 // 00249 00250 FsRtlInitializeFileLocks(); 00251 00252 // 00253 // Initialize the global largemcb structures. 00254 // 00255 00256 FsRtlInitializeLargeMcbs(); 00257 00258 // 00259 // Initialize the semaphore used to guard loading of the MUP 00260 // 00261 00262 KeInitializeSemaphore( &FsRtlpUncSemaphore, 1, MAXLONG ); 00263 00264 // 00265 // Pull the bit from the registry telling us whether to do a safe 00266 // or dangerous extension truncation. 00267 // 00268 00269 ValueName.Buffer = COMPATIBILITY_MODE_VALUE_NAME; 00270 ValueName.Length = sizeof(COMPATIBILITY_MODE_VALUE_NAME) - sizeof(WCHAR); 00271 ValueName.MaximumLength = sizeof(COMPATIBILITY_MODE_VALUE_NAME); 00272 00273 if (NT_SUCCESS(FsRtlGetCompatibilityModeValue( &ValueName, &Value )) && 00274 (Value != 0)) { 00275 00276 FsRtlSafeExtensions = FALSE; 00277 } 00278 00279 // 00280 // Initialize the FsRtl stack overflow work QueueObject and thread. 00281 // 00282 00283 if (!NT_SUCCESS(FsRtlInitializeWorkerThread())) { 00284 00285 return FALSE; 00286 } 00287 00288 return TRUE; 00289 }

NTKERNELAPI NTSTATUS FsRtlInsertFilterContext IN PFILE_OBJECT  FileObject,
IN PFSRTL_FILTER_CONTEXT  Ptr
 

Definition at line 58 of file filtrctx.c.

References ASSERT, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS, Header, PFSRTL_FILTER_CONTEXT, and Ptr.

00064 : 00065 00066 This routine associates filter driver context with a stream. 00067 00068 Arguments: 00069 00070 FileObject - Specifies the stream of interest. 00071 00072 Ptr - Pointer to the filter-specific context structure. 00073 The common header fields OwnerId and InstanceId should 00074 be filled in by the filter driver before calling. 00075 00076 Return Value: 00077 00078 STATUS_SUCCESS - operation succeeded. 00079 00080 STATUS_INVALID_DEVICE_REQUEST - underlying filesystem does not support 00081 filter contexts. 00082 00083 --*/ 00084 00085 { 00086 PFSRTL_COMMON_FCB_HEADER Header; 00087 00088 ASSERT(FileObject); 00089 ASSERT(FileObject->FsContext); 00090 00091 Header = FileObject->FsContext; 00092 00093 if (! (Header->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS) ) { 00094 return STATUS_INVALID_DEVICE_REQUEST; 00095 } 00096 00097 ExAcquireFastMutex (Header->FastMutex); 00098 00099 InsertHeadList (&Header->FilterContexts, &Ptr->Links); 00100 00101 ExReleaseFastMutex(Header->FastMutex); 00102 return STATUS_SUCCESS; 00103 }

NTKERNELAPI BOOLEAN FsRtlIsDbcsInExpression IN PANSI_STRING  Expression,
IN PANSI_STRING  Name
 

Definition at line 771 of file dbcsname.c.

References ASSERT, Dbg, DebugTrace, ExFreePool(), FALSE, FsRtlDoesDbcsContainWildCards(), FsRtlIsLeadDbcsCharacter, FsRtlpAllocatePool, GetDbcs, MATCHES_ARRAY_SIZE, Name, NlsMbOemCodePageTag, NULL, Offset, PAGED_CODE, PagedPool, TRUE, and USHORT.

00778 : 00779 00780 This routine compares a Dbcs name and an expression and tells the caller 00781 if the name is in the language defined by the expression. The input name 00782 cannot contain wildcards, while the expression may contain wildcards. 00783 00784 Expression wild cards are evaluated as shown in the nondeterministic 00785 finite automatons below. Note that ~* and ~? are DOS_STAR and DOS_QM. 00786 00787 00788 ~* is DOS_STAR, ~? is DOS_QM, and ~. is DOS_DOT 00789 00790 00791 S 00792 <-----< 00793 X | | e Y 00794 X * Y == (0)----->-(1)->-----(2)-----(3) 00795 00796 00797 S-. 00798 <-----< 00799 X | | e Y 00800 X ~* Y == (0)----->-(1)->-----(2)-----(3) 00801 00802 00803 00804 X S S Y 00805 X ?? Y == (0)---(1)---(2)---(3)---(4) 00806 00807 00808 00809 X . . Y 00810 X ~.~. Y == (0)---(1)----(2)------(3)---(4) 00811 | |________| 00812 | ^ | 00813 |_______________| 00814 ^EOF or .^ 00815 00816 00817 X S-. S-. Y 00818 X ~?~? Y == (0)---(1)-----(2)-----(3)---(4) 00819 | |________| 00820 | ^ | 00821 |_______________| 00822 ^EOF or .^ 00823 00824 00825 00826 where S is any single character 00827 00828 S-. is any single character except the final . 00829 00830 e is a null character transition 00831 00832 EOF is the end of the name string 00833 00834 In words: 00835 00836 * matches 0 or more characters. 00837 00838 ? matches exactly 1 character. 00839 00840 DOS_STAR matches 0 or more characters until encountering and matching 00841 the final . in the name. 00842 00843 DOS_QM matches any single character, or upon encountering a period or 00844 end of name string, advances the expression to the end of the 00845 set of contiguous DOS_QMs. 00846 00847 DOS_DOT matches either a . or zero characters beyond name string. 00848 00849 Arguments: 00850 00851 Expression - Supplies the input expression to check against 00852 00853 Name - Supplies the input name to check for. 00854 00855 Return Value: 00856 00857 BOOLEAN - TRUE if Name is an element in the set of strings denoted 00858 by the input Expression and FALSE otherwise. 00859 00860 --*/ 00861 00862 { 00863 USHORT NameOffset; 00864 USHORT ExprOffset; 00865 USHORT Length; 00866 00867 ULONG SrcCount; 00868 ULONG DestCount; 00869 ULONG PreviousDestCount; 00870 ULONG MatchesCount; 00871 00872 WCHAR NameChar, ExprChar; 00873 00874 USHORT LocalBuffer[MATCHES_ARRAY_SIZE * 2]; 00875 00876 USHORT *AuxBuffer = NULL; 00877 USHORT *PreviousMatches; 00878 USHORT *CurrentMatches; 00879 00880 USHORT MaxState; 00881 USHORT CurrentState; 00882 00883 BOOLEAN NameFinished = FALSE; 00884 00885 // 00886 // The idea behind the algorithm is pretty simple. We keep track of 00887 // all possible locations in the regular expression that are matching 00888 // the name. If when the name has been exhausted one of the locations 00889 // in the expression is also just exhausted, the name is in the language 00890 // defined by the regular expression. 00891 // 00892 00893 PAGED_CODE(); 00894 00895 DebugTrace(+1, Dbg, "FsRtlIsDbcsInExpression\n", 0); 00896 DebugTrace( 0, Dbg, " Expression = %Z\n", Expression ); 00897 DebugTrace( 0, Dbg, " Name = %Z\n", Name ); 00898 00899 ASSERT( Name->Length != 0 ); 00900 ASSERT( Expression->Length != 0 ); 00901 00902 // 00903 // If one string is empty return FALSE. If both are empty return TRUE. 00904 // 00905 00906 if ( (Name->Length == 0) || (Expression->Length == 0) ) { 00907 00908 return (BOOLEAN)(!(Name->Length + Expression->Length)); 00909 } 00910 00911 // 00912 // Special case by far the most common wild card search of * 00913 // 00914 00915 if ((Expression->Length == 1) && (Expression->Buffer[0] == '*')) { 00916 00917 return TRUE; 00918 } 00919 00920 ASSERT( FsRtlDoesDbcsContainWildCards( Expression ) ); 00921 00922 // 00923 // Also special case expressions of the form *X. With this and the prior 00924 // case we have covered virtually all normal queries. 00925 // 00926 00927 if (Expression->Buffer[0] == '*') { 00928 00929 ANSI_STRING LocalExpression; 00930 00931 LocalExpression = *Expression; 00932 00933 LocalExpression.Buffer += 1; 00934 LocalExpression.Length -= 1; 00935 00936 // 00937 // Only special case an expression with a single * 00938 // 00939 00940 if ( !FsRtlDoesDbcsContainWildCards( &LocalExpression ) ) { 00941 00942 ULONG StartingNameOffset; 00943 00944 if (Name->Length < (USHORT)(Expression->Length - 1)) { 00945 00946 return FALSE; 00947 } 00948 00949 StartingNameOffset = Name->Length - LocalExpression.Length; 00950 00951 // 00952 // FsRtlIsDbcsInExpression(): bug fix "expression[0] == *" case 00953 // 00954 // StatingNameOffset must not bisect DBCS characters. 00955 // 00956 00957 if (NlsMbOemCodePageTag) { 00958 00959 ULONG i = 0; 00960 00961 while ( i < StartingNameOffset ) { 00962 00963 i += FsRtlIsLeadDbcsCharacter( Name->Buffer[i] ) ? 2 : 1; 00964 } 00965 00966 if ( i > StartingNameOffset ) { 00967 00968 return FALSE; 00969 } 00970 } 00971 00972 // 00973 // Do a simple memory compare if case sensitive, otherwise 00974 // we have got to check this one character at a time. 00975 // 00976 00977 return (BOOLEAN) RtlEqualMemory( LocalExpression.Buffer, 00978 Name->Buffer + StartingNameOffset, 00979 LocalExpression.Length ); 00980 } 00981 } 00982 00983 // 00984 // Walk through the name string, picking off characters. We go one 00985 // character beyond the end because some wild cards are able to match 00986 // zero characters beyond the end of the string. 00987 // 00988 // With each new name character we determine a new set of states that 00989 // match the name so far. We use two arrays that we swap back and forth 00990 // for this purpose. One array lists the possible expression states for 00991 // all name characters up to but not including the current one, and other 00992 // array is used to build up the list of states considering the current 00993 // name character as well. The arrays are then switched and the process 00994 // repeated. 00995 // 00996 // There is not a one-to-one correspondence between state number and 00997 // offset into the expression. This is evident from the NFAs in the 00998 // initial comment to this function. State numbering is not continuous. 00999 // This allows a simple conversion between state number and expression 01000 // offset. Each character in the expression can represent one or two 01001 // states. * and DOS_STAR generate two states: ExprOffset*2 and 01002 // ExprOffset*2 + 1. All other expreesion characters can produce only 01003 // a single state. Thus ExprOffset = State/2. 01004 // 01005 // 01006 // Here is a short description of the variables involved: 01007 // 01008 // NameOffset - The offset of the current name char being processed. 01009 // 01010 // ExprOffset - The offset of the current expression char being processed. 01011 // 01012 // SrcCount - Prior match being investigated with current name char 01013 // 01014 // DestCount - Next location to put a matching assuming current name char 01015 // 01016 // NameFinished - Allows one more itteration through the Matches array 01017 // after the name is exhusted (to come *s for example) 01018 // 01019 // PreviousDestCount - This is used to prevent entry duplication, see coment 01020 // 01021 // PreviousMatches - Holds the previous set of matches (the Src array) 01022 // 01023 // CurrentMatches - Holds the current set of matches (the Dest array) 01024 // 01025 // AuxBuffer, LocalBuffer - the storage for the Matches arrays 01026 // 01027 01028 // 01029 // Set up the initial variables 01030 // 01031 01032 PreviousMatches = &LocalBuffer[0]; 01033 CurrentMatches = &LocalBuffer[MATCHES_ARRAY_SIZE]; 01034 01035 PreviousMatches[0] = 0; 01036 MatchesCount = 1; 01037 01038 NameOffset = 0; 01039 01040 MaxState = (USHORT)(Expression->Length * 2); 01041 01042 while ( !NameFinished ) { 01043 01044 if ( NameOffset < Name->Length ) { 01045 01046 GetDbcs( Name->Buffer, NameOffset, &NameChar, &Length ); 01047 NameOffset += Length; 01048 01049 } else { 01050 01051 NameFinished = TRUE; 01052 01053 // 01054 // if we have already exhasted the expression, cool. Don't 01055 // continue. 01056 // 01057 01058 if ( PreviousMatches[MatchesCount-1] == MaxState ) { 01059 01060 break; 01061 } 01062 } 01063 01064 01065 // 01066 // Now, for each of the previous stored expression matches, see what 01067 // we can do with this name character. 01068 // 01069 01070 SrcCount = 0; 01071 DestCount = 0; 01072 PreviousDestCount = 0; 01073 01074 while ( SrcCount < MatchesCount ) { 01075 01076 // 01077 // We have to carry on our expression analysis as far as possible 01078 // for each character of name, so we loop here until the 01079 // expression stops matching. A clue here is that expression 01080 // cases that can match zero or more characters end with a 01081 // continue, while those that can accept only a single character 01082 // end with a break. 01083 // 01084 01085 ExprOffset = (USHORT)((PreviousMatches[SrcCount++] + 1) / 2); 01086 01087 Length = 0; 01088 01089 01090 while ( TRUE ) { 01091 01092 if ( ExprOffset == Expression->Length ) { 01093 01094 break; 01095 } 01096 01097 // 01098 // The first time through the loop we don't want 01099 // to increment ExprOffset. 01100 // 01101 01102 ExprOffset += Length; 01103 01104 CurrentState = (USHORT)(ExprOffset * 2); 01105 01106 if ( ExprOffset == Expression->Length ) { 01107 01108 CurrentMatches[DestCount++] = MaxState; 01109 break; 01110 } 01111 01112 GetDbcs(Expression->Buffer, ExprOffset, &ExprChar, &Length); 01113 01114 ASSERT( !((ExprChar >= 'a') && (ExprChar <= 'z')) ); 01115 01116 // 01117 // Before we get started, we have to check for something 01118 // really gross. We may be about to exhaust the local 01119 // space for ExpressionMatches[][], so we have to allocate 01120 // some pool if this is the case. Yuk! 01121 // 01122 01123 if ( (DestCount >= MATCHES_ARRAY_SIZE - 2) && 01124 (AuxBuffer == NULL) ) { 01125 01126 AuxBuffer = FsRtlpAllocatePool( PagedPool, 01127 (Expression->Length+1) * 01128 sizeof(USHORT)*2*2 ); 01129 01130 RtlCopyMemory( AuxBuffer, 01131 CurrentMatches, 01132 MATCHES_ARRAY_SIZE * sizeof(USHORT) ); 01133 01134 CurrentMatches = AuxBuffer; 01135 01136 RtlCopyMemory( AuxBuffer + (Expression->Length+1)*2, 01137 PreviousMatches, 01138 MATCHES_ARRAY_SIZE * sizeof(USHORT) ); 01139 01140 PreviousMatches = AuxBuffer + (Expression->Length+1)*2; 01141 01142 } 01143 01144 // 01145 // * matches any character zero or more times. 01146 // 01147 01148 if (ExprChar == '*') { 01149 01150 CurrentMatches[DestCount++] = CurrentState; 01151 CurrentMatches[DestCount++] = CurrentState + 1; 01152 continue; 01153 } 01154 01155 // 01156 // DOS_STAR matches any character except . zero or more times. 01157 // 01158 01159 if (ExprChar == ANSI_DOS_STAR) { 01160 01161 BOOLEAN ICanEatADot = FALSE; 01162 01163 // 01164 // If we are at a period, determine if we are allowed to 01165 // consume it, ie. make sure it is not the last one. 01166 // 01167 01168 if ( !NameFinished && (NameChar == '.') ) { 01169 01170 WCHAR NameChar; 01171 USHORT Offset; 01172 USHORT Length; 01173 01174 for ( Offset = NameOffset; 01175 Offset < Name->Length; 01176 Offset += Length ) { 01177 01178 GetDbcs( Name->Buffer, Offset, &NameChar, &Length ); 01179 01180 if (NameChar == '.') { 01181 01182 ICanEatADot = TRUE; 01183 break; 01184 } 01185 } 01186 } 01187 01188 if (NameFinished || (NameChar != '.') || ICanEatADot) { 01189 01190 CurrentMatches[DestCount++] = CurrentState; 01191 CurrentMatches[DestCount++] = CurrentState + 1; 01192 continue; 01193 01194 } else { 01195 01196 // 01197 // We are at a period. We can only match zero 01198 // characters (ie. the epsilon transition). 01199 // 01200 01201 CurrentMatches[DestCount++] = CurrentState + 1; 01202 continue; 01203 } 01204 } 01205 01206 // 01207 // The following expreesion characters all match by consuming 01208 // a character, thus force the expression, and thus state 01209 // forward. 01210 // 01211 01212 CurrentState += (USHORT)(Length * 2); 01213 01214 // 01215 // DOS_QM is the most complicated. If the name is finished, 01216 // we can match zero characters. If this name is a '.', we 01217 // don't match, but look at the next expression. Otherwise 01218 // we match a single character. 01219 // 01220 01221 if ( ExprChar == ANSI_DOS_QM ) { 01222 01223 if ( NameFinished || (NameChar == '.') ) { 01224 01225 continue; 01226 } 01227 01228 CurrentMatches[DestCount++] = CurrentState; 01229 break; 01230 } 01231 01232 // 01233 // A DOS_DOT can match either a period, or zero characters 01234 // beyond the end of name. 01235 // 01236 01237 if (ExprChar == DOS_DOT) { 01238 01239 if ( NameFinished ) { 01240 01241 continue; 01242 } 01243 01244 if (NameChar == '.') { 01245 01246 CurrentMatches[DestCount++] = CurrentState; 01247 break; 01248 } 01249 } 01250 01251 // 01252 // From this point on a name character is required to even 01253 // continue, let alone make a match. 01254 // 01255 01256 if ( NameFinished ) { 01257 01258 break; 01259 } 01260 01261 // 01262 // If this expression was a '?' we can match it once. 01263 // 01264 01265 if (ExprChar == '?') { 01266 01267 CurrentMatches[DestCount++] = CurrentState; 01268 break; 01269 } 01270 01271 // 01272 // Finally, check if the expression char matches the name char 01273 // 01274 01275 if (ExprChar == NameChar) { 01276 01277 CurrentMatches[DestCount++] = CurrentState; 01278 break; 01279 } 01280 01281 // 01282 // The expression didn't match so go look at the next 01283 // previous match. 01284 // 01285 01286 break; 01287 } 01288 01289 01290 // 01291 // Prevent duplication in the destination array. 01292 // 01293 // Each of the arrays is montonically increasing and non- 01294 // duplicating, thus we skip over any source element in the src 01295 // array if we just added the same element to the destination 01296 // array. This guarentees non-duplication in the dest. array. 01297 // 01298 01299 if ((SrcCount < MatchesCount) && 01300 (PreviousDestCount < DestCount) ) { 01301 01302 while (PreviousDestCount < DestCount) { 01303 01304 while ( PreviousMatches[SrcCount] < 01305 CurrentMatches[PreviousDestCount] ) { 01306 01307 01308 SrcCount += 1; 01309 } 01310 01311 PreviousDestCount += 1; 01312 } 01313 } 01314 } 01315 01316 // 01317 // If we found no matches in the just finished itteration, it's time 01318 // to bail. 01319 // 01320 01321 if ( DestCount == 0 ) { 01322 01323 01324 if (AuxBuffer != NULL) { ExFreePool( AuxBuffer ); } 01325 01326 return FALSE; 01327 } 01328 01329 // 01330 // Swap the meaning the two arrays 01331 // 01332 01333 { 01334 USHORT *Tmp; 01335 01336 Tmp = PreviousMatches; 01337 01338 PreviousMatches = CurrentMatches; 01339 01340 CurrentMatches = Tmp; 01341 } 01342 01343 MatchesCount = DestCount; 01344 } 01345 01346 01347 CurrentState = PreviousMatches[MatchesCount-1]; 01348 01349 if (AuxBuffer != NULL) { ExFreePool( AuxBuffer ); } 01350 01351 01352 return (BOOLEAN)(CurrentState == MaxState); 01353 } }

NTKERNELAPI BOOLEAN FsRtlIsFatDbcsLegal IN ANSI_STRING  DbcsName,
IN BOOLEAN  WildCardsPermissible,
IN BOOLEAN  PathNamePermissible,
IN BOOLEAN  LeadingBackslashPermissible
 

Definition at line 81 of file dbcsname.c.

References ASSERT, FALSE, FsRtlDissectDbcs(), FsRtlDoesDbcsContainWildCards(), FsRtlIsAnsiCharacterLegalFat, FsRtlIsLeadDbcsCharacter, Index, PAGED_CODE, and TRUE.

Referenced by UdfIs8dot3Name().

00090 : 00091 00092 This routine simple returns whether the specified file names conforms 00093 to the file system specific rules for legal file names. This routine 00094 will check the single name, or if PathNamePermissible is specified as 00095 TRUE, whether the whole path is a legal name. 00096 00097 For FAT, the following rules apply: 00098 00099 A. A Fat file name may not contain any of the following characters: 00100 00101 0x00-0x1F " / : | + , ; = [ ] 00102 00103 B. A Fat file name is either of the form N.E or just N, where N is a 00104 string of 1-8 bytes and E is a string of 1-3 bytes conformant to 00105 rule A above. In addition, neither N nor E may contain a period 00106 character or end with a space character. 00107 00108 Incidently, N corresponds to name and E to extension. 00109 00110 Case: Lower case characters are taken as valid, but are up-shifted upon 00111 receipt, ie. Fat only deals with upper case file names. 00112 00113 For example, the files ".foo", "foo.", and "foo .b" are illegal, while 00114 "foo. b" and " bar" are legal. 00115 00116 Arguments: 00117 00118 DbcsName - Supllies the name/path to check. 00119 00120 WildCardsPermissible - Specifies if Nt wild card characters are to be 00121 considered considered legal. 00122 00123 PathNamePermissible - Spcifes if Name may be a path name separated by 00124 backslash characters, or just a simple file name. 00125 00126 LeadingBackSlashPermissible - Specifies if a single leading backslash 00127 is permissible in the file/path name. 00128 00129 Return Value: 00130 00131 BOOLEAN - TRUE if the name is legal, FALSE otherwise. 00132 00133 --*/ 00134 { 00135 BOOLEAN ExtensionPresent = FALSE; 00136 00137 ULONG Index; 00138 00139 UCHAR Char; 00140 00141 PAGED_CODE(); 00142 00143 // 00144 // Empty names are not valid. 00145 // 00146 00147 if ( DbcsName.Length == 0 ) { return FALSE; } 00148 00149 // 00150 // If Wild Cards are OK, then for directory enumeration to work 00151 // correctly we have to accept . and .. 00152 // 00153 00154 if ( WildCardsPermissible && 00155 ( ( (DbcsName.Length == 1) && 00156 ((DbcsName.Buffer[0] == '.') || 00157 (DbcsName.Buffer[0] == ANSI_DOS_DOT)) ) 00158 || 00159 ( (DbcsName.Length == 2) && 00160 ( ((DbcsName.Buffer[0] == '.') && 00161 (DbcsName.Buffer[1] == '.')) || 00162 ((DbcsName.Buffer[0] == ANSI_DOS_DOT) && 00163 (DbcsName.Buffer[1] == ANSI_DOS_DOT)) ) ) ) ) { 00164 00165 return TRUE; 00166 } 00167 00168 // 00169 // If a leading \ is OK, skip over it (if there's more) 00170 // 00171 00172 if ( DbcsName.Buffer[0] == '\\' ) { 00173 00174 if ( LeadingBackslashPermissible ) { 00175 00176 if ( (DbcsName.Length > 1) ) { 00177 00178 DbcsName.Buffer += 1; 00179 DbcsName.Length -= 1; 00180 00181 } else { return TRUE; } 00182 00183 } else { return FALSE; } 00184 } 00185 00186 // 00187 // If we got a path name, check each componant. 00188 // 00189 00190 if ( PathNamePermissible ) { 00191 00192 ANSI_STRING FirstName; 00193 ANSI_STRING RemainingName; 00194 00195 RemainingName = DbcsName; 00196 00197 while ( RemainingName.Length != 0 ) { 00198 00199 // 00200 // This will catch the case of an illegal double backslash. 00201 // 00202 00203 if ( RemainingName.Buffer[0] == '\\' ) { return FALSE; } 00204 00205 FsRtlDissectDbcs(RemainingName, &FirstName, &RemainingName); 00206 00207 if ( !FsRtlIsFatDbcsLegal( FirstName, 00208 WildCardsPermissible, 00209 FALSE, 00210 FALSE) ) { 00211 00212 return FALSE; 00213 } 00214 } 00215 00216 // 00217 // All the componants were OK, so the path is OK. 00218 // 00219 00220 return TRUE; 00221 } 00222 00223 // 00224 // If this name contains wild cards, just check for invalid characters. 00225 // 00226 00227 if ( WildCardsPermissible && FsRtlDoesDbcsContainWildCards(&DbcsName) ) { 00228 00229 for ( Index = 0; Index < DbcsName.Length; Index += 1 ) { 00230 00231 Char = DbcsName.Buffer[ Index ]; 00232 00233 // 00234 // Skip over any Dbcs chacters 00235 // 00236 00237 if ( FsRtlIsLeadDbcsCharacter( Char ) ) { 00238 00239 ASSERT( Index != (ULONG)(DbcsName.Length - 1) ); 00240 Index += 1; 00241 continue; 00242 } 00243 00244 // 00245 // Make sure this character is legal, and if a wild card, that 00246 // wild cards are permissible. 00247 // 00248 00249 if ( !FsRtlIsAnsiCharacterLegalFat(Char, WildCardsPermissible) ) { 00250 return FALSE; 00251 } 00252 } 00253 00254 return TRUE; 00255 } 00256 00257 00258 // 00259 // At this point we should only have a single name, which can't have 00260 // more than 12 characters (including a single period) 00261 // 00262 00263 if ( DbcsName.Length > 12 ) { return FALSE; } 00264 00265 for ( Index = 0; Index < DbcsName.Length; Index += 1 ) { 00266 00267 Char = DbcsName.Buffer[ Index ]; 00268 00269 // 00270 // Skip over and Dbcs chacters 00271 // 00272 00273 if ( FsRtlIsLeadDbcsCharacter( Char ) ) { 00274 00275 // 00276 // FsRtlIsFatDbcsLegal(): fat name part and extension part dbcs check 00277 // 00278 // 1) if we're looking at base part ( !ExtensionPresent ) and the 8th byte 00279 // is in the dbcs leading byte range, it's error ( Index == 7 ). If the 00280 // length of base part is more than 8 ( Index > 7 ), it's definitely error. 00281 // 00282 // 2) if the last byte ( Index == DbcsName.Length - 1 ) is in the dbcs leading 00283 // byte range, it's error 00284 // 00285 00286 if ( (!ExtensionPresent && (Index >= 7)) || 00287 ( Index == (ULONG)(DbcsName.Length - 1) ) ) { 00288 return FALSE; 00289 } 00290 00291 Index += 1; 00292 00293 continue; 00294 } 00295 00296 // 00297 // Make sure this character is legal, and if a wild card, that 00298 // wild cards are permissible. 00299 // 00300 00301 if ( !FsRtlIsAnsiCharacterLegalFat(Char, WildCardsPermissible) ) { 00302 00303 return FALSE; 00304 } 00305 00306 if ( (Char == '.') || (Char == ANSI_DOS_DOT) ) { 00307 00308 // 00309 // We stepped onto a period. We require the following things: 00310 // 00311 // - It can't be the first character 00312 // - There can only be one 00313 // - There can't be more than three characters following 00314 // - The previous character can't be a space. 00315 // 00316 00317 if ( (Index == 0) || 00318 ExtensionPresent || 00319 (DbcsName.Length - (Index + 1) > 3) || 00320 (DbcsName.Buffer[Index - 1] == ' ') ) { 00321 00322 return FALSE; 00323 } 00324 00325 ExtensionPresent = TRUE; 00326 } 00327 00328 // 00329 // The base part of the name can't be more than 8 characters long. 00330 // 00331 00332 if ( (Index >= 8) && !ExtensionPresent ) { return FALSE; } 00333 } 00334 00335 // 00336 // The name cannot end in a space or a period. 00337 // 00338 00339 if ( (Char == ' ') || (Char == '.') || (Char == ANSI_DOS_DOT)) { return FALSE; } 00340 00341 return TRUE; 00342 }

NTKERNELAPI BOOLEAN FsRtlIsHpfsDbcsLegal IN ANSI_STRING  DbcsName,
IN BOOLEAN  WildCardsPermissible,
IN BOOLEAN  PathNamePermissible,
IN BOOLEAN  LeadingBackslashPermissible
 

Definition at line 345 of file dbcsname.c.

References FALSE, FsRtlDissectDbcs(), FsRtlIsAnsiCharacterLegalHpfs, FsRtlIsLeadDbcsCharacter, Index, PAGED_CODE, and TRUE.

00354 : 00355 00356 This routine simple returns whether the specified file names conforms 00357 to the file system specific rules for legal file names. This routine 00358 will check the single name, or if PathNamePermissible is specified as 00359 TRUE, whether the whole path is a legal name. 00360 00361 For HPFS, the following rules apply: 00362 00363 A. An HPFS file name may not contain any of the following characters: 00364 00365 0x0000 - 0x001F " / : < > ? | * 00366 00367 B. An HPFS file name may not end in a period or a space. 00368 00369 C. An HPFS file name must contain no more than 255 bytes. 00370 00371 Case: HPFS is case preserving, but not case sensitive. Case is 00372 preserved on creates, but not checked for on file name compares. 00373 00374 For example, the files "foo " and "foo." are illegal, while ".foo", 00375 " foo" and "foo.bar.foo" are legal. 00376 00377 Arguments: 00378 00379 DbcsName - Supllies the name/path to check. 00380 00381 WildCardsPermissible - Specifies if Nt wild card characters are to be 00382 considered considered legal. 00383 00384 PathNamePermissible - Spcifes if Name may be a path name separated by 00385 backslash characters, or just a simple file name. 00386 00387 LeadingBackSlashPermissible - Specifies if a single leading backslash 00388 is permissible in the file/path name. 00389 00390 Return Value: 00391 00392 BOOLEAN - TRUE if the name is legal, FALSE otherwise. 00393 00394 --*/ 00395 { 00396 BOOLEAN ExtensionPresent = FALSE; 00397 00398 ULONG Index; 00399 00400 UCHAR Char; 00401 00402 PAGED_CODE(); 00403 00404 // 00405 // Empty names are not valid. 00406 // 00407 00408 if ( DbcsName.Length == 0 ) { return FALSE; } 00409 00410 // 00411 // If Wild Cards are OK, then for directory enumeration to work 00412 // correctly we have to accept . and .. 00413 // 00414 00415 if ( WildCardsPermissible && 00416 ( ( (DbcsName.Length == 1) && 00417 ((DbcsName.Buffer[0] == '.') || 00418 (DbcsName.Buffer[0] == ANSI_DOS_DOT)) ) 00419 || 00420 ( (DbcsName.Length == 2) && 00421 ( ((DbcsName.Buffer[0] == '.') && 00422 (DbcsName.Buffer[1] == '.')) || 00423 ((DbcsName.Buffer[0] == ANSI_DOS_DOT) && 00424 (DbcsName.Buffer[1] == ANSI_DOS_DOT)) ) ) ) ) { 00425 00426 return TRUE; 00427 } 00428 00429 // 00430 // If a leading \ is OK, skip over it (if there's more) 00431 // 00432 00433 if ( DbcsName.Buffer[0] == '\\' ) { 00434 00435 if ( LeadingBackslashPermissible ) { 00436 00437 if ( (DbcsName.Length > 1) ) { 00438 00439 DbcsName.Buffer += 1; 00440 DbcsName.Length -= 1; 00441 00442 } else { return TRUE; } 00443 00444 } else { return FALSE; } 00445 } 00446 00447 // 00448 // If we got a path name, check each componant. 00449 // 00450 00451 if ( PathNamePermissible ) { 00452 00453 ANSI_STRING FirstName; 00454 ANSI_STRING RemainingName; 00455 00456 RemainingName = DbcsName; 00457 00458 while ( RemainingName.Length != 0 ) { 00459 00460 // 00461 // This will catch the case of an illegal double backslash. 00462 // 00463 00464 if ( RemainingName.Buffer[0] == '\\' ) { return FALSE; } 00465 00466 FsRtlDissectDbcs(RemainingName, &FirstName, &RemainingName); 00467 00468 if ( !FsRtlIsHpfsDbcsLegal( FirstName, 00469 WildCardsPermissible, 00470 FALSE, 00471 FALSE) ) { 00472 00473 return FALSE; 00474 } 00475 } 00476 00477 // 00478 // All the componants were OK, so the path is OK. 00479 // 00480 00481 return TRUE; 00482 } 00483 00484 // 00485 // At this point we should only have a single name, which can't have 00486 // more than 255 characters 00487 // 00488 00489 if ( DbcsName.Length > 255 ) { return FALSE; } 00490 00491 for ( Index = 0; Index < DbcsName.Length; Index += 1 ) { 00492 00493 Char = DbcsName.Buffer[ Index ]; 00494 00495 // 00496 // Skip over and Dbcs chacters 00497 // 00498 00499 if ( FsRtlIsLeadDbcsCharacter( Char ) ) { 00500 00501 // 00502 // FsRtlIsHpfsDbcsLegal () hpfs dbcs check 00503 // 00504 // If the last byte ( Index == DbcsName.Length - 1 ) is in the 00505 // dbcs leading byte range, it's error. 00506 // 00507 00508 if ( Index == (ULONG)(DbcsName.Length - 1) ) { 00509 00510 return FALSE; 00511 } 00512 00513 Index += 1; 00514 continue; 00515 } 00516 00517 // 00518 // Make sure this character is legal, and if a wild card, that 00519 // wild cards are permissible. 00520 // 00521 00522 if ( !FsRtlIsAnsiCharacterLegalHpfs(Char, WildCardsPermissible) ) { 00523 00524 return FALSE; 00525 } 00526 } 00527 00528 // 00529 // The name cannot end in a space or a period. 00530 // 00531 00532 if ( (Char == ' ') || (Char == '.') || (Char == ANSI_DOS_DOT) ) { 00533 00534 return FALSE; 00535 } 00536 00537 return TRUE; 00538 }

NTKERNELAPI BOOLEAN FsRtlIsNameInExpression IN PUNICODE_STRING  Expression,
IN PUNICODE_STRING  Name,
IN BOOLEAN  IgnoreCase,
IN PWCH UpcaseTable  OPTIONAL
 

Definition at line 415 of file name.c.

References ExRaiseStatus(), FALSE, FsRtlIsNameInExpressionPrivate(), Name, NT_SUCCESS, NTSTATUS(), NULL, RtlFreeUnicodeString(), RtlUpcaseUnicodeString(), Status, and TRUE.

Referenced by UdfIsNameInExpression().

00422 { 00423 BOOLEAN Result; 00424 UNICODE_STRING LocalName; 00425 00426 // 00427 // If we weren't given an upcase table, we have to upcase the names 00428 // ourselves. 00429 // 00430 00431 if ( IgnoreCase && !ARGUMENT_PRESENT(UpcaseTable) ) { 00432 00433 NTSTATUS Status; 00434 00435 Status = RtlUpcaseUnicodeString( &LocalName, Name, TRUE ); 00436 00437 if ( !NT_SUCCESS(Status) ) { 00438 00439 ExRaiseStatus( Status ); 00440 } 00441 00442 Name = &LocalName; 00443 00444 IgnoreCase = FALSE; 00445 00446 } else { 00447 00448 LocalName.Buffer = NULL; 00449 } 00450 00451 // 00452 // Now call the main routine, remembering to free the upcased string 00453 // if we allocated one. 00454 // 00455 00456 try { 00457 00458 Result = FsRtlIsNameInExpressionPrivate( Expression, 00459 Name, 00460 IgnoreCase, 00461 UpcaseTable ); 00462 00463 } finally { 00464 00465 if (LocalName.Buffer != NULL) { 00466 00467 RtlFreeUnicodeString( &LocalName ); 00468 } 00469 } 00470 00471 return Result; 00472 }

NTKERNELAPI BOOLEAN FsRtlIsNtstatusExpected IN NTSTATUS  Exception  ) 
 

Definition at line 82 of file fsrtl/filter.c.

References FALSE, and TRUE.

Referenced by CcExceptionFilter(), FsRtlCancelNotify(), FsRtlCopyRead(), FsRtlCopyWrite(), FsRtlMdlReadDev(), FsRtlNormalizeNtstatus(), FsRtlNotifyFullReportChange(), FsRtlPrepareMdlWriteDev(), LfsExceptionFilter(), UdfCreateUserMdl(), UdfExceptionFilter(), and UdfQueryDirectory().

00088 : 00089 00090 This routine is used to decide if a status is within the set of values 00091 handled by the exception filter. 00092 00093 Arguments: 00094 00095 Exception - Supplies the exception being queried 00096 00097 Return Value: 00098 00099 BOOLEAN - Returns TRUE if the value is handled by the filter, and 00100 FALSE otherwise. 00101 00102 --*/ 00103 00104 { 00105 switch (Exception) { 00106 00107 case STATUS_DATATYPE_MISALIGNMENT: 00108 case STATUS_ACCESS_VIOLATION: 00109 case STATUS_ILLEGAL_INSTRUCTION: 00110 case STATUS_INSTRUCTION_MISALIGNMENT: 00111 00112 return FALSE; 00113 00114 default: 00115 00116 return TRUE; 00117 } 00118 }

NTKERNELAPI BOOLEAN FsRtlIsTotalDeviceFailure IN NTSTATUS  Status  ) 
 

Definition at line 304 of file fsrtl/filter.c.

References FALSE, NT_SUCCESS, Status, and TRUE.

Referenced by IopMountVolume().

00310 : 00311 00312 This routine is given an NTSTATUS value and make a determination as to 00313 if this value indicates that the complete device has failed and therefore 00314 should no longer be used, or if the failure is one that indicates that 00315 continued use of the device is ok (i.e. a sector failure). 00316 00317 Arguments: 00318 00319 Status - the NTSTATUS value to test. 00320 00321 Return Value: 00322 00323 TRUE - The status value given is believed to be a fatal device error. 00324 FALSE - The status value given is believed to be a sector failure, but not 00325 a complete device failure. 00326 --*/ 00327 00328 { 00329 if (NT_SUCCESS(Status)) { 00330 00331 // 00332 // All warning and informational errors will be resolved here. 00333 // 00334 00335 return FALSE; 00336 } 00337 00338 switch (Status) { 00339 case STATUS_CRC_ERROR: 00340 case STATUS_DEVICE_DATA_ERROR: 00341 return FALSE; 00342 default: 00343 return TRUE; 00344 } 00345 } }

NTKERNELAPI PFSRTL_FILTER_CONTEXT FsRtlLookupFilterContextInternal IN PFILE_OBJECT  FileObject,
IN PVOID OwnerId  OPTIONAL,
IN PVOID InstanceId  OPTIONAL
 

Definition at line 108 of file filtrctx.c.

References ASSERT, FSRTL_FILTER_CONTEXT, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS, Header, _FSRTL_FILTER_CONTEXT::InstanceId, List, MySearchList, NULL, and _FSRTL_FILTER_CONTEXT::OwnerId.

00115 : 00116 00117 This routine lookups filter driver context associated with a stream. 00118 00119 The macro FsRtlLookupFilterContext should be used instead of calling 00120 this routine directly. The macro optimizes for the common case 00121 of an empty list. 00122 00123 Arguments: 00124 00125 FileObject - Specifies the stream of interest. 00126 00127 OwnerId - Used to identify context information belonging to a particular 00128 filter driver. 00129 00130 InstanceId - Used to search for a particular instance of a filter driver 00131 context. If not provided, any of the contexts owned by the filter 00132 driver is returned. 00133 00134 If neither the OwnerId nor the InstanceId is provided, any associated 00135 filter context will be returned. 00136 00137 Return Value: 00138 00139 A pointer to the filter context, or NULL if no match found. 00140 00141 --*/ 00142 00143 { 00144 PFSRTL_COMMON_FCB_HEADER Header; 00145 PFSRTL_FILTER_CONTEXT Ctx, RtnCtx; 00146 PLIST_ENTRY List; 00147 00148 ASSERT(FileObject); 00149 ASSERT(FileObject->FsContext); 00150 00151 Header = FileObject->FsContext; 00152 00153 ASSERT (Header->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS); 00154 00155 ExAcquireFastMutex (Header->FastMutex); 00156 RtnCtx = NULL; 00157 00158 // Use different loops depending on whether we are comparing both Ids or not. 00159 if ( ARGUMENT_PRESENT(InstanceId) ) { 00160 00161 MySearchList (&Header->FilterContexts, List) { 00162 Ctx = CONTAINING_RECORD (List, FSRTL_FILTER_CONTEXT, Links); 00163 if (Ctx->OwnerId == OwnerId && Ctx->InstanceId == InstanceId) { 00164 RtnCtx = Ctx; 00165 break; 00166 } 00167 } 00168 } else if ( ARGUMENT_PRESENT(OwnerId) ) { 00169 00170 MySearchList (&Header->FilterContexts, List) { 00171 Ctx = CONTAINING_RECORD (List, FSRTL_FILTER_CONTEXT, Links); 00172 if (Ctx->OwnerId == OwnerId) { 00173 RtnCtx = Ctx; 00174 break; 00175 } 00176 } 00177 } else if (!IsListEmpty(&Header->FilterContexts)) { 00178 00179 RtnCtx = (PFSRTL_FILTER_CONTEXT) Header->FilterContexts.Flink; 00180 } 00181 00182 ExReleaseFastMutex(Header->FastMutex); 00183 return RtnCtx; 00184 }

NTKERNELAPI BOOLEAN FsRtlLookupLargeMcbEntry IN PLARGE_MCB  Mcb,
IN LONGLONG  Vbn,
OUT PLONGLONG Lbn  OPTIONAL,
OUT PLONGLONG SectorCountFromLbn  OPTIONAL,
OUT PLONGLONG StartingLbn  OPTIONAL,
OUT PLONGLONG SectorCountFromStartingLbn  OPTIONAL,
OUT PULONG Index  OPTIONAL
 

Referenced by FsRtlLookupMcbEntry(), UdfDvdReadStructure(), UdfDvdTransferKey(), UdfLookupAllocation(), UdfReadSectors(), and UdfVmcbLookupMcbEntry().

NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntry IN PLARGE_MCB  Mcb,
OUT PLONGLONG  Vbn,
OUT PLONGLONG  Lbn
 

Definition at line 1763 of file largemcb.c.

References Dbg, DebugTrace, EndingLbn, EndingVbn, FALSE, _NONOPAQUE_MCB::FastMutex, PAGED_CODE, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, TRUE, try_return, and UNUSED_LBN.

Referenced by FsRtlLookupLastMcbEntry().

01771 : 01772 01773 This routine retrieves the last Vbn to Lbn mapping stored in the Mcb. 01774 It returns the mapping for the last sector or the last run in the 01775 Mcb. The results of this function is useful when extending an existing 01776 file and needing to a hint on where to try and allocate sectors on the 01777 disk. 01778 01779 Arguments: 01780 01781 OpaqueMcb - Supplies the Mcb being examined. 01782 01783 Vbn - Receives the last Vbn value mapped. 01784 01785 Lbn - Receives the Lbn corresponding to the Vbn. 01786 01787 Return Value: 01788 01789 BOOLEAN - TRUE if there is a mapping within the Mcb and FALSE otherwise 01790 (i.e., the Mcb does not contain any mapping). 01791 01792 --*/ 01793 01794 { 01795 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 01796 01797 BOOLEAN Result; 01798 01799 PAGED_CODE(); 01800 01801 DebugTrace(+1, Dbg, "FsRtlLookupLastLargeMcbEntry, Mcb = %08lx\n", Mcb ); 01802 01803 ExAcquireFastMutex( Mcb->FastMutex ); 01804 01805 try { 01806 01807 // 01808 // Check to make sure there is at least one run in the mcb 01809 // 01810 01811 if (Mcb->PairCount <= 0) { 01812 01813 try_return (Result = FALSE); 01814 } 01815 01816 // 01817 // Return the last mapping of the last run 01818 // 01819 01820 *((PULONG)LargeLbn) = EndingLbn(Mcb,Mcb->PairCount-1); 01821 *((PULONG)LargeVbn) = EndingVbn(Mcb,Mcb->PairCount-1); 01822 01823 Result = TRUE; 01824 01825 try_exit: NOTHING; 01826 } finally { 01827 01828 ExReleaseFastMutex( Mcb->FastMutex ); 01829 01830 DebugTrace(-1, Dbg, "FsRtlLookupLastLargeMcbEntry -> %08lx\n", Result ); 01831 } 01832 01833 ((PLARGE_INTEGER)LargeVbn)->HighPart = (*((PULONG)LargeVbn) == UNUSED_LBN ? UNUSED_LBN : 0); 01834 ((PLARGE_INTEGER)LargeLbn)->HighPart = (*((PULONG)LargeLbn) == UNUSED_LBN ? UNUSED_LBN : 0); 01835 01836 return Result; 01837 }

NTKERNELAPI BOOLEAN FsRtlLookupLastLargeMcbEntryAndIndex IN PLARGE_MCB  OpaqueMcb,
OUT PLONGLONG  LargeVbn,
OUT PLONGLONG  LargeLbn,
OUT PULONG  Index
 

Definition at line 1841 of file largemcb.c.

References Dbg, DebugTrace, EndingLbn, EndingVbn, FALSE, _NONOPAQUE_MCB::FastMutex, Index, PAGED_CODE, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, TRUE, try_return, and UNUSED_LBN.

01850 : 01851 01852 This routine retrieves the last Vbn to Lbn mapping stored in the Mcb. 01853 It returns the mapping for the last sector or the last run in the 01854 Mcb. The results of this function is useful when extending an existing 01855 file and needing to a hint on where to try and allocate sectors on the 01856 disk. 01857 01858 Arguments: 01859 01860 OpaqueMcb - Supplies the Mcb being examined. 01861 01862 Vbn - Receives the last Vbn value mapped. 01863 01864 Lbn - Receives the Lbn corresponding to the Vbn. 01865 01866 Index - Receives the index of the last run. 01867 01868 Return Value: 01869 01870 BOOLEAN - TRUE if there is a mapping within the Mcb and FALSE otherwise 01871 (i.e., the Mcb does not contain any mapping). 01872 01873 --*/ 01874 01875 { 01876 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 01877 01878 BOOLEAN Result; 01879 01880 PAGED_CODE(); 01881 01882 DebugTrace(+1, Dbg, "FsRtlLookupLastLargeMcbEntryAndIndex, Mcb = %08lx\n", Mcb ); 01883 01884 ExAcquireFastMutex( Mcb->FastMutex ); 01885 01886 try { 01887 01888 // 01889 // Check to make sure there is at least one run in the mcb 01890 // 01891 01892 if (Mcb->PairCount <= 0) { 01893 01894 try_return (Result = FALSE); 01895 } 01896 01897 // 01898 // Return the last mapping of the last run 01899 // 01900 01901 *((PULONG)LargeLbn) = EndingLbn(Mcb,Mcb->PairCount-1); 01902 *((PULONG)LargeVbn) = EndingVbn(Mcb,Mcb->PairCount-1); 01903 01904 *Index = Mcb->PairCount - 1; 01905 01906 Result = TRUE; 01907 01908 try_exit: NOTHING; 01909 } finally { 01910 01911 ExReleaseFastMutex( Mcb->FastMutex ); 01912 01913 DebugTrace(-1, Dbg, "FsRtlLookupLastLargeMcbEntryAndIndex -> %08lx\n", Result ); 01914 } 01915 01916 ((PLARGE_INTEGER)LargeVbn)->HighPart = (*((PULONG)LargeVbn) == UNUSED_LBN ? UNUSED_LBN : 0); 01917 ((PLARGE_INTEGER)LargeLbn)->HighPart = (*((PULONG)LargeLbn) == UNUSED_LBN ? UNUSED_LBN : 0); 01918 01919 return Result; 01920 }

NTKERNELAPI BOOLEAN FsRtlLookupLastMcbEntry IN PMCB  Mcb,
OUT PVBN  Vbn,
OUT PLBN  Lbn
 

Definition at line 455 of file largemcb.c.

References FsRtlLookupLastLargeMcbEntry(), and PAGED_CODE.

Referenced by UdfAddVmcbMapping().

00461 { 00462 BOOLEAN Results; 00463 LONGLONG LiVbn; 00464 LONGLONG LiLbn; 00465 00466 PAGED_CODE(); 00467 00468 Results = FsRtlLookupLastLargeMcbEntry( (PLARGE_MCB)Mcb, 00469 &LiVbn, 00470 &LiLbn ); 00471 00472 *Vbn = ((ULONG)LiVbn); 00473 *Lbn = (((ULONG)LiLbn) == -1 ? 0 : ((ULONG)LiLbn)); 00474 00475 return Results; 00476 }

NTKERNELAPI BOOLEAN FsRtlLookupMcbEntry IN PMCB  Mcb,
IN VBN  Vbn,
OUT PLBN  Lbn,
OUT PULONG SectorCount  OPTIONAL,
OUT PULONG  Index
 

Definition at line 426 of file largemcb.c.

References FsRtlLookupLargeMcbEntry(), Index, and NULL.

00434 { 00435 BOOLEAN Results; 00436 LONGLONG LiLbn; 00437 LONGLONG LiSectorCount; 00438 00439 Results = FsRtlLookupLargeMcbEntry( (PLARGE_MCB)Mcb, 00440 (LONGLONG)(Vbn), 00441 &LiLbn, 00442 ARGUMENT_PRESENT(SectorCount) ? &LiSectorCount : NULL, 00443 NULL, 00444 NULL, 00445 Index ); 00446 00447 *Lbn = (((ULONG)LiLbn) == -1 ? 0 : ((ULONG)LiLbn)); 00448 00449 if (ARGUMENT_PRESENT(SectorCount)) { *SectorCount = ((ULONG)LiSectorCount); } 00450 00451 return Results; 00452 }

NTKERNELAPI BOOLEAN FsRtlMdlRead IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus
 

Definition at line 1277 of file fastio.c.

References _DEVICE_OBJECT::DriverObject, FALSE, FAST_IO_DISPATCH, _DRIVER_OBJECT::FastIoDispatch, FsRtlMdlReadDev(), IoGetBaseFileSystemDeviceObject(), IoGetRelatedDeviceObject(), _FAST_IO_DISPATCH::MdlRead, NULL, and _FAST_IO_DISPATCH::SizeOfFastIoDispatch.

01288 : 01289 01290 This routine does a fast cached mdl read bypassing the usual file system 01291 entry routine (i.e., without the Irp). It is used to do a copy read 01292 of a cached file object. For a complete description of the arguments 01293 see CcMdlRead. 01294 01295 Arguments: 01296 01297 FileObject - Pointer to the file object being read. 01298 01299 FileOffset - Byte offset in file for desired data. 01300 01301 Length - Length of desired data in bytes. 01302 01303 MdlChain - On output it returns a pointer to an MDL chain describing 01304 the desired data. 01305 01306 IoStatus - Pointer to standard I/O status block to receive the status 01307 for the transfer. 01308 01309 Return Value: 01310 01311 FALSE - if the data was not delivered, or if there is an I/O error. 01312 01313 TRUE - if the data is being delivered 01314 01315 --*/ 01316 01317 { 01318 PDEVICE_OBJECT DeviceObject, VolumeDeviceObject; 01319 PFAST_IO_DISPATCH FastIoDispatch; 01320 01321 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 01322 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 01323 01324 // 01325 // See if the (top-level) FileSystem has a FastIo routine, and if so, call it. 01326 // 01327 01328 if ((FastIoDispatch != NULL) && 01329 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlRead)) && 01330 (FastIoDispatch->MdlRead != NULL)) { 01331 01332 return FastIoDispatch->MdlRead( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject ); 01333 01334 } else { 01335 01336 // 01337 // Get the DeviceObject for the volume. If that DeviceObject is different, and 01338 // it specifies the FastIo routine, then we have to return FALSE here and cause 01339 // an Irp to get generated. 01340 // 01341 01342 VolumeDeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 01343 if ((VolumeDeviceObject != DeviceObject) && 01344 (FastIoDispatch = VolumeDeviceObject->DriverObject->FastIoDispatch) && 01345 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlRead)) && 01346 (FastIoDispatch->MdlRead != NULL)) { 01347 01348 return FALSE; 01349 01350 // 01351 // Otherwise, call the default routine. 01352 // 01353 01354 } else { 01355 01356 return FsRtlMdlReadDev( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject ); 01357 } 01358 } 01359 }

BOOLEAN FsRtlMdlReadComplete IN PFILE_OBJECT  FileObject,
IN PMDL  MdlChain
 

Definition at line 1367 of file fastio.c.

References _DEVICE_OBJECT::DriverObject, FALSE, _DRIVER_OBJECT::FastIoDispatch, FsRtlMdlReadCompleteDev(), IoGetBaseFileSystemDeviceObject(), IoGetRelatedDeviceObject(), _FAST_IO_DISPATCH::MdlReadComplete, NULL, and _FAST_IO_DISPATCH::SizeOfFastIoDispatch.

01374 : 01375 01376 This routine does a fast cached mdl read bypassing the usual file system 01377 entry routine (i.e., without the Irp). It is used to do a copy read 01378 of a cached file object. 01379 01380 Arguments: 01381 01382 FileObject - Pointer to the file object being read. 01383 01384 MdlChain - Supplies a pointer to an MDL chain returned from CcMdlRead. 01385 01386 Return Value: 01387 01388 None 01389 01390 --*/ 01391 01392 { 01393 PDEVICE_OBJECT DeviceObject, VolumeDeviceObject; 01394 PFAST_IO_DISPATCH FastIoDispatch; 01395 01396 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 01397 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 01398 01399 // 01400 // See if the (top-level) FileSystem has a FastIo routine, and if so, call it. 01401 // 01402 01403 if ((FastIoDispatch != NULL) && 01404 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlReadComplete)) && 01405 (FastIoDispatch->MdlReadComplete != NULL)) { 01406 01407 return FastIoDispatch->MdlReadComplete( FileObject, MdlChain, DeviceObject ); 01408 01409 } else { 01410 01411 // 01412 // Get the DeviceObject for the volume. If that DeviceObject is different, and 01413 // it specifies the FastIo routine, then we have to return FALSE here and cause 01414 // an Irp to get generated. 01415 // 01416 01417 VolumeDeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 01418 if ((VolumeDeviceObject != DeviceObject) && 01419 (FastIoDispatch = VolumeDeviceObject->DriverObject->FastIoDispatch) && 01420 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlReadComplete)) && 01421 (FastIoDispatch->MdlReadComplete != NULL)) { 01422 01423 return FALSE; 01424 01425 // 01426 // Otherwise, call the default routine. 01427 // 01428 01429 } else { 01430 01431 return FsRtlMdlReadCompleteDev( FileObject, MdlChain, DeviceObject ); 01432 } 01433 } 01434 }

NTKERNELAPI BOOLEAN FsRtlMdlReadCompleteDev IN PFILE_OBJECT  FileObject,
IN PMDL  MdlChain,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 1438 of file fastio.c.

References CcMdlReadComplete2(), and TRUE.

Referenced by FsRtlMdlReadComplete().

01446 : 01447 01448 This routine does a fast cached mdl read bypassing the usual file system 01449 entry routine (i.e., without the Irp). It is used to do a copy read 01450 of a cached file object. 01451 01452 Arguments: 01453 01454 FileObject - Pointer to the file object being read. 01455 01456 MdlChain - Supplies a pointer to an MDL chain returned from CcMdlRead. 01457 01458 DeviceObject - Supplies the DeviceObject for the callee. 01459 01460 Return Value: 01461 01462 None 01463 01464 --*/ 01465 01466 01467 { 01468 CcMdlReadComplete2( FileObject, MdlChain ); 01469 return TRUE; 01470 }

NTKERNELAPI BOOLEAN FsRtlMdlReadDev IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 1064 of file fastio.c.

References ASSERT, CcFastMdlReadNotPossible, CcFastMdlReadWait, CcMdlRead(), _DEVICE_OBJECT::DriverObject, ExAcquireResourceShared, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, ExReleaseResource, FALSE, _FAST_IO_DISPATCH::FastIoCheckIfPossible, _DRIVER_OBJECT::FastIoDispatch, FastIoIsNotPossible, FastIoIsQuestionable, FO_FILE_FAST_IO_READ, FSRTL_FAST_IO_TOP_LEVEL_IRP, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlIsNtstatusExpected(), Header, IoGetRelatedDeviceObject(), NULL, PAGED_CODE, PsGetCurrentThread, Status, TRUE, and VOID().

Referenced by FsRtlMdlRead().

01076 : 01077 01078 This routine does a fast cached mdl read bypassing the usual file system 01079 entry routine (i.e., without the Irp). It is used to do a copy read 01080 of a cached file object. For a complete description of the arguments 01081 see CcMdlRead. 01082 01083 Arguments: 01084 01085 FileObject - Pointer to the file object being read. 01086 01087 FileOffset - Byte offset in file for desired data. 01088 01089 Length - Length of desired data in bytes. 01090 01091 MdlChain - On output it returns a pointer to an MDL chain describing 01092 the desired data. 01093 01094 IoStatus - Pointer to standard I/O status block to receive the status 01095 for the transfer. 01096 01097 DeviceObject - Supplies DeviceObject for callee. 01098 01099 Return Value: 01100 01101 FALSE - if the data was not delivered, or if there is an I/O error. 01102 01103 TRUE - if the data is being delivered 01104 01105 --*/ 01106 01107 { 01108 PFSRTL_COMMON_FCB_HEADER Header; 01109 BOOLEAN Status = TRUE; 01110 LARGE_INTEGER BeyondLastByte; 01111 01112 PAGED_CODE(); 01113 01114 // 01115 // Special case a read of zero length 01116 // 01117 01118 if (Length == 0) { 01119 01120 IoStatus->Status = STATUS_SUCCESS; 01121 IoStatus->Information = 0; 01122 01123 return TRUE; 01124 } 01125 01126 // 01127 // Overflows should've been handled by caller. 01128 // 01129 01130 ASSERT(MAXLONGLONG - FileOffset->QuadPart >= (LONGLONG)Length); 01131 01132 01133 // 01134 // Get a real pointer to the common fcb header 01135 // 01136 01137 BeyondLastByte.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 01138 Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 01139 01140 // 01141 // Enter the file system 01142 // 01143 01144 FsRtlEnterFileSystem(); 01145 01146 CcFastMdlReadWait += 1; 01147 01148 // 01149 // Acquired shared on the common fcb header 01150 // 01151 01152 (VOID)ExAcquireResourceShared( Header->Resource, TRUE ); 01153 01154 // 01155 // Now that the File is acquired shared, we can safely test if it is 01156 // really cached and if we can do fast i/o and if not 01157 // then release the fcb and return. 01158 // 01159 01160 if ((FileObject->PrivateCacheMap == NULL) || 01161 (Header->IsFastIoPossible == FastIoIsNotPossible)) { 01162 01163 ExReleaseResource( Header->Resource ); 01164 FsRtlExitFileSystem(); 01165 01166 CcFastMdlReadNotPossible += 1; 01167 01168 return FALSE; 01169 } 01170 01171 // 01172 // Check if fast I/O is questionable and if so then go ask the file system 01173 // the answer 01174 // 01175 01176 if (Header->IsFastIoPossible == FastIoIsQuestionable) { 01177 01178 PFAST_IO_DISPATCH FastIoDispatch; 01179 01180 ASSERT(!KeIsExecutingDpc()); 01181 01182 FastIoDispatch = IoGetRelatedDeviceObject( FileObject )->DriverObject->FastIoDispatch; 01183 01184 01185 // 01186 // All file system then set "Is Questionable" had better support fast I/O 01187 // 01188 01189 ASSERT(FastIoDispatch != NULL); 01190 ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); 01191 01192 // 01193 // Call the file system to check for fast I/O. If the answer is anything 01194 // other than GoForIt then we cannot take the fast I/O path. 01195 // 01196 01197 if (!FastIoDispatch->FastIoCheckIfPossible( FileObject, 01198 FileOffset, 01199 Length, 01200 TRUE, 01201 LockKey, 01202 TRUE, // read operation 01203 IoStatus, 01204 IoGetRelatedDeviceObject( FileObject ) )) { 01205 01206 // 01207 // Fast I/O is not possible so release the Fcb and return. 01208 // 01209 01210 ExReleaseResource( Header->Resource ); 01211 FsRtlExitFileSystem(); 01212 01213 CcFastMdlReadNotPossible += 1; 01214 01215 return FALSE; 01216 } 01217 } 01218 01219 // 01220 // Check for read past file size. 01221 // 01222 01223 if ( BeyondLastByte.QuadPart > Header->FileSize.QuadPart ) { 01224 01225 if ( FileOffset->QuadPart >= Header->FileSize.QuadPart ) { 01226 IoStatus->Status = STATUS_END_OF_FILE; 01227 IoStatus->Information = 0; 01228 01229 ExReleaseResource( Header->Resource ); 01230 FsRtlExitFileSystem(); 01231 01232 return TRUE; 01233 } 01234 01235 Length = (ULONG)( Header->FileSize.QuadPart - FileOffset->QuadPart ); 01236 } 01237 01238 // 01239 // We can do fast i/o so call the cc routine to do the work and then 01240 // release the fcb when we've done. If for whatever reason the 01241 // mdl read fails, then return FALSE to our caller. 01242 // 01243 // 01244 // Also mark this as the top level "Irp" so that lower file system levels 01245 // will not attempt a pop-up 01246 // 01247 01248 PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; 01249 01250 try { 01251 01252 CcMdlRead( FileObject, FileOffset, Length, MdlChain, IoStatus ); 01253 01254 FileObject->Flags |= FO_FILE_FAST_IO_READ; 01255 01256 } except( FsRtlIsNtstatusExpected(GetExceptionCode()) 01257 ? EXCEPTION_EXECUTE_HANDLER 01258 : EXCEPTION_CONTINUE_SEARCH ) { 01259 01260 Status = FALSE; 01261 } 01262 01263 PsGetCurrentThread()->TopLevelIrp = 0; 01264 01265 ExReleaseResource( Header->Resource ); 01266 FsRtlExitFileSystem(); 01267 01268 return Status; 01269 }

BOOLEAN FsRtlMdlWriteComplete IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PMDL  MdlChain
 

Definition at line 1950 of file fastio.c.

References _DEVICE_OBJECT::DriverObject, FALSE, _DRIVER_OBJECT::FastIoDispatch, FsRtlMdlWriteCompleteDev(), IoGetBaseFileSystemDeviceObject(), IoGetRelatedDeviceObject(), _FAST_IO_DISPATCH::MdlWriteComplete, NULL, and _FAST_IO_DISPATCH::SizeOfFastIoDispatch.

01958 : 01959 01960 This routine completes an Mdl write. 01961 01962 Arguments: 01963 01964 FileObject - Pointer to the file object being read. 01965 01966 MdlChain - Supplies a pointer to an MDL chain returned from CcMdlPrepareMdlWrite. 01967 01968 Return Value: 01969 01970 01971 01972 --*/ 01973 01974 { 01975 PDEVICE_OBJECT DeviceObject, VolumeDeviceObject; 01976 PFAST_IO_DISPATCH FastIoDispatch; 01977 01978 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 01979 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 01980 01981 // 01982 // See if the (top-level) FileSystem has a FastIo routine, and if so, call it. 01983 // 01984 01985 if ((FastIoDispatch != NULL) && 01986 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlWriteComplete)) && 01987 (FastIoDispatch->MdlWriteComplete != NULL)) { 01988 01989 return FastIoDispatch->MdlWriteComplete( FileObject, FileOffset, MdlChain, DeviceObject ); 01990 01991 } else { 01992 01993 // 01994 // Get the DeviceObject for the volume. If that DeviceObject is different, and 01995 // it specifies the FastIo routine, then we have to return FALSE here and cause 01996 // an Irp to get generated. 01997 // 01998 01999 VolumeDeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02000 if ((VolumeDeviceObject != DeviceObject) && 02001 (FastIoDispatch = VolumeDeviceObject->DriverObject->FastIoDispatch) && 02002 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, MdlWriteComplete)) && 02003 (FastIoDispatch->MdlWriteComplete != NULL)) { 02004 02005 return FALSE; 02006 02007 // 02008 // Otherwise, call the default routine. 02009 // 02010 02011 } else { 02012 02013 return FsRtlMdlWriteCompleteDev( FileObject, FileOffset, MdlChain, DeviceObject ); 02014 } 02015 } 02016 }

NTKERNELAPI BOOLEAN FsRtlMdlWriteCompleteDev IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PMDL  MdlChain,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 2020 of file fastio.c.

References CcMdlWriteComplete2(), FALSE, FlagOn, FO_WRITE_THROUGH, and TRUE.

Referenced by FsRtlMdlWriteComplete().

02029 : 02030 02031 This routine completes an Mdl write. 02032 02033 Arguments: 02034 02035 FileObject - Pointer to the file object being read. 02036 02037 MdlChain - Supplies a pointer to an MDL chain returned from CcMdlPrepareMdlWrite. 02038 02039 DeviceObject - Supplies the DeviceObject for the callee. 02040 02041 Return Value: 02042 02043 02044 02045 --*/ 02046 02047 02048 { 02049 // 02050 // Do not support WRITE_THROUGH in the fast path call. 02051 // 02052 02053 if (FlagOn( FileObject->Flags, FO_WRITE_THROUGH )) { 02054 return FALSE; 02055 } 02056 02057 CcMdlWriteComplete2( FileObject, FileOffset, MdlChain ); 02058 return TRUE; 02059 }

NTKERNELAPI NTSTATUS FsRtlNormalizeNtstatus IN NTSTATUS  Exception,
IN NTSTATUS  GenericException
 

Definition at line 49 of file fsrtl/filter.c.

References FsRtlIsNtstatusExpected().

Referenced by CcCopyRead(), CcCopyWrite(), CcFastCopyRead(), CcFastCopyWrite(), CcGetVacbMiss(), CcInitializeCacheMap(), CcMapAndCopy(), CcMdlWriteComplete2(), CcSetFileSizes(), UdfCommonRead(), and UdfNormalizeAndRaiseStatus().

00056 : 00057 00058 This routine is used to normalize an NTSTATUS into a status 00059 that is handled by the file system's top level exception handlers. 00060 00061 Arguments: 00062 00063 Exception - Supplies the exception being normalized 00064 00065 GenericException - Supplies a second exception to translate to 00066 if the first exception is not within the set of exceptions 00067 handled by the filter 00068 00069 Return Value: 00070 00071 NTSTATUS - Returns Exception if the value is already handled 00072 by the filter, and GenericException otherwise. 00073 00074 --*/ 00075 00076 { 00077 return (FsRtlIsNtstatusExpected(Exception) ? Exception : GenericException); 00078 }

NTKERNELAPI VOID FsRtlNotifyChangeDirectory IN PNOTIFY_SYNC  NotifySync,
IN PVOID  FsContext,
IN PSTRING  FullDirectoryName,
IN PLIST_ENTRY  NotifyList,
IN BOOLEAN  WatchTree,
IN ULONG  CompletionFilter,
IN PIRP  NotifyIrp
 

Definition at line 469 of file notify.c.

References Dbg, DebugTrace, FsRtlNotifyFullChangeDirectory(), NULL, PAGED_CODE, TRUE, and WatchTree.

00481 : 00482 00483 This routine is called by a file system which has received a NotifyChange 00484 request. This routine checks if there is already a notify structure and 00485 inserts one if not present. With a notify structure in hand, we check 00486 whether we already have a pending notify and report it if so. If there 00487 is no pending notify, we check if this Irp has already been cancelled and 00488 completes it if so. Otherwise we add this to the list of Irps waiting 00489 for notification. 00490 00491 Arguments: 00492 00493 NotifySync - This is the controlling fast mutex for this notify list. 00494 It is stored here so that it can be found for an Irp which is being 00495 cancelled. 00496 00497 FsContext - This is supplied by the file system so that this notify 00498 structure can be uniquely identified. 00499 00500 FullDirectoryName - Points to the full name for the directory associated 00501 with this notify structure. 00502 00503 NotifyList - This is the start of the notify list to add this 00504 structure to. 00505 00506 WatchTree - This indicates whether all subdirectories for this directory 00507 should be watched, or just the directory itself. 00508 00509 CompletionFilter - This provides the mask to determine which operations 00510 will trigger the notify operations. 00511 00512 NotifyIrp - This is the Irp to complete on notify change. 00513 00514 Return Value: 00515 00516 None. 00517 00518 --*/ 00519 00520 { 00521 PAGED_CODE(); 00522 00523 DebugTrace( +1, Dbg, "FsRtlNotifyChangeDirectory: Entered\n", 0 ); 00524 00525 // 00526 // We will simply call the full notify routine to do the real work. 00527 // 00528 00529 FsRtlNotifyFullChangeDirectory( NotifySync, 00530 NotifyList, 00531 FsContext, 00532 FullDirectoryName, 00533 WatchTree, 00534 TRUE, 00535 CompletionFilter, 00536 NotifyIrp, 00537 NULL, 00538 NULL ); 00539 00540 DebugTrace( -1, Dbg, "FsRtlNotifyChangeDirectory: Exit\n", 0 ); 00541 00542 return; 00543 }

NTKERNELAPI VOID FsRtlNotifyCleanup IN PNOTIFY_SYNC  NotifySync,
IN PLIST_ENTRY  NotifyList,
IN PVOID  FsContext
 

Definition at line 1795 of file notify.c.

References AcquireNotifySync, _NOTIFY_CHANGE::AllocatedBuffer, Dbg, DebugTrace, ExFreePool(), _NOTIFY_CHANGE::Flags, FsRtlIsNotifyOnList(), FsRtlNotifyCompleteIrpList(), _NOTIFY_CHANGE::FullDirectoryName, NOTIFY_CLEANUP_CALLED, _NOTIFY_CHANGE::NotifyIrps, _NOTIFY_CHANGE::NotifyList, NULL, _NOTIFY_CHANGE::OwningProcess, PAGED_CODE, PagedPool, PNOTIFY_CHANGE, PsReturnPoolQuota(), _NOTIFY_CHANGE::ReferenceCount, ReleaseNotifySync, SeReleaseSubjectContext(), SetFlag, _NOTIFY_CHANGE::SubjectContext, and _NOTIFY_CHANGE::ThisBufferLength.

Referenced by UdfCommonCleanup().

01803 : 01804 01805 This routine is called for a cleanup of a user directory handle. We 01806 walk through our notify structures looking for a matching context field. 01807 We complete all the pending notify Irps for this Notify structure, remove 01808 the notify structure and deallocate it. 01809 01810 Arguments: 01811 01812 NotifySync - This is the controlling fast mutex for this notify list. 01813 It is stored here so that it can be found for an Irp which is being 01814 cancelled. 01815 01816 NotifyList - This is the start of the notify list to add this 01817 structure to. 01818 01819 FsContext - This is a unique value assigned by the file system to 01820 identify a particular notify structure. 01821 01822 Return Value: 01823 01824 None. 01825 01826 --*/ 01827 01828 { 01829 PNOTIFY_CHANGE Notify; 01830 PSECURITY_SUBJECT_CONTEXT SubjectContext = NULL; 01831 01832 PAGED_CODE(); 01833 01834 DebugTrace( +1, Dbg, "FsRtlNotifyCleanup: Entered\n", 0 ); 01835 DebugTrace( 0, Dbg, "Mutex -> %08lx\n", Mutex ); 01836 DebugTrace( 0, Dbg, "Notify List -> %08lx\n", NotifyList ); 01837 DebugTrace( 0, Dbg, "FsContext -> %08lx\n", FsContext ); 01838 01839 // 01840 // Acquire exclusive access to the list by acquiring the mutex. 01841 // 01842 01843 AcquireNotifySync( NotifySync ); 01844 01845 // 01846 // Use a try-finally to facilitate cleanup. 01847 // 01848 01849 try { 01850 01851 // 01852 // Search for a match on the list. 01853 // 01854 01855 Notify = FsRtlIsNotifyOnList( NotifyList, FsContext ); 01856 01857 // 01858 // If found, then complete all the Irps with STATUS_NOTIFY_CLEANUP 01859 // 01860 01861 if (Notify != NULL) { 01862 01863 // 01864 // Set the flag to indicate that we have been called with cleanup. 01865 // 01866 01867 SetFlag( Notify->Flags, NOTIFY_CLEANUP_CALLED ); 01868 01869 if (!IsListEmpty( &Notify->NotifyIrps )) { 01870 01871 FsRtlNotifyCompleteIrpList( Notify, STATUS_NOTIFY_CLEANUP ); 01872 } 01873 01874 RemoveEntryList( &Notify->NotifyList ); 01875 01876 InterlockedDecrement( &Notify->ReferenceCount ); 01877 01878 if (Notify->ReferenceCount == 0) { 01879 01880 if (Notify->AllocatedBuffer != NULL) { 01881 01882 PsReturnPoolQuota( Notify->OwningProcess, 01883 PagedPool, 01884 Notify->ThisBufferLength ); 01885 01886 ExFreePool( Notify->AllocatedBuffer ); 01887 } 01888 01889 if (Notify->FullDirectoryName != NULL) { 01890 01891 SubjectContext = Notify->SubjectContext; 01892 } 01893 01894 ExFreePool( Notify ); 01895 } 01896 } 01897 01898 } finally { 01899 01900 ReleaseNotifySync( NotifySync ); 01901 01902 if (SubjectContext != NULL) { 01903 01904 SeReleaseSubjectContext( SubjectContext ); 01905 ExFreePool( SubjectContext ); 01906 } 01907 01908 DebugTrace( -1, Dbg, "FsRtlNotifyCleanup: Exit\n", 0 ); 01909 } 01910 01911 return; 01912 }

NTKERNELAPI VOID FsRtlNotifyFullChangeDirectory IN PNOTIFY_SYNC  NotifySync,
IN PLIST_ENTRY  NotifyList,
IN PVOID  FsContext,
IN PSTRING  FullDirectoryName,
IN BOOLEAN  WatchTree,
IN BOOLEAN  IgnoreBuffer,
IN ULONG  CompletionFilter,
IN PIRP  NotifyIrp,
IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback  OPTIONAL,
IN PSECURITY_SUBJECT_CONTEXT SubjectContext  OPTIONAL
 

Definition at line 547 of file notify.c.

References AcquireNotifySync, _NOTIFY_CHANGE::BufferLength, CHAR, _NOTIFY_CHANGE::CharacterSize, ClearFlag, _NOTIFY_CHANGE::CompletionFilter, _NOTIFY_CHANGE::DataLength, Dbg, DebugTrace, ExFreePool(), FALSE, _IO_STACK_LOCATION::FileObject, FlagOn, _NOTIFY_CHANGE::Flags, _FILE_OBJECT::Flags, FO_CLEANUP_COMPLETE, _FILE_OBJECT::FsContext, _NOTIFY_CHANGE::FsContext, FsRtlCheckNotifyForDelete(), FsRtlCompleteRequest, FsRtlIsNotifyOnList(), FsRtlNotifyCompleteIrp(), FsRtlNotifySetCancelRoutine(), FsRtlpAllocatePool, _NOTIFY_CHANGE::FullDirectoryName, IoGetCurrentIrpStackLocation, IoMarkIrpPending, _NOTIFY_CHANGE::LastEntry, NOTIFY_CHANGE, NOTIFY_CLEANUP_CALLED, NOTIFY_DEFER_NOTIFY, NOTIFY_DIR_IS_ROOT, NOTIFY_IMMEDIATE_NOTIFY, NOTIFY_STREAM_IS_DELETED, NOTIFY_WATCH_TREE, _NOTIFY_CHANGE::NotifyIrps, _NOTIFY_CHANGE::NotifyList, _NOTIFY_CHANGE::NotifySync, NULL, _NOTIFY_CHANGE::OwningProcess, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, PNOTIFY_CHANGE, PREAL_NOTIFY_SYNC, _NOTIFY_CHANGE::ReferenceCount, ReleaseNotifySync, SeReleaseSubjectContext(), SetFlag, _NOTIFY_CHANGE::StreamID, _NOTIFY_CHANGE::SubjectContext, THREAD_TO_PROCESS, _NOTIFY_CHANGE::TraverseCallback, try_return, and WatchTree.

Referenced by FsRtlNotifyChangeDirectory(), and UdfNotifyChangeDirectory().

00562 : 00563 00564 This routine is called by a file system which has received a NotifyChange 00565 request. This routine checks if there is already a notify structure and 00566 inserts one if not present. With a notify structure in hand, we check 00567 whether we already have a pending notify and report it if so. If there 00568 is no pending notify, we check if this Irp has already been cancelled and 00569 completes it if so. Otherwise we add this to the list of Irps waiting 00570 for notification. 00571 00572 This is the version of this routine which understands about the user's 00573 buffer and will fill it in on a reported change. 00574 00575 Arguments: 00576 00577 NotifySync - This is the controlling fast mutex for this notify list. 00578 It is stored here so that it can be found for an Irp which is being 00579 cancelled. 00580 00581 NotifyList - This is the start of the notify list to add this 00582 structure to. 00583 00584 FsContext - This is supplied by the file system so that this notify 00585 structure can be uniquely identified. If the NotifyIrp is not specified 00586 then this is used to identify the stream and it will match the FsContext 00587 field in the file object of a stream being deleted. 00588 00589 FullDirectoryName - Points to the full name for the directory associated 00590 with this notify structure. Ignored if the NotifyIrp is not specified. 00591 00592 WatchTree - This indicates whether all subdirectories for this directory 00593 should be watched, or just the directory itself. Ignored if the 00594 NotifyIrp is not specified. 00595 00596 IgnoreBuffer - Indicates whether we will always ignore any user buffer 00597 and force the directory to be reenumerated. This will speed up the 00598 operation. Ignored if the NotifyIrp is not specified. 00599 00600 CompletionFilter - This provides the mask to determine which operations 00601 will trigger the notify operations. Ignored if the NotifyIrp is not 00602 specified. 00603 00604 NotifyIrp - This is the Irp to complete on notify change. If this irp is 00605 not specified it means that the stream represented by this file object 00606 is being deleted. 00607 00608 TraverseCallback - If specified we must call this routine when a change 00609 has occurred in a subdirectory being watched in a tree. This will 00610 let the filesystem check if the watcher has traverse access to that 00611 directory. Ignored if the NotifyIrp is not specified. 00612 00613 SubjectContext - If there is a traverse callback routine then we will 00614 pass this subject context as a parameter to the call. We will release 00615 the context and free the structure when done with it. Ignored if the 00616 NotifyIrp is not specified. 00617 00618 Return Value: 00619 00620 None. 00621 00622 --*/ 00623 00624 { 00625 PNOTIFY_CHANGE Notify; 00626 PIO_STACK_LOCATION IrpSp; 00627 00628 PAGED_CODE(); 00629 00630 DebugTrace( +1, Dbg, "FsRtlNotifyFullChangeDirectory: Entered\n", 0 ); 00631 00632 // 00633 // Acquire exclusive access to the list by acquiring the mutex. 00634 // 00635 00636 AcquireNotifySync( NotifySync ); 00637 00638 // 00639 // Use a try-finally to facilitate cleanup. 00640 // 00641 00642 try { 00643 00644 // 00645 // If there is no Irp then find all of the pending Irps whose file objects 00646 // refer to the same stream and complete them with STATUS_DELETE_PENDING. 00647 // 00648 00649 if (NotifyIrp == NULL) { 00650 00651 FsRtlCheckNotifyForDelete( NotifyList, FsContext ); 00652 try_return( NOTHING ); 00653 } 00654 00655 // 00656 // Get the current Stack location 00657 // 00658 00659 IrpSp = IoGetCurrentIrpStackLocation( NotifyIrp ); 00660 00661 // 00662 // Clear the Iosb in the Irp. 00663 // 00664 00665 NotifyIrp->IoStatus.Status = STATUS_SUCCESS; 00666 NotifyIrp->IoStatus.Information = 0; 00667 00668 // 00669 // If the file object has already gone through cleanup, then complete 00670 // the request immediately. 00671 // 00672 00673 if (FlagOn( IrpSp->FileObject->Flags, FO_CLEANUP_COMPLETE )) { 00674 00675 // 00676 // Always mark this Irp as pending returned. 00677 // 00678 00679 IoMarkIrpPending( NotifyIrp ); 00680 00681 FsRtlCompleteRequest( NotifyIrp, STATUS_NOTIFY_CLEANUP ); 00682 try_return( NOTHING ); 00683 } 00684 00685 // 00686 // If the notify structure is not already in the list, add it 00687 // now. 00688 // 00689 00690 Notify = FsRtlIsNotifyOnList( NotifyList, FsContext ); 00691 00692 if (Notify == NULL) { 00693 00694 // 00695 // Allocate and initialize the structure. 00696 // 00697 00698 Notify = FsRtlpAllocatePool( PagedPool, sizeof( NOTIFY_CHANGE )); 00699 RtlZeroMemory( Notify, sizeof( NOTIFY_CHANGE )); 00700 00701 Notify->NotifySync = (PREAL_NOTIFY_SYNC) NotifySync; 00702 Notify->FsContext = FsContext; 00703 Notify->StreamID = IrpSp->FileObject->FsContext; 00704 00705 Notify->TraverseCallback = TraverseCallback; 00706 Notify->SubjectContext = SubjectContext; 00707 SubjectContext = NULL; 00708 00709 Notify->FullDirectoryName = FullDirectoryName; 00710 00711 InitializeListHead( &Notify->NotifyIrps ); 00712 00713 if (WatchTree) { 00714 00715 SetFlag( Notify->Flags, NOTIFY_WATCH_TREE ); 00716 } 00717 00718 if (FullDirectoryName == NULL) { 00719 00720 // 00721 // In the view index we aren't using this buffer to hold a 00722 // unicode string. 00723 // 00724 00725 Notify->CharacterSize = sizeof( CHAR ); 00726 00727 } else { 00728 00729 // 00730 // We look at the directory name to decide if we have a unicode 00731 // name. 00732 // 00733 00734 if (FullDirectoryName->Length >= 2 00735 && FullDirectoryName->Buffer[1] == '\0') { 00736 00737 Notify->CharacterSize = sizeof( WCHAR ); 00738 00739 } else { 00740 00741 Notify->CharacterSize = sizeof( CHAR ); 00742 } 00743 00744 if (FullDirectoryName->Length == Notify->CharacterSize) { 00745 00746 SetFlag( Notify->Flags, NOTIFY_DIR_IS_ROOT ); 00747 } 00748 } 00749 00750 Notify->CompletionFilter = CompletionFilter; 00751 00752 // 00753 // If we are to return data to the user then look for the length 00754 // of the original buffer in the IrpSp. 00755 // 00756 00757 if (!IgnoreBuffer) { 00758 00759 Notify->BufferLength = IrpSp->Parameters.NotifyDirectory.Length; 00760 } 00761 00762 Notify->OwningProcess = THREAD_TO_PROCESS( NotifyIrp->Tail.Overlay.Thread ); 00763 InsertTailList( NotifyList, &Notify->NotifyList ); 00764 00765 Notify->ReferenceCount = 1; 00766 00767 // 00768 // If we have already been called with cleanup then complete 00769 // the request immediately. 00770 // 00771 00772 } else if (FlagOn( Notify->Flags, NOTIFY_CLEANUP_CALLED )) { 00773 00774 // 00775 // Always mark this Irp as pending returned. 00776 // 00777 00778 IoMarkIrpPending( NotifyIrp ); 00779 00780 FsRtlCompleteRequest( NotifyIrp, STATUS_NOTIFY_CLEANUP ); 00781 try_return( NOTHING ); 00782 00783 // 00784 // If this file has been deleted then complete with STATUS_DELETE_PENDING. 00785 // 00786 00787 } else if (FlagOn( Notify->Flags, NOTIFY_STREAM_IS_DELETED )) { 00788 00789 // 00790 // Always mark this Irp as pending returned. 00791 // 00792 00793 IoMarkIrpPending( NotifyIrp ); 00794 00795 FsRtlCompleteRequest( NotifyIrp, STATUS_DELETE_PENDING ); 00796 try_return( NOTHING ); 00797 00798 // 00799 // If the notify pending flag is set or there is data in an internal buffer 00800 // we complete this Irp immediately and exit. 00801 // 00802 00803 } else if (FlagOn( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ) 00804 && !FlagOn( Notify->Flags, NOTIFY_DEFER_NOTIFY )) { 00805 00806 DebugTrace( 0, Dbg, "Notify has been pending\n", 0 ); 00807 00808 // 00809 // Clear the flag in our notify structure before completing the 00810 // Irp. This will prevent a caller who reposts in his completion 00811 // routine from looping in the completion routine. 00812 // 00813 00814 ClearFlag( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ); 00815 00816 // 00817 // Always mark this Irp as pending returned. 00818 // 00819 00820 IoMarkIrpPending( NotifyIrp ); 00821 00822 FsRtlCompleteRequest( NotifyIrp, STATUS_NOTIFY_ENUM_DIR ); 00823 try_return( NOTHING ); 00824 00825 } else if (Notify->DataLength != 0 00826 && !FlagOn( Notify->Flags, NOTIFY_DEFER_NOTIFY )) { 00827 00828 ULONG ThisDataLength = Notify->DataLength; 00829 00830 // 00831 // Now set our buffer pointers back to indicate an empty buffer. 00832 // 00833 00834 Notify->DataLength = 0; 00835 Notify->LastEntry = 0; 00836 00837 FsRtlNotifyCompleteIrp( NotifyIrp, 00838 Notify, 00839 ThisDataLength, 00840 STATUS_SUCCESS, 00841 FALSE ); 00842 00843 try_return( NOTHING ); 00844 } 00845 00846 // 00847 // Add the Irp to the tail of the notify queue. 00848 // 00849 00850 NotifyIrp->IoStatus.Information = (ULONG_PTR) Notify; 00851 IoMarkIrpPending( NotifyIrp ); 00852 InsertTailList( &Notify->NotifyIrps, &NotifyIrp->Tail.Overlay.ListEntry ); 00853 00854 // 00855 // Increment the reference count to indicate that Irp might go through cancel. 00856 // 00857 00858 InterlockedIncrement( &Notify->ReferenceCount ); 00859 00860 // 00861 // Call the routine to set the cancel routine. 00862 // 00863 00864 FsRtlNotifySetCancelRoutine( NotifyIrp, NULL ); 00865 00866 try_exit: NOTHING; 00867 } finally { 00868 00869 // 00870 // Release the mutex. 00871 // 00872 00873 ReleaseNotifySync( NotifySync ); 00874 00875 // 00876 // If there is still a subject context then release it and deallocate 00877 // the structure. Remember that if FullDirectoryName is null, it means 00878 // this is a view index, not a directory index, and the SubjectContext 00879 // is really a piece of file system context information. 00880 // 00881 00882 if ((SubjectContext != NULL) && 00883 (Notify->FullDirectoryName != NULL)) { 00884 00885 SeReleaseSubjectContext( SubjectContext ); 00886 ExFreePool( SubjectContext ); 00887 } 00888 00889 DebugTrace( -1, Dbg, "FsRtlNotifyFullChangeDirectory: Exit\n", 0 ); 00890 } 00891 00892 return; 00893 }

NTKERNELAPI VOID FsRtlNotifyFullReportChange IN PNOTIFY_SYNC  NotifySync,
IN PLIST_ENTRY  NotifyList,
IN PSTRING  FullTargetName,
IN USHORT  TargetNameOffset,
IN PSTRING StreamName  OPTIONAL,
IN PSTRING NormalizedParentName  OPTIONAL,
IN ULONG  FilterMatch,
IN ULONG  Action,
IN PVOID  TargetContext
 

Definition at line 973 of file notify.c.

References AcquireNotifySync, Action, Add2Ptr, _NOTIFY_CHANGE::AllocatedBuffer, ASSERT, ASSERTMSG, _IRP::AssociatedIrp, _NOTIFY_CHANGE::Buffer, _NOTIFY_CHANGE::BufferLength, CHAR, _NOTIFY_CHANGE::CharacterSize, ClearFlag, _NOTIFY_CHANGE::CompletionFilter, _NOTIFY_CHANGE::DataLength, Dbg, DebugTrace, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), FALSE, FileName, FlagOn, _NOTIFY_CHANGE::Flags, _NOTIFY_CHANGE::FsContext, FsRtlIsNtstatusExpected(), FsRtlNotifyCompleteIrpList(), FsRtlNotifyUpdateBuffer(), FsRtlpAllocatePool, _NOTIFY_CHANGE::FullDirectoryName, IoGetCurrentIrpStackLocation, L, _NOTIFY_CHANGE::LastEntry, LongAlign, _IRP::MdlAddress, MmGetSystemAddressForMdl, NOTIFY_DEFER_NOTIFY, NOTIFY_DIR_IS_ROOT, NOTIFY_IMMEDIATE_NOTIFY, NOTIFY_WATCH_TREE, _NOTIFY_CHANGE::NotifyIrps, NULL, _NOTIFY_CHANGE::OwningProcess, PAGED_CODE, PagedPool, _IO_STACK_LOCATION::Parameters, PNOTIFY_CHANGE, PsChargePoolQuota(), PsReturnPoolQuota(), ReleaseNotifySync, SetFlag, _NOTIFY_CHANGE::SubjectContext, _NOTIFY_CHANGE::ThisBufferLength, _NOTIFY_CHANGE::TraverseCallback, TRUE, and USHORT.

Referenced by FsRtlNotifyReportChange().

00987 : 00988 00989 This routine is called by a file system when a file has been modified in 00990 such a way that it will cause a notify change Irp to complete. We walk 00991 through all the notify structures looking for those structures which 00992 would be associated with an ancestor directory of the target file name. 00993 00994 We look for all the notify structures which have a filter match and 00995 then check that the directory name in the notify structure is a 00996 proper prefix of the full target name. 00997 00998 If we find a notify structure which matches the above conditions, we 00999 complete all the Irps for the notify structure. If the structure has 01000 no Irps, we mark the notify pending field. 01001 01002 Arguments: 01003 01004 NotifySync - This is the controlling fast mutex for this notify list. 01005 It is stored here so that it can be found for an Irp which is being 01006 cancelled. 01007 01008 NotifyList - This is the start of the notify list to add this 01009 structure to. 01010 01011 FullTargetName - This is the full name of the file from the root of the volume. 01012 01013 TargetNameOffset - This is the offset in the full name of the final component 01014 of the name. 01015 01016 StreamName - If present then this is the stream name to store with 01017 the filename. 01018 01019 NormalizedParentName - If present this is the same path as the parent name 01020 but the DOS-ONLY names have been replaced with the associated long name. 01021 01022 FilterMatch - This flag field is compared with the completion filter 01023 in the notify structure. If any of the corresponding bits in the 01024 completion filter are set, then a notify condition exists. 01025 01026 Action - This is the action code to store in the user's buffer if 01027 present. 01028 01029 TargetContext - This is one of the context pointers to pass to the file 01030 system if performing a traverse check in the case of a tree being 01031 watched. 01032 01033 Return Value: 01034 01035 None. 01036 01037 --*/ 01038 01039 { 01040 PLIST_ENTRY NotifyLinks; 01041 01042 STRING NormalizedParent; 01043 STRING ParentName; 01044 STRING TargetName; 01045 01046 PNOTIFY_CHANGE Notify; 01047 STRING TargetParent; 01048 PIRP NotifyIrp; 01049 01050 BOOLEAN NotifyIsParent; 01051 BOOLEAN ViewIndex = FALSE; 01052 UCHAR ComponentCount; 01053 ULONG SizeOfEntry; 01054 ULONG CurrentOffset; 01055 ULONG NextEntryOffset; 01056 ULONG ExceptionCode; 01057 01058 PAGED_CODE(); 01059 01060 DebugTrace( +1, Dbg, "FsRtlNotifyFullReportChange: Entered\n", 0 ); 01061 01062 // 01063 // If this is a change to the root directory then return immediately. 01064 // 01065 01066 if ((TargetNameOffset == 0) && (FullTargetName != NULL)) { 01067 01068 DebugTrace( -1, Dbg, "FsRtlNotifyFullReportChange: Exit\n", 0 ); 01069 return; 01070 } 01071 01072 ParentName.Buffer = NULL; 01073 TargetName.Buffer = NULL; 01074 01075 // 01076 // Acquire exclusive access to the list by acquiring the mutex. 01077 // 01078 01079 AcquireNotifySync( NotifySync ); 01080 01081 // 01082 // Use a try-finally to facilitate cleanup. 01083 // 01084 01085 try { 01086 01087 // 01088 // Walk through all the notify blocks. 01089 // 01090 01091 for (NotifyLinks = NotifyList->Flink; 01092 NotifyLinks != NotifyList; 01093 NotifyLinks = NotifyLinks->Flink) { 01094 01095 // 01096 // Obtain the Notify structure from the list entry. 01097 // 01098 01099 Notify = CONTAINING_RECORD( NotifyLinks, NOTIFY_CHANGE, NotifyList ); 01100 01101 // 01102 // The rules for deciding whether this notification applies are 01103 // different for view indices versus file name indices (directories). 01104 // 01105 01106 if (FullTargetName == NULL) { 01107 01108 ASSERTMSG( "Directory notify handle in view index notify list!", Notify->FullDirectoryName == NULL); 01109 01110 // 01111 // Make sure this is the Fcb being watched. 01112 // 01113 01114 if (TargetContext != Notify->SubjectContext) { 01115 01116 continue; 01117 } 01118 01119 TargetParent.Buffer = NULL; 01120 TargetParent.Length = 0; 01121 01122 ViewIndex = TRUE; 01123 01124 // 01125 // Handle the directory case. 01126 // 01127 01128 } else { 01129 01130 ASSERTMSG( "View index notify handle in directory notify list!", Notify->FullDirectoryName != NULL); 01131 01132 // 01133 // If the length of the name in the notify block is currently zero then 01134 // someone is doing a rename and we can skip this block. 01135 // 01136 01137 if (Notify->FullDirectoryName->Length == 0) { 01138 01139 continue; 01140 } 01141 01142 // 01143 // If this filter match is not part of the completion filter then continue. 01144 // 01145 01146 if (!(FilterMatch & Notify->CompletionFilter)) { 01147 01148 continue; 01149 } 01150 01151 // 01152 // If there is no normalized name then set its value from the full 01153 // file name. 01154 // 01155 01156 if (!ARGUMENT_PRESENT( NormalizedParentName )) { 01157 NormalizedParent.Buffer = FullTargetName->Buffer; 01158 NormalizedParent.Length = TargetNameOffset; 01159 01160 if (NormalizedParent.Length != Notify->CharacterSize) { 01161 01162 NormalizedParent.Length -= Notify->CharacterSize; 01163 } 01164 01165 NormalizedParent.MaximumLength = NormalizedParent.Length; 01166 01167 NormalizedParentName = &NormalizedParent; 01168 } 01169 01170 // 01171 // If the length of the directory being watched is longer than the 01172 // parent of the modified file then it can't be an ancestor of the 01173 // modified file. 01174 // 01175 01176 if (Notify->FullDirectoryName->Length > NormalizedParentName->Length) { 01177 01178 continue; 01179 } 01180 01181 // 01182 // If the lengths match exactly then this can only be the parent of 01183 // the modified file. 01184 // 01185 01186 if (NormalizedParentName->Length == Notify->FullDirectoryName->Length) { 01187 01188 NotifyIsParent = TRUE; 01189 01190 // 01191 // If we are not watching the subtree of this directory then continue. 01192 // 01193 01194 } else if (!FlagOn( Notify->Flags, NOTIFY_WATCH_TREE )) { 01195 01196 continue; 01197 01198 // 01199 // The watched directory can only be an ancestor of the modified 01200 // file. Make sure that there is legal pathname separator immediately 01201 // after the end of the watched directory name within the normalized name. 01202 // If the watched directory is the root then we know this condition is TRUE. 01203 // 01204 01205 } else { 01206 01207 if (!FlagOn( Notify->Flags, NOTIFY_DIR_IS_ROOT )) { 01208 01209 // 01210 // Check for the character size. 01211 // 01212 01213 if (Notify->CharacterSize == sizeof( CHAR )) { 01214 01215 if (*(Add2Ptr( NormalizedParentName->Buffer, 01216 Notify->FullDirectoryName->Length, 01217 PCHAR )) != '\\') { 01218 01219 continue; 01220 } 01221 01222 } else if (*(Add2Ptr( NormalizedParentName->Buffer, 01223 Notify->FullDirectoryName->Length, 01224 PWCHAR )) != L'\\') { 01225 01226 continue; 01227 } 01228 } 01229 01230 NotifyIsParent = FALSE; 01231 } 01232 01233 // 01234 // We now have a correct match of the name lengths. Now verify that the 01235 // characters match exactly. 01236 // 01237 01238 if (!RtlEqualMemory( Notify->FullDirectoryName->Buffer, 01239 NormalizedParentName->Buffer, 01240 Notify->FullDirectoryName->Length )) { 01241 01242 continue; 01243 } 01244 01245 // 01246 // The characters are correct. Now check in the case of a non-parent 01247 // notify that we have traverse callback. 01248 // 01249 01250 if (!NotifyIsParent && 01251 Notify->TraverseCallback != NULL && 01252 !Notify->TraverseCallback( Notify->FsContext, 01253 TargetContext, 01254 Notify->SubjectContext )) { 01255 01256 continue; 01257 } 01258 } 01259 01260 // 01261 // If this entry is going into a buffer then check that 01262 // it will fit. 01263 // 01264 01265 if (!FlagOn( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ) 01266 && Notify->BufferLength != 0) { 01267 01268 ULONG AllocationLength; 01269 01270 AllocationLength = 0; 01271 NotifyIrp = NULL; 01272 01273 // 01274 // If we don't already have a buffer then check to see 01275 // if we have any Irps in the list and use the buffer 01276 // length in the Irp. 01277 // 01278 01279 if (Notify->ThisBufferLength == 0) { 01280 01281 // 01282 // If there is an entry in the list then get the length. 01283 // 01284 01285 if (!IsListEmpty( &Notify->NotifyIrps )) { 01286 01287 PIO_STACK_LOCATION IrpSp; 01288 01289 NotifyIrp = CONTAINING_RECORD( Notify->NotifyIrps.Flink, 01290 IRP, 01291 Tail.Overlay.ListEntry ); 01292 01293 IrpSp = IoGetCurrentIrpStackLocation( NotifyIrp ); 01294 01295 AllocationLength = IrpSp->Parameters.NotifyDirectory.Length; 01296 01297 // 01298 // Otherwise use the caller's last buffer size. 01299 // 01300 01301 } else { 01302 01303 AllocationLength = Notify->BufferLength; 01304 } 01305 01306 // 01307 // Otherwise use the length of the current buffer. 01308 // 01309 01310 } else { 01311 01312 AllocationLength = Notify->ThisBufferLength; 01313 } 01314 01315 // 01316 // Build the strings for the relative name. This includes 01317 // the strings for the parent name, file name and stream 01318 // name. 01319 // 01320 01321 if (!NotifyIsParent) { 01322 01323 // 01324 // We need to find the string for the ancestor of this 01325 // file from the watched directory. If the normalized parent 01326 // name is the same as the parent name then we can use 01327 // the tail of the parent directly. Otherwise we need to 01328 // count the matching name components and capture the 01329 // final components. 01330 // 01331 01332 if (!ViewIndex) { 01333 01334 // 01335 // If the watched directory is the root then we just use the full 01336 // parent name. 01337 // 01338 01339 if (FlagOn( Notify->Flags, NOTIFY_DIR_IS_ROOT ) || 01340 NormalizedParentName->Buffer != FullTargetName->Buffer) { 01341 01342 // 01343 // If we don't have a string for the parent then construct 01344 // it now. 01345 // 01346 01347 if (ParentName.Buffer == NULL) { 01348 01349 ParentName.Buffer = FullTargetName->Buffer; 01350 ParentName.Length = TargetNameOffset; 01351 01352 if (ParentName.Length != Notify->CharacterSize) { 01353 01354 ParentName.Length -= Notify->CharacterSize; 01355 } 01356 01357 ParentName.MaximumLength = ParentName.Length; 01358 } 01359 01360 // 01361 // Count through the components of the parent until we have 01362 // swallowed the same number of name components as in the 01363 // watched directory name. We have the unicode version and 01364 // the Ansi version to watch for. 01365 // 01366 01367 ComponentCount = 0; 01368 CurrentOffset = 0; 01369 01370 // 01371 // If this is the root then there is no more to do. 01372 // 01373 01374 if (FlagOn( Notify->Flags, NOTIFY_DIR_IS_ROOT )) { 01375 01376 NOTHING; 01377 01378 } else { 01379 01380 ULONG ParentComponentCount; 01381 ULONG ParentOffset; 01382 01383 ParentComponentCount = 1; 01384 ParentOffset = 0; 01385 01386 if (Notify->CharacterSize == sizeof( CHAR )) { 01387 01388 // 01389 // Find the number of components in the parent. We 01390 // have to do this for each one because this name and 01391 // the number of components could have changed. 01392 // 01393 01394 while (ParentOffset < Notify->FullDirectoryName->Length) { 01395 01396 if (*((PCHAR) Notify->FullDirectoryName->Buffer + ParentOffset) == '\\') { 01397 01398 ParentComponentCount += 1; 01399 } 01400 01401 ParentOffset += 1; 01402 } 01403 01404 while (TRUE) { 01405 01406 if (*((PCHAR) ParentName.Buffer + CurrentOffset) == '\\') { 01407 01408 ComponentCount += 1; 01409 01410 if (ComponentCount == ParentComponentCount) { 01411 01412 break; 01413 } 01414 01415 } 01416 01417 CurrentOffset += 1; 01418 } 01419 01420 } else { 01421 01422 // 01423 // Find the number of components in the parent. We 01424 // have to do this for each one because this name and 01425 // the number of components could have changed. 01426 // 01427 01428 while (ParentOffset < Notify->FullDirectoryName->Length / sizeof( WCHAR )) { 01429 01430 if (*((PWCHAR) Notify->FullDirectoryName->Buffer + ParentOffset) == '\\') { 01431 01432 ParentComponentCount += 1; 01433 } 01434 01435 ParentOffset += 1; 01436 } 01437 01438 while (TRUE) { 01439 01440 if (*((PWCHAR) ParentName.Buffer + CurrentOffset) == L'\\') { 01441 01442 ComponentCount += 1; 01443 01444 if (ComponentCount == ParentComponentCount) { 01445 01446 break; 01447 } 01448 } 01449 01450 CurrentOffset += 1; 01451 } 01452 01453 // 01454 // Convert characters to bytes. 01455 // 01456 01457 CurrentOffset *= Notify->CharacterSize; 01458 } 01459 } 01460 01461 // 01462 // We now know the offset into the parent name of the separator 01463 // immediately preceding the relative parent name. Construct the 01464 // target parent name for the buffer. 01465 // 01466 01467 CurrentOffset += Notify->CharacterSize; 01468 01469 TargetParent.Buffer = Add2Ptr( ParentName.Buffer, 01470 CurrentOffset, 01471 PCHAR ); 01472 TargetParent.MaximumLength = 01473 TargetParent.Length = ParentName.Length - (USHORT) CurrentOffset; 01474 01475 // 01476 // If the normalized is the same as the parent name use the portion 01477 // after the match with the watched directory. 01478 // 01479 01480 } else { 01481 01482 TargetParent.Buffer = Add2Ptr( NormalizedParentName->Buffer, 01483 (Notify->FullDirectoryName->Length + 01484 Notify->CharacterSize), 01485 PCHAR ); 01486 01487 TargetParent.MaximumLength = 01488 TargetParent.Length = NormalizedParentName->Length - 01489 Notify->FullDirectoryName->Length - 01490 Notify->CharacterSize; 01491 01492 } 01493 } 01494 01495 } else { 01496 01497 // 01498 // The length of the target parent is zero. 01499 // 01500 01501 TargetParent.Length = 0; 01502 } 01503 01504 // 01505 // Compute how much buffer space this report will take. 01506 // 01507 01508 SizeOfEntry = FIELD_OFFSET( FILE_NOTIFY_INFORMATION, FileName ); 01509 01510 if (ViewIndex) { 01511 01512 // 01513 // In the view index case, the information to copy to the 01514 // buffer comes to us in the stream name, and that is all 01515 // the room we need to worry about having. 01516 // 01517 01518 ASSERT(ARGUMENT_PRESENT( StreamName )); 01519 01520 SizeOfEntry += StreamName->Length; 01521 01522 } else { 01523 01524 // 01525 // If there is a parent to report, find the size and include a separator 01526 // character. 01527 // 01528 01529 if (!NotifyIsParent) { 01530 01531 if (Notify->CharacterSize == sizeof( CHAR )) { 01532 01533 SizeOfEntry += RtlOemStringToCountedUnicodeSize( &TargetParent ); 01534 01535 } else { 01536 01537 SizeOfEntry += TargetParent.Length; 01538 } 01539 01540 // 01541 // Include the separator. This is always a unicode character. 01542 // 01543 01544 SizeOfEntry += sizeof( WCHAR ); 01545 } 01546 01547 // 01548 // If we don't have the string for the target then construct it now. 01549 // 01550 01551 if (TargetName.Buffer == NULL) { 01552 01553 TargetName.Buffer = Add2Ptr( FullTargetName->Buffer, TargetNameOffset, PCHAR ); 01554 TargetName.MaximumLength = 01555 TargetName.Length = FullTargetName->Length - TargetNameOffset; 01556 } 01557 01558 if (Notify->CharacterSize == sizeof( CHAR )) { 01559 01560 SizeOfEntry += RtlOemStringToCountedUnicodeSize( &TargetName ); 01561 01562 } else { 01563 01564 SizeOfEntry += TargetName.Length; 01565 } 01566 01567 // 01568 // If there is a stream name then add the bytes needed 01569 // for that. 01570 // 01571 01572 if (ARGUMENT_PRESENT( StreamName )) { 01573 01574 // 01575 // Add the space needed for the ':' separator. 01576 // 01577 01578 if (Notify->CharacterSize == sizeof( WCHAR )) { 01579 01580 SizeOfEntry += (StreamName->Length + sizeof( WCHAR )); 01581 01582 } else { 01583 01584 SizeOfEntry += (RtlOemStringToCountedUnicodeSize( StreamName ) 01585 + sizeof( CHAR )); 01586 } 01587 } 01588 } 01589 01590 // 01591 // Remember if this report would overflow the buffer. 01592 // 01593 01594 NextEntryOffset = (ULONG)LongAlign( Notify->DataLength ); 01595 01596 if (SizeOfEntry <= AllocationLength 01597 && (NextEntryOffset + SizeOfEntry) <= AllocationLength) { 01598 01599 PFILE_NOTIFY_INFORMATION NotifyInfo = NULL; 01600 01601 // 01602 // If there is already a notify buffer, we append this 01603 // data to it. 01604 // 01605 01606 if (Notify->Buffer != NULL) { 01607 01608 NotifyInfo = Add2Ptr( Notify->Buffer, 01609 Notify->LastEntry, 01610 PFILE_NOTIFY_INFORMATION ); 01611 01612 NotifyInfo->NextEntryOffset = NextEntryOffset - Notify->LastEntry; 01613 01614 Notify->LastEntry = NextEntryOffset; 01615 01616 NotifyInfo = Add2Ptr( Notify->Buffer, 01617 Notify->LastEntry, 01618 PFILE_NOTIFY_INFORMATION ); 01619 01620 // 01621 // If there is an Irp list we check whether we will need 01622 // to allocate a new buffer. 01623 // 01624 01625 } else if (NotifyIrp != NULL) { 01626 01627 if (NotifyIrp->AssociatedIrp.SystemBuffer != NULL) { 01628 01629 Notify->Buffer = 01630 NotifyInfo = NotifyIrp->AssociatedIrp.SystemBuffer; 01631 01632 Notify->ThisBufferLength = AllocationLength; 01633 01634 } else if (NotifyIrp->MdlAddress != NULL) { 01635 01636 Notify->Buffer = 01637 NotifyInfo = MmGetSystemAddressForMdl( NotifyIrp->MdlAddress ); 01638 01639 Notify->ThisBufferLength = AllocationLength; 01640 } 01641 } 01642 01643 // 01644 // If we need to allocate a buffer, we will charge quota 01645 // to the original process and allocate paged pool. 01646 // 01647 01648 if (Notify->Buffer == NULL) { 01649 01650 BOOLEAN ChargedQuota = FALSE; 01651 01652 try { 01653 01654 PsChargePoolQuota( Notify->OwningProcess, 01655 PagedPool, 01656 AllocationLength ); 01657 01658 ChargedQuota = TRUE; 01659 01660 Notify->AllocatedBuffer = 01661 Notify->Buffer = FsRtlpAllocatePool( PagedPool, 01662 AllocationLength ); 01663 01664 Notify->ThisBufferLength = AllocationLength; 01665 01666 NotifyInfo = Notify->Buffer; 01667 01668 } except(( ExceptionCode = GetExceptionCode(), FsRtlIsNtstatusExpected(ExceptionCode)) 01669 ? EXCEPTION_EXECUTE_HANDLER 01670 : EXCEPTION_CONTINUE_SEARCH ) { 01671 01672 01673 ASSERT( (ExceptionCode == STATUS_INSUFFICIENT_RESOURCES) || 01674 (ExceptionCode == STATUS_QUOTA_EXCEEDED) ); 01675 01676 // 01677 // Return quota if we allocated the buffer. 01678 // 01679 01680 if (ChargedQuota) { 01681 01682 PsReturnPoolQuota( Notify->OwningProcess, 01683 PagedPool, 01684 AllocationLength ); 01685 01686 } 01687 01688 // 01689 // Forget any current buffer and resort to immediate 01690 // notify. 01691 // 01692 01693 SetFlag( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ); 01694 } 01695 } 01696 01697 // 01698 // If we have a buffer then fill in the results 01699 // from this operation. Otherwise we remember 01700 // to simply alert the caller. 01701 // 01702 01703 if (NotifyInfo != NULL) { 01704 01705 // 01706 // Update the buffer with the current data. 01707 // 01708 01709 if (FsRtlNotifyUpdateBuffer( NotifyInfo, 01710 Action, 01711 &TargetParent, 01712 &TargetName, 01713 StreamName, 01714 (BOOLEAN) (Notify->CharacterSize == sizeof( WCHAR )), 01715 SizeOfEntry )) { 01716 01717 // 01718 // Update the buffer data length. 01719 // 01720 01721 Notify->DataLength = NextEntryOffset + SizeOfEntry; 01722 01723 // 01724 // We couldn't copy the data into the buffer. Just 01725 // notify without any additional information. 01726 // 01727 01728 } else { 01729 01730 SetFlag( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ); 01731 } 01732 } 01733 01734 } else { 01735 01736 SetFlag( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ); 01737 } 01738 01739 // 01740 // If we have a buffer but can't use it then clear all of the 01741 // buffer related fields. Also deallocate any buffer allocated 01742 // by us. 01743 // 01744 01745 if (FlagOn( Notify->Flags, NOTIFY_IMMEDIATE_NOTIFY ) 01746 && Notify->Buffer != NULL) { 01747 01748 if (Notify->AllocatedBuffer != NULL) { 01749 01750 PsReturnPoolQuota( Notify->OwningProcess, 01751 PagedPool, 01752 Notify->ThisBufferLength ); 01753 01754 ExFreePool( Notify->AllocatedBuffer ); 01755 } 01756 01757 Notify->AllocatedBuffer = Notify->Buffer = NULL; 01758 01759 Notify->ThisBufferLength = Notify->DataLength = Notify->LastEntry = 0; 01760 } 01761 } 01762 01763 // 01764 // Complete the next entry on the list if we aren't holding 01765 // up notification. 01766 // 01767 01768 if (Action == FILE_ACTION_RENAMED_OLD_NAME) { 01769 01770 SetFlag( Notify->Flags, NOTIFY_DEFER_NOTIFY ); 01771 01772 } else { 01773 01774 ClearFlag( Notify->Flags, NOTIFY_DEFER_NOTIFY ); 01775 01776 if (!IsListEmpty( &Notify->NotifyIrps )) { 01777 01778 FsRtlNotifyCompleteIrpList( Notify, STATUS_SUCCESS ); 01779 } 01780 } 01781 } 01782 01783 } finally { 01784 01785 ReleaseNotifySync( NotifySync ); 01786 01787 DebugTrace( -1, Dbg, "FsRtlNotifyFullReportChange: Exit\n", 0 ); 01788 } 01789 01790 return; 01791 }

NTKERNELAPI VOID FsRtlNotifyInitializeSync IN PNOTIFY_SYNC NotifySync  ) 
 

Definition at line 371 of file notify.c.

References Dbg, DebugTrace, ERESOURCE_THREAD, ExInitializeFastMutex, _REAL_NOTIFY_SYNC::FastMutex, FsRtlpAllocatePool, NonPagedPool, NULL, _REAL_NOTIFY_SYNC::OwnerCount, _REAL_NOTIFY_SYNC::OwningThread, PAGED_CODE, PNOTIFY_SYNC, and PREAL_NOTIFY_SYNC.

Referenced by UdfInitializeVcb().

00377 : 00378 00379 This routine is called to allocate and initialize the synchronization object 00380 for this notify list. 00381 00382 Arguments: 00383 00384 NotifySync - This is the address to store the structure we allocate. 00385 00386 Return Value: 00387 00388 None. 00389 00390 --*/ 00391 00392 { 00393 PREAL_NOTIFY_SYNC RealSync; 00394 00395 PAGED_CODE(); 00396 00397 DebugTrace( +1, Dbg, "FsRtlNotifyInitializeSync: Entered\n", 0 ); 00398 00399 // 00400 // Clear the pointer and then attempt to allocate a non-paged 00401 // structure. 00402 // 00403 00404 *NotifySync = NULL; 00405 00406 RealSync = (PREAL_NOTIFY_SYNC) FsRtlpAllocatePool( NonPagedPool, 00407 sizeof( REAL_NOTIFY_SYNC )); 00408 00409 // 00410 // Initialize the structure. 00411 // 00412 00413 ExInitializeFastMutex( &RealSync->FastMutex ); 00414 RealSync->OwningThread = (ERESOURCE_THREAD) 0; 00415 RealSync->OwnerCount = 0; 00416 00417 *NotifySync = (PNOTIFY_SYNC) RealSync; 00418 00419 DebugTrace( -1, Dbg, "FsRtlNotifyInitializeSync: Exit\n", 0 ); 00420 return; 00421 }

NTKERNELAPI VOID FsRtlNotifyReportChange IN PNOTIFY_SYNC  NotifySync,
IN PLIST_ENTRY  NotifyList,
IN PSTRING  FullTargetName,
IN PSTRING  TargetName,
IN ULONG  FilterMatch
 

Definition at line 897 of file notify.c.

References Dbg, DebugTrace, FsRtlNotifyFullReportChange(), NULL, PAGED_CODE, and USHORT.

00907 : 00908 00909 This routine is called by a file system when a file has been modified in 00910 such a way that it will cause a notify change Irp to complete. We walk 00911 through all the notify structures looking for those structures which 00912 would be associated with an ancestor directory of the target file name. 00913 00914 We look for all the notify structures which have a filter match and 00915 then check that the directory name in the notify structure is a 00916 proper prefix of the full target name. 00917 00918 If we find a notify structure which matches the above conditions, we 00919 complete all the Irps for the notify structure. If the structure has 00920 no Irps, we mark the notify pending field. 00921 00922 Arguments: 00923 00924 NotifySync - This is the controlling fast mutex for this notify list. 00925 It is stored here so that it can be found for an Irp which is being 00926 cancelled. 00927 00928 NotifyList - This is the start of the notify list to add this 00929 structure to. 00930 00931 FullTargetName - This is the full name of the file which has been 00932 changed. 00933 00934 TargetName - This is the final component of the modified file. 00935 00936 FilterMatch - This flag field is compared with the completion filter 00937 in the notify structure. If any of the corresponding 00938 bits in the completion filter are set, then a notify 00939 condition exists. 00940 00941 Return Value: 00942 00943 None. 00944 00945 --*/ 00946 00947 { 00948 PAGED_CODE(); 00949 00950 DebugTrace( +1, Dbg, "FsRtlNotifyReportChange: Entered\n", 0 ); 00951 00952 // 00953 // Call the full notify routine to do the actual work. 00954 // 00955 00956 FsRtlNotifyFullReportChange( NotifySync, 00957 NotifyList, 00958 FullTargetName, 00959 (USHORT) (FullTargetName->Length - TargetName->Length), 00960 NULL, 00961 NULL, 00962 FilterMatch, 00963 0, 00964 NULL ); 00965 00966 DebugTrace( -1, Dbg, "FsRtlNotifyReportChange: Exit\n", 0 ); 00967 00968 return; 00969 }

NTKERNELAPI VOID FsRtlNotifyUninitializeSync IN PNOTIFY_SYNC NotifySync  ) 
 

Definition at line 426 of file notify.c.

References Dbg, DebugTrace, ExFreePool(), NULL, and PAGED_CODE.

Referenced by UdfDeleteVcb().

00432 : 00433 00434 This routine is called to uninitialize the synchronization object 00435 for this notify list. 00436 00437 Arguments: 00438 00439 NotifySync - This is the address containing the pointer to our synchronization 00440 object. 00441 00442 Return Value: 00443 00444 None. 00445 00446 --*/ 00447 00448 { 00449 PAGED_CODE(); 00450 00451 DebugTrace( +1, Dbg, "FsRtlNotifyUninitializeSync: Entered\n", 0 ); 00452 00453 // 00454 // Free the structure if present and clear the pointer. 00455 // 00456 00457 if (*NotifySync != NULL) { 00458 00459 ExFreePool( *NotifySync ); 00460 *NotifySync = NULL; 00461 } 00462 00463 DebugTrace( -1, Dbg, "FsRtlNotifyUninitializeSync: Exit\n", 0 ); 00464 return; 00465 }

NTKERNELAPI NTSTATUS FsRtlNotifyVolumeEvent IN PFILE_OBJECT  FileObject,
IN ULONG  EventCode
 

Definition at line 41 of file fsrtl/pnp.c.

References ASSERT, Event(), FSRTL_VOLUME_DISMOUNT, FSRTL_VOLUME_DISMOUNT_FAILED, FSRTL_VOLUME_LOCK, FSRTL_VOLUME_LOCK_FAILED, FSRTL_VOLUME_MOUNT, FSRTL_VOLUME_UNLOCK, IoGetRelatedTargetDevice(), IoReportTargetDeviceChange(), IoReportTargetDeviceChangeAsynchronous(), NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, Status, TARGET_DEVICE_CUSTOM_NOTIFICATION, and USHORT.

Referenced by UdfCommonCleanup(), UdfDismountVolume(), UdfLockVolume(), UdfMountVolume(), UdfUnlockVolume(), and UdfVerifyVolume().

00048 : 00049 00050 This routine notifies any registered applications that a 00051 volume is being locked, unlocked, etc. 00052 00053 Arguments: 00054 00055 FileeObject - Supplies a file object for the volume being 00056 locked. 00057 00058 EventCode - Which event is occuring -- e.g. FSRTL_VOLUME_LOCK 00059 00060 Return Value: 00061 00062 Status of the notification. 00063 00064 --*/ 00065 00066 { 00067 NTSTATUS Status = STATUS_SUCCESS; 00068 00069 TARGET_DEVICE_CUSTOM_NOTIFICATION Event; 00070 PDEVICE_OBJECT Pdo; 00071 00072 // 00073 // Retrieve the device object associated with this file object. 00074 // 00075 00076 Status = IoGetRelatedTargetDevice( FileObject, &Pdo ); 00077 00078 if (NT_SUCCESS( Status )) { 00079 00080 ASSERT(Pdo != NULL); 00081 00082 Event.Version = 1; 00083 Event.FileObject = NULL; 00084 Event.NameBufferOffset = -1; 00085 Event.Size = (USHORT)FIELD_OFFSET( TARGET_DEVICE_CUSTOM_NOTIFICATION, CustomDataBuffer ); 00086 00087 switch (EventCode) { 00088 00089 case FSRTL_VOLUME_DISMOUNT: 00090 00091 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_DISMOUNT, sizeof( GUID )); 00092 break; 00093 00094 case FSRTL_VOLUME_DISMOUNT_FAILED: 00095 00096 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_DISMOUNT_FAILED, sizeof( GUID )); 00097 break; 00098 00099 case FSRTL_VOLUME_LOCK: 00100 00101 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_LOCK, sizeof( GUID )); 00102 break; 00103 00104 case FSRTL_VOLUME_LOCK_FAILED: 00105 00106 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_LOCK_FAILED, sizeof( GUID )); 00107 break; 00108 00109 case FSRTL_VOLUME_MOUNT: 00110 00111 // 00112 // Mount notification is asynchronous to avoid deadlocks when someone 00113 // unwittingly causes a mount in the course of handling some other 00114 // PnP notification, e.g. MountMgr's device arrival code. 00115 // 00116 00117 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_MOUNT, sizeof( GUID )); 00118 IoReportTargetDeviceChangeAsynchronous( Pdo, &Event, NULL, NULL ); 00119 ObDereferenceObject( Pdo ); 00120 return STATUS_SUCCESS; 00121 break; 00122 00123 case FSRTL_VOLUME_UNLOCK: 00124 00125 RtlCopyMemory( &Event.Event, &GUID_IO_VOLUME_UNLOCK, sizeof( GUID )); 00126 break; 00127 00128 default: 00129 00130 ObDereferenceObject( Pdo ); 00131 return STATUS_INVALID_PARAMETER; 00132 } 00133 00134 IoReportTargetDeviceChange( Pdo, &Event ); 00135 ObDereferenceObject( Pdo ); 00136 } 00137 00138 return Status; 00139 }

NTKERNELAPI ULONG FsRtlNumberOfRunsInLargeMcb IN PLARGE_MCB  Mcb  ) 
 

Definition at line 1924 of file largemcb.c.

References Count, Dbg, DebugTrace, _NONOPAQUE_MCB::FastMutex, PAGED_CODE, _NONOPAQUE_MCB::PairCount, and PNONOPAQUE_MCB.

Referenced by FsRtlNumberOfRunsInMcb().

01930 : 01931 01932 This routine returns to the its caller the number of distinct runs 01933 mapped by an Mcb. Holes (i.e., Vbns that map to Lbn=UNUSED_LBN) are counted 01934 as runs. For example, an Mcb containing a mapping for only Vbns 0 and 3 01935 will have 3 runs, one for the first mapped sector, a second for the 01936 hole covering Vbns 1 and 2, and a third for Vbn 3. 01937 01938 Arguments: 01939 01940 OpaqueMcb - Supplies the Mcb being examined. 01941 01942 Return Value: 01943 01944 ULONG - Returns the number of distinct runs mapped by the input Mcb. 01945 01946 --*/ 01947 01948 { 01949 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 01950 01951 ULONG Count; 01952 01953 PAGED_CODE(); 01954 01955 DebugTrace(+1, Dbg, "FsRtlNumberOfRunsInLargeMcb, Mcb = %08lx\n", Mcb ); 01956 01957 ExAcquireFastMutex( Mcb->FastMutex ); 01958 01959 Count = Mcb->PairCount; 01960 01961 ExReleaseFastMutex( Mcb->FastMutex ); 01962 01963 DebugTrace(-1, Dbg, "FsRtlNumberOfRunsInLargeMcb -> %08lx\n", Count ); 01964 01965 return Count; 01966 }

NTKERNELAPI ULONG FsRtlNumberOfRunsInMcb IN PMCB  Mcb  ) 
 

Definition at line 479 of file largemcb.c.

References FsRtlNumberOfRunsInLargeMcb(), and PAGED_CODE.

00483 { 00484 PAGED_CODE(); 00485 00486 return FsRtlNumberOfRunsInLargeMcb( (PLARGE_MCB)Mcb ); 00487 }

NTKERNELAPI NTSTATUS FsRtlOplockFsctrl IN POPLOCK  Oplock,
IN PIRP  Irp,
IN ULONG  OpenCount
 

Definition at line 581 of file oplock.c.

References Dbg, DebugTrace, EXCLUSIVE, FALSE, _IO_STACK_LOCATION::FileObject, FlagOn, _FILE_OBJECT::Flags, _IRP::Flags, FO_CLEANUP_COMPLETE, FsRtlAcknowledgeOplockBreak(), FsRtlCompleteRequest, FsRtlOpBatchBreakClosePending(), FsRtlOplockBreakNotify(), FsRtlRequestExclusiveOplock(), FsRtlRequestOplockII(), IoGetCurrentIrpStackLocation, IoIsOperationSynchronous(), Irp, IRP_INPUT_OPERATION, IRP_MJ_CREATE, LEVEL_I_OPLOCK, _IO_STACK_LOCATION::MajorFunction, NTSTATUS(), NULL, OpFilterReqPending, OPLOCK_STATE, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PNONOPAQUE_OPLOCK, SetFlag, Status, and TRUE.

Referenced by UdfOplockRequest().

00589 : 00590 00591 This is the interface with the filesystems for Fsctl calls, it handles 00592 oplock requests, break acknowledgement and break notify. 00593 00594 Arguments: 00595 00596 Oplock - Supplies the address of the opaque OPLOCK structure. 00597 00598 Irp - Supplies a pointer to the Irp which declares the requested 00599 operation. 00600 00601 OpenCount - This is the number of user handles on the file if we are requsting 00602 an exclusive oplock. A non-zero value for a level II request indicates 00603 that there are locks on the file. 00604 00605 Return Value: 00606 00607 NTSTATUS - Returns the result of this operation. If this is an Oplock 00608 request which is granted, then STATUS_PENDING is returned. 00609 If the Oplock isn't granted then STATUS_OPLOCK_NOT_GRANTED 00610 is returned. If this is an Oplock I break to no oplock, 00611 then STATUS_SUCCESS. If this is an Oplock I break to 00612 Oplock II then STATUS_PENDING is returned. Other 00613 error codes returned depend on the nature of the error. 00614 00615 STATUS_CANCELLED is returned if the Irp is cancelled during 00616 this operation. 00617 00618 STATUS_SUCCESS is returned if this is a create asking for 00619 a filter oplock. 00620 00621 --*/ 00622 00623 { 00624 NTSTATUS Status; 00625 PIO_STACK_LOCATION IrpSp; 00626 OPLOCK_STATE OplockState; 00627 00628 PAGED_CODE(); 00629 00630 // 00631 // Get the current IRP stack location 00632 // 00633 00634 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 00635 00636 DebugTrace(+1, Dbg, "FsRtlOplockFsctrl: Entered\n", 0); 00637 DebugTrace( 0, Dbg, "FsRtlOplockFsctrl: Oplock -> %08lx\n", *Oplock ); 00638 DebugTrace( 0, Dbg, "FsRtlOplockFsctrl: Irp -> %08lx\n", Irp ); 00639 00640 // 00641 // Check if this is the create case where the user is requesting a pending 00642 // filter oplock. 00643 // 00644 00645 if (IrpSp->MajorFunction == IRP_MJ_CREATE) { 00646 00647 // 00648 // Check that all the conditions hold to grant this oplock. 00649 // The conditions that must hold are: 00650 // 00651 // - This is the only opener of the file. 00652 // - Desired Access must be exactly FILE_READ_ATTRIBUTES. 00653 // This will insure an asynch open since the SYNCHRONIZE 00654 // flag can't be set. 00655 // - Share access is precisely 00656 // (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE) 00657 // 00658 00659 if ((OpenCount != 1) || 00660 (FlagOn( IrpSp->Parameters.Create.SecurityContext->DesiredAccess, 00661 ~(FILE_READ_ATTRIBUTES))) || 00662 ((IrpSp->Parameters.Create.ShareAccess & 00663 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)) != 00664 (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE))) { 00665 00666 Status = STATUS_OPLOCK_NOT_GRANTED; 00667 00668 } else { 00669 00670 Status = FsRtlRequestExclusiveOplock( (PNONOPAQUE_OPLOCK *) Oplock, 00671 IrpSp, 00672 NULL, 00673 OpFilterReqPending ); 00674 } 00675 00676 // 00677 // Case on the FsControlFile code control code. 00678 // 00679 00680 } else { 00681 00682 // 00683 // Assume this is an OplockLevel I. 00684 // 00685 // NOTE - This code depends on the defined bits for these oplock types. 00686 // FILTER_OPLOCK = 4 * LEVEL_I_OPLOCK 00687 // BATCH_OPLOCK = 2 * LEVEL_I_OPLOCK 00688 // 00689 00690 OplockState = LEVEL_I_OPLOCK; 00691 00692 switch (IrpSp->Parameters.FileSystemControl.FsControlCode) { 00693 00694 case FSCTL_REQUEST_FILTER_OPLOCK : 00695 00696 OplockState *= 2; 00697 00698 case FSCTL_REQUEST_BATCH_OPLOCK : 00699 00700 OplockState *= 2; 00701 00702 case FSCTL_REQUEST_OPLOCK_LEVEL_1 : 00703 00704 // 00705 // Set the other flags for an exclusive oplock. 00706 // 00707 00708 SetFlag( OplockState, EXCLUSIVE ); 00709 00710 // 00711 // We short circuit the request if this request is treated 00712 // synchronously or the open count is not 1. Otherwise the Io system 00713 // will hold the return code until the Irp is completed. 00714 // 00715 // Also fail this if the flag is set which indicates that 00716 // the IO system should copy data back to a user's buffer. 00717 // 00718 // If cleanup has occurrred on this file, then we refuse 00719 // the oplock request. 00720 // 00721 00722 if ((OpenCount != 1) || 00723 IoIsOperationSynchronous( Irp ) || 00724 FlagOn( Irp->Flags, IRP_INPUT_OPERATION ) || 00725 FlagOn( IrpSp->FileObject->Flags, FO_CLEANUP_COMPLETE )) { 00726 00727 FsRtlCompleteRequest( Irp, STATUS_OPLOCK_NOT_GRANTED ); 00728 Status = STATUS_OPLOCK_NOT_GRANTED; 00729 00730 } else { 00731 00732 Status = FsRtlRequestExclusiveOplock( (PNONOPAQUE_OPLOCK *) Oplock, 00733 IrpSp, 00734 Irp, 00735 OplockState ); 00736 } 00737 00738 break; 00739 00740 case FSCTL_REQUEST_OPLOCK_LEVEL_2 : 00741 00742 // 00743 // We short circuit the request if this request is treated 00744 // synchronously. Otherwise the Io system will hold the return 00745 // code until the Irp is completed. 00746 // 00747 // If cleanup has occurrred on this file, then we refuse 00748 // the oplock request. 00749 // 00750 // Also fail this if the flag is set which indicates that 00751 // the IO system should copy data back to a user's buffer. 00752 // 00753 // A non-zero open count in this case indicates that there are 00754 // file locks on the file. We will also fail the request in 00755 // this case. 00756 // 00757 00758 if ((OpenCount != 0) || 00759 IoIsOperationSynchronous( Irp ) || 00760 FlagOn( Irp->Flags, IRP_INPUT_OPERATION ) || 00761 FlagOn( IrpSp->FileObject->Flags, FO_CLEANUP_COMPLETE )) { 00762 00763 FsRtlCompleteRequest( Irp, STATUS_OPLOCK_NOT_GRANTED ); 00764 Status = STATUS_OPLOCK_NOT_GRANTED; 00765 00766 } else { 00767 00768 Status = FsRtlRequestOplockII( (PNONOPAQUE_OPLOCK *) Oplock, 00769 IrpSp, 00770 Irp ); 00771 } 00772 00773 break; 00774 00775 case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE : 00776 00777 Status = FsRtlAcknowledgeOplockBreak( (PNONOPAQUE_OPLOCK) *Oplock, 00778 IrpSp, 00779 Irp, 00780 TRUE ); 00781 break; 00782 00783 case FSCTL_OPLOCK_BREAK_ACK_NO_2 : 00784 00785 Status = FsRtlAcknowledgeOplockBreak( (PNONOPAQUE_OPLOCK) *Oplock, 00786 IrpSp, 00787 Irp, 00788 FALSE ); 00789 break; 00790 00791 case FSCTL_OPBATCH_ACK_CLOSE_PENDING : 00792 00793 Status = FsRtlOpBatchBreakClosePending( (PNONOPAQUE_OPLOCK) *Oplock, 00794 IrpSp, 00795 Irp ); 00796 break; 00797 00798 case FSCTL_OPLOCK_BREAK_NOTIFY : 00799 00800 Status = FsRtlOplockBreakNotify( (PNONOPAQUE_OPLOCK) *Oplock, 00801 IrpSp, 00802 Irp ); 00803 break; 00804 00805 default : 00806 00807 DebugTrace( 0, 00808 Dbg, 00809 "Invalid Control Code\n", 00810 0); 00811 00812 FsRtlCompleteRequest( Irp, STATUS_INVALID_PARAMETER ); 00813 Status = STATUS_INVALID_PARAMETER; 00814 } 00815 } 00816 00817 DebugTrace(-1, Dbg, "FsRtlOplockFsctrl: Exit -> %08lx\n", Status ); 00818 return Status; 00819 }

NTKERNELAPI BOOLEAN FsRtlOplockIsFastIoPossible IN POPLOCK  Oplock  ) 
 

Definition at line 1116 of file oplock.c.

References Dbg, DebugTrace, FALSE, FlagOn, LEVEL_II_OPLOCK, NULL, OPLOCK_BREAK_MASK, OPLOCK_STATE, PAGED_CODE, PNONOPAQUE_OPLOCK, and TRUE.

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

01122 : 01123 01124 This routine indicates to the caller where there are any outstanding 01125 oplocks which prevent fast Io from happening. 01126 01127 Arguments: 01128 01129 OpLock - Supplies the oplock being queried 01130 01131 Return Value: 01132 01133 BOOLEAN - TRUE if there are outstanding oplocks and FALSE otherwise 01134 01135 --*/ 01136 01137 { 01138 BOOLEAN FastIoPossible = TRUE; 01139 01140 PAGED_CODE(); 01141 01142 DebugTrace(+1, Dbg, "FsRtlOplockIsFastIoPossible: Oplock -> %08lx\n", *Oplock); 01143 01144 // 01145 // There are not any current oplocks if the variable is null or 01146 // the state is no oplocks held. If an exclusive oplock was granted 01147 // but no break is in progress then allow the Fast IO. 01148 // 01149 01150 if (*Oplock != NULL) { 01151 01152 OPLOCK_STATE OplockState; 01153 01154 OplockState = ((PNONOPAQUE_OPLOCK) *Oplock)->OplockState; 01155 01156 if (FlagOn( OplockState, LEVEL_II_OPLOCK | OPLOCK_BREAK_MASK )) { 01157 01158 FastIoPossible = FALSE; 01159 } 01160 } 01161 01162 DebugTrace(-1, Dbg, "FsRtlOplockIsFastIoPossible: Exit -> %08lx\n", FastIoPossible); 01163 01164 return FastIoPossible; 01165 }

NTKERNELAPI VOID FsRtlPostPagingFileStackOverflow IN PVOID  Context,
IN PKEVENT  Event,
IN PFSRTL_STACK_OVERFLOW_ROUTINE  StackOverflowRoutine
 

Definition at line 177 of file stackovf.c.

References Event(), FsRtlpPostStackOverflow(), and TRUE.

00185 : 00186 00187 This routines posts a stack overflow item to the stack overflow 00188 thread and returns. 00189 00190 Arguments: 00191 00192 Context - Supplies the context to pass to the stack overflow 00193 call back routine. If the low order bit is set, then 00194 this overflow was a read to a paging file. 00195 00196 Event - Supplies a pointer to an event to pass to the stack 00197 overflow call back routine. 00198 00199 StackOverflowRoutine - Supplies the call back to use when 00200 processing the request in the overflow thread. 00201 00202 Return Value: 00203 00204 None. 00205 00206 --*/ 00207 00208 { 00209 FsRtlpPostStackOverflow( Context, Event, StackOverflowRoutine, TRUE ); 00210 return; 00211 }

NTKERNELAPI VOID FsRtlPostStackOverflow IN PVOID  Context,
IN PKEVENT  Event,
IN PFSRTL_STACK_OVERFLOW_ROUTINE  StackOverflowRoutine
 

Definition at line 139 of file stackovf.c.

References Event(), FALSE, and FsRtlpPostStackOverflow().

00147 : 00148 00149 This routines posts a stack overflow item to the stack overflow 00150 thread and returns. 00151 00152 Arguments: 00153 00154 Context - Supplies the context to pass to the stack overflow 00155 call back routine. If the low order bit is set, then 00156 this overflow was a read to a paging file. 00157 00158 Event - Supplies a pointer to an event to pass to the stack 00159 overflow call back routine. 00160 00161 StackOverflowRoutine - Supplies the call back to use when 00162 processing the request in the overflow thread. 00163 00164 Return Value: 00165 00166 None. 00167 00168 --*/ 00169 00170 { 00171 FsRtlpPostStackOverflow( Context, Event, StackOverflowRoutine, FALSE ); 00172 return; 00173 }

NTKERNELAPI BOOLEAN FsRtlPrepareMdlWrite IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus
 

Definition at line 1860 of file fastio.c.

References _DEVICE_OBJECT::DriverObject, FALSE, _DRIVER_OBJECT::FastIoDispatch, FsRtlPrepareMdlWriteDev(), IoGetBaseFileSystemDeviceObject(), IoGetRelatedDeviceObject(), NULL, _FAST_IO_DISPATCH::PrepareMdlWrite, and _FAST_IO_DISPATCH::SizeOfFastIoDispatch.

01871 : 01872 01873 This routine does a fast cached mdl read bypassing the usual file system 01874 entry routine (i.e., without the Irp). It is used to do a copy read 01875 of a cached file object. For a complete description of the arguments 01876 see CcMdlRead. 01877 01878 Arguments: 01879 01880 FileObject - Pointer to the file object being read. 01881 01882 FileOffset - Byte offset in file for desired data. 01883 01884 Length - Length of desired data in bytes. 01885 01886 MdlChain - On output it returns a pointer to an MDL chain describing 01887 the desired data. 01888 01889 IoStatus - Pointer to standard I/O status block to receive the status 01890 for the transfer. 01891 01892 Return Value: 01893 01894 FALSE - if the data was not written, or if there is an I/O error. 01895 01896 TRUE - if the data is being written 01897 01898 --*/ 01899 01900 { 01901 PDEVICE_OBJECT DeviceObject, VolumeDeviceObject; 01902 PFAST_IO_DISPATCH FastIoDispatch; 01903 01904 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 01905 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 01906 01907 // 01908 // See if the (top-level) FileSystem has a FastIo routine, and if so, call it. 01909 // 01910 01911 if ((FastIoDispatch != NULL) && 01912 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, PrepareMdlWrite)) && 01913 (FastIoDispatch->PrepareMdlWrite != NULL)) { 01914 01915 return FastIoDispatch->PrepareMdlWrite( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject ); 01916 01917 } else { 01918 01919 // 01920 // Get the DeviceObject for the volume. If that DeviceObject is different, and 01921 // it specifies the FastIo routine, then we have to return FALSE here and cause 01922 // an Irp to get generated. 01923 // 01924 01925 VolumeDeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 01926 if ((VolumeDeviceObject != DeviceObject) && 01927 (FastIoDispatch = VolumeDeviceObject->DriverObject->FastIoDispatch) && 01928 (FastIoDispatch->SizeOfFastIoDispatch > FIELD_OFFSET(FAST_IO_DISPATCH, PrepareMdlWrite)) && 01929 (FastIoDispatch->PrepareMdlWrite != NULL)) { 01930 01931 return FALSE; 01932 01933 // 01934 // Otherwise, call the default routine. 01935 // 01936 01937 } else { 01938 01939 return FsRtlPrepareMdlWriteDev( FileObject, FileOffset, Length, LockKey, MdlChain, IoStatus, DeviceObject ); 01940 } 01941 } 01942 }

NTKERNELAPI BOOLEAN FsRtlPrepareMdlWriteDev IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN ULONG  Length,
IN ULONG  LockKey,
OUT PMDL MdlChain,
OUT PIO_STATUS_BLOCK  IoStatus,
IN PDEVICE_OBJECT  DeviceObject
 

Definition at line 1474 of file fastio.c.

References ASSERT, CcCanIWrite(), CcGetFileSizePointer, CcPrepareMdlWrite(), CcZeroData(), _DEVICE_OBJECT::DriverObject, ExAcquireResourceExclusive, ExAcquireResourceShared, EXCEPTION_CONTINUE_SEARCH, EXCEPTION_EXECUTE_HANDLER, ExReleaseResource, FALSE, _FAST_IO_DISPATCH::FastIoCheckIfPossible, _DRIVER_OBJECT::FastIoDispatch, FastIoIsNotPossible, FastIoIsQuestionable, FlagOn, FO_FILE_MODIFIED, FO_FILE_SIZE_CHANGED, FO_WRITE_THROUGH, FSRTL_FAST_IO_TOP_LEVEL_IRP, FsRtlEnterFileSystem, FsRtlExitFileSystem, FsRtlIsNtstatusExpected(), Header, IoGetRelatedDeviceObject(), NULL, Offset, PAGED_CODE, PsGetCurrentThread, Status, TRUE, and VOID().

Referenced by FsRtlPrepareMdlWrite().

01486 : 01487 01488 This routine does a fast cached mdl read bypassing the usual file system 01489 entry routine (i.e., without the Irp). It is used to do a copy read 01490 of a cached file object. For a complete description of the arguments 01491 see CcMdlRead. 01492 01493 Arguments: 01494 01495 FileObject - Pointer to the file object being read. 01496 01497 FileOffset - Byte offset in file for desired data. 01498 01499 Length - Length of desired data in bytes. 01500 01501 MdlChain - On output it returns a pointer to an MDL chain describing 01502 the desired data. 01503 01504 IoStatus - Pointer to standard I/O status block to receive the status 01505 for the transfer. 01506 01507 DeviceObject - Supplies the DeviceObject for the callee. 01508 01509 Return Value: 01510 01511 FALSE - if the data was not written, or if there is an I/O error. 01512 01513 TRUE - if the data is being written 01514 01515 --*/ 01516 01517 { 01518 PFSRTL_COMMON_FCB_HEADER Header; 01519 LARGE_INTEGER Offset, NewFileSize; 01520 LARGE_INTEGER OldFileSize; 01521 LARGE_INTEGER OldValidDataLength; 01522 BOOLEAN Status = TRUE; 01523 BOOLEAN AcquiredShared = FALSE; 01524 BOOLEAN FileSizeChanged = FALSE; 01525 BOOLEAN WriteToEndOfFile = (BOOLEAN)((FileOffset->LowPart == FILE_WRITE_TO_END_OF_FILE) && 01526 (FileOffset->HighPart == -1)); 01527 01528 PAGED_CODE(); 01529 01530 // 01531 // Call CcCanIWrite. Also return FALSE if FileObject is write through, 01532 // the File System must do that. 01533 // 01534 01535 if ( !CcCanIWrite( FileObject, Length, TRUE, FALSE ) || 01536 FlagOn( FileObject->Flags, FO_WRITE_THROUGH )) { 01537 01538 return FALSE; 01539 } 01540 01541 // 01542 // Assume our transfer will work 01543 // 01544 01545 IoStatus->Status = STATUS_SUCCESS; 01546 01547 // 01548 // Special case the zero byte length 01549 // 01550 01551 if (Length == 0) { 01552 01553 return TRUE; 01554 } 01555 01556 // 01557 // Get a real pointer to the common fcb header 01558 // 01559 01560 Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext; 01561 01562 // 01563 // Enter the file system 01564 // 01565 01566 FsRtlEnterFileSystem(); 01567 01568 // 01569 // Make our best guess on whether we need the file exclusive or 01570 // shared. 01571 // 01572 01573 NewFileSize.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 01574 01575 if (WriteToEndOfFile || (NewFileSize.QuadPart > Header->ValidDataLength.QuadPart)) { 01576 01577 // 01578 // Acquired exclusive on the common fcb header, and return if we don't 01579 // get it. 01580 // 01581 01582 ExAcquireResourceExclusive( Header->Resource, TRUE ); 01583 01584 } else { 01585 01586 // 01587 // Acquired shared on the common fcb header, and return if we don't 01588 // get it. 01589 // 01590 01591 ExAcquireResourceShared( Header->Resource, TRUE ); 01592 01593 AcquiredShared = TRUE; 01594 } 01595 01596 01597 // 01598 // We have the fcb shared now check if we can do fast i/o and if the file 01599 // space is allocated, and if not then release the fcb and return. 01600 // 01601 01602 if (WriteToEndOfFile) { 01603 01604 Offset = Header->FileSize; 01605 NewFileSize.QuadPart = Header->FileSize.QuadPart + (LONGLONG)Length; 01606 01607 } else { 01608 01609 Offset = *FileOffset; 01610 NewFileSize.QuadPart = FileOffset->QuadPart + (LONGLONG)Length; 01611 } 01612 01613 // 01614 // Now that the File is acquired shared, we can safely test if it is 01615 // really cached and if we can do fast i/o and we do not have to extend. 01616 // If not then release the fcb and return. 01617 // 01618 01619 if ((FileObject->PrivateCacheMap == NULL) || 01620 (Header->IsFastIoPossible == FastIoIsNotPossible) || 01621 (MAXLONGLONG - Offset.QuadPart < (LONGLONG)Length) || 01622 ( NewFileSize.QuadPart > Header->AllocationSize.QuadPart ) ) { 01623 01624 ExReleaseResource( Header->Resource ); 01625 FsRtlExitFileSystem(); 01626 01627 return FALSE; 01628 } 01629 01630 // 01631 // If we will be extending ValidDataLength, we will have to get the 01632 // Fcb exclusive, and make sure that FastIo is still possible. 01633 // 01634 01635 if (AcquiredShared && ( NewFileSize.QuadPart > Header->ValidDataLength.QuadPart )) { 01636 01637 ExReleaseResource( Header->Resource ); 01638 01639 ExAcquireResourceExclusive( Header->Resource, TRUE ); 01640 01641 AcquiredShared = FALSE; 01642 01643 // 01644 // If writing to end of file, we must recalculate new size. 01645 // 01646 01647 if (WriteToEndOfFile) { 01648 01649 Offset = Header->FileSize; 01650 NewFileSize.QuadPart = Header->FileSize.QuadPart + (LONGLONG)Length; 01651 } 01652 01653 if ((FileObject->PrivateCacheMap == NULL) || 01654 (Header->IsFastIoPossible == FastIoIsNotPossible) || 01655 ( NewFileSize.QuadPart > Header->AllocationSize.QuadPart )) { 01656 01657 ExReleaseResource( Header->Resource ); 01658 FsRtlExitFileSystem(); 01659 01660 return FALSE; 01661 } 01662 } 01663 01664 // 01665 // Check if fast I/O is questionable and if so then go ask the file system 01666 // the answer 01667 // 01668 01669 if (Header->IsFastIoPossible == FastIoIsQuestionable) { 01670 01671 PFAST_IO_DISPATCH FastIoDispatch = IoGetRelatedDeviceObject( FileObject )->DriverObject->FastIoDispatch; 01672 01673 // 01674 // All file system then set "Is Questionable" had better support fast I/O 01675 // 01676 01677 ASSERT(FastIoDispatch != NULL); 01678 ASSERT(FastIoDispatch->FastIoCheckIfPossible != NULL); 01679 01680 // 01681 // Call the file system to check for fast I/O. If the answer is anything 01682 // other than GoForIt then we cannot take the fast I/O path. 01683 // 01684 01685 if (!FastIoDispatch->FastIoCheckIfPossible( FileObject, 01686 FileOffset, 01687 Length, 01688 TRUE, 01689 LockKey, 01690 FALSE, // write operation 01691 IoStatus, 01692 IoGetRelatedDeviceObject( FileObject ) )) { 01693 01694 // 01695 // Fast I/O is not possible so release the Fcb and return. 01696 // 01697 01698 ExReleaseResource( Header->Resource ); 01699 FsRtlExitFileSystem(); 01700 01701 return FALSE; 01702 } 01703 } 01704 01705 // 01706 // Now see if we will change FileSize. We have to do it now so that our 01707 // reads are not nooped. 01708 // 01709 01710 if ( NewFileSize.QuadPart > Header->FileSize.QuadPart ) { 01711 01712 FileSizeChanged = TRUE; 01713 OldFileSize = Header->FileSize; 01714 OldValidDataLength = Header->ValidDataLength; 01715 01716 // 01717 // Deal with an extremely rare pathalogical case here the file 01718 // size wraps. 01719 // 01720 01721 if ( (Header->FileSize.HighPart != NewFileSize.HighPart) && 01722 (Header->PagingIoResource != NULL) ) { 01723 01724 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 01725 Header->FileSize = NewFileSize; 01726 ExReleaseResource( Header->PagingIoResource ); 01727 01728 } else { 01729 01730 Header->FileSize = NewFileSize; 01731 } 01732 } 01733 01734 // 01735 // We can do fast i/o so call the cc routine to do the work and then 01736 // release the fcb when we've done. If for whatever reason the 01737 // copy write fails, then return FALSE to our caller. 01738 // 01739 // 01740 // Also mark this as the top level "Irp" so that lower file system levels 01741 // will not attempt a pop-up 01742 // 01743 01744 PsGetCurrentThread()->TopLevelIrp = FSRTL_FAST_IO_TOP_LEVEL_IRP; 01745 01746 try { 01747 01748 // 01749 // See if we have to do some zeroing 01750 // 01751 01752 if ( Offset.QuadPart > Header->ValidDataLength.QuadPart ) { 01753 01754 Status = CcZeroData( FileObject, 01755 &Header->ValidDataLength, 01756 &Offset, 01757 TRUE ); 01758 } 01759 01760 if (Status) { 01761 01762 CcPrepareMdlWrite( FileObject, &Offset, Length, MdlChain, IoStatus ); 01763 } 01764 01765 } except( FsRtlIsNtstatusExpected(GetExceptionCode()) 01766 ? EXCEPTION_EXECUTE_HANDLER 01767 : EXCEPTION_CONTINUE_SEARCH ) { 01768 01769 Status = FALSE; 01770 } 01771 01772 PsGetCurrentThread()->TopLevelIrp = 0; 01773 01774 // 01775 // If we succeeded, see if we have to update FileSize or ValidDataLength. 01776 // 01777 01778 if (Status) { 01779 01780 // 01781 // In the case of ValidDataLength, we really have to check again 01782 // since we did not do this when we acquired the resource exclusive. 01783 // 01784 01785 if ( NewFileSize.QuadPart > Header->ValidDataLength.QuadPart ) { 01786 01787 // 01788 // Deal with an extremely rare pathalogical case here the 01789 // ValidDataLength wraps. 01790 // 01791 01792 if ( (Header->ValidDataLength.HighPart != NewFileSize.HighPart) && 01793 (Header->PagingIoResource != NULL) ) { 01794 01795 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 01796 Header->ValidDataLength = NewFileSize; 01797 ExReleaseResource( Header->PagingIoResource ); 01798 01799 } else { 01800 01801 Header->ValidDataLength = NewFileSize; 01802 } 01803 } 01804 01805 // 01806 // Set this handle as having modified the file 01807 // 01808 01809 FileObject->Flags |= FO_FILE_MODIFIED; 01810 01811 if (FileSizeChanged) { 01812 01813 *CcGetFileSizePointer(FileObject) = NewFileSize; 01814 01815 FileObject->Flags |= FO_FILE_SIZE_CHANGED; 01816 } 01817 01818 // 01819 // If we did not succeed, then we must restore the original FileSize 01820 // and release the resource. In the success path, the cache manager 01821 // will release the resource. 01822 // 01823 01824 } else { 01825 01826 if (FileSizeChanged) { 01827 01828 if ( Header->PagingIoResource != NULL ) { 01829 01830 (VOID)ExAcquireResourceExclusive( Header->PagingIoResource, TRUE ); 01831 Header->FileSize = OldFileSize; 01832 Header->ValidDataLength = OldValidDataLength; 01833 ExReleaseResource( Header->PagingIoResource ); 01834 01835 } else { 01836 01837 Header->FileSize = OldFileSize; 01838 Header->ValidDataLength = OldValidDataLength; 01839 } 01840 } 01841 } 01842 01843 // 01844 // Now we can release the resource. 01845 // 01846 01847 ExReleaseResource( Header->Resource ); 01848 01849 FsRtlExitFileSystem(); 01850 01851 return Status; 01852 }

NTKERNELAPI BOOLEAN FsRtlPrivateLock IN PFILE_LOCK  FileLock,
IN PFILE_OBJECT  FileObject,
IN PLARGE_INTEGER  FileOffset,
IN PLARGE_INTEGER  Length,
IN PEPROCESS  ProcessId,
IN ULONG  Key,
IN BOOLEAN  FailImmediately,
IN BOOLEAN  ExclusiveLock,
OUT PIO_STATUS_BLOCK  Iosb,
IN PIRP  Irp,
IN PVOID  Context,
IN BOOLEAN  AlreadySynchronized
 

Definition at line 3867 of file filelock.c.

References _IRP::Cancel, _IRP::CancelIrql, _WAITING_LOCK::Context, Dbg, DebugTrace, _FILE_LOCK_INFO::EndingByte, _FILE_LOCK_INFO::ExclusiveLock, ExRaiseStatus(), FALSE, _FILE_LOCK_INFO::FileObject, FsRtlAcquireLockQueue, FsRtlAllocateWaitingLock(), FsRtlCompleteLockIrp, FsRtlPrivateCancelFileLockIrp(), FsRtlPrivateCheckForExclusiveLockAccess(), FsRtlPrivateCheckForSharedLockAccess(), FsRtlPrivateInitializeFileLock(), FsRtlPrivateInsertLock(), FsRtlPrivateRemoveLock(), FsRtlReleaseLockQueue, IoMarkIrpPending, IoSetCancelRoutine, _IRP::IoStatus, _WAITING_LOCK::Irp, Irp, Key, _FILE_LOCK_INFO::Key, _FILE_LOCK_INFO::Length, _WAITING_LOCK::Link, _LOCK_INFO::LockQueue, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, PLOCK_INFO, PLOCK_QUEUE, _FILE_LOCK_INFO::ProcessId, PWAITING_LOCK, _FILE_LOCK_INFO::StartingByte, TRUE, try_return, _LOCK_QUEUE::WaitingLocks, and _LOCK_QUEUE::WaitingLocksTail.

Referenced by FsRtlProcessFileLock().

03884 : 03885 03886 This routine preforms a lock operation request. This handles both the fast 03887 get lock and the Irp based get lock. If the Irp is supplied then 03888 this routine will either complete the Irp or enqueue it as a waiting 03889 lock request. 03890 03891 Arguments: 03892 03893 FileLock - Supplies the File Lock to work against 03894 03895 FileObject - Supplies the file object used in this operation 03896 03897 FileOffset - Supplies the file offset used in this operation 03898 03899 Length - Supplies the length used in this operation 03900 03901 ProcessId - Supplies the process ID used in this operation 03902 03903 Key - Supplies the key used in this operation 03904 03905 FailImmediately - Indicates if the request should fail immediately 03906 if the lock cannot be granted. 03907 03908 ExclusiveLock - Indicates if this is a request for an exclusive or 03909 shared lock 03910 03911 Iosb - Receives the Status if this operation is successful 03912 03913 Context - Supplies the context with which to complete Irp with 03914 03915 AlreadySynchronized - Indicates that the caller has already synchronized 03916 access to the file lock so the fields in the file lock and 03917 be updated without further locking, but not the queues. 03918 03919 Return Value: 03920 03921 BOOLEAN - TRUE if this operation completed and FALSE otherwise. 03922 03923 --*/ 03924 03925 { 03926 BOOLEAN Results; 03927 BOOLEAN AccessGranted; 03928 BOOLEAN ViaFastCall; 03929 BOOLEAN ReleaseQueue = FALSE; 03930 03931 PLOCK_INFO LockInfo; 03932 PLOCK_QUEUE LockQueue; 03933 KIRQL OldIrql; 03934 FILE_LOCK_INFO FileLockInfo; 03935 03936 DebugTrace(+1, Dbg, "FsRtlPrivateLock, FileLock = %08lx\n", FileLock); 03937 03938 // 03939 // If the irp is null then this is being called via the fast call method. 03940 // 03941 03942 ViaFastCall = (BOOLEAN) !ARGUMENT_PRESENT( Irp ); 03943 03944 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 03945 DebugTrace(+2, Dbg, "FsRtlPrivateLock, New LockInfo required\n", 0); 03946 03947 // 03948 // No lock information on this FileLock, create the structure. 03949 // 03950 // 03951 03952 if (!FsRtlPrivateInitializeFileLock (FileLock, ViaFastCall)) { 03953 03954 return FALSE; 03955 } 03956 03957 // 03958 // Set flag so file locks will be checked on the fast io 03959 // code paths 03960 // 03961 03962 FileLock->FastIoIsQuestionable = TRUE; 03963 03964 // 03965 // Pickup allocated lockinfo structure 03966 // 03967 03968 LockInfo = (PLOCK_INFO) FileLock->LockInformation; 03969 } 03970 03971 // 03972 // Assume success and build LockData structure prior to acquiring 03973 // the lock queue spinlock. (mp perf enhancement) 03974 // 03975 03976 FileLockInfo.StartingByte = *FileOffset; 03977 FileLockInfo.Length = *Length; 03978 (ULONGLONG)FileLockInfo.EndingByte.QuadPart = 03979 (ULONGLONG)FileLockInfo.StartingByte.QuadPart + (ULONGLONG)FileLockInfo.Length.QuadPart - 1; 03980 03981 FileLockInfo.Key = Key; 03982 FileLockInfo.FileObject = FileObject; 03983 FileLockInfo.ProcessId = ProcessId; 03984 FileLockInfo.ExclusiveLock = ExclusiveLock; 03985 03986 LockQueue = &LockInfo->LockQueue; 03987 03988 // 03989 // Now we need to actually run through our current lock queue. 03990 // 03991 03992 FsRtlAcquireLockQueue(LockQueue, &OldIrql); 03993 ReleaseQueue = TRUE; 03994 03995 try { 03996 03997 // 03998 // Case on whether we're trying to take out an exclusive lock or 03999 // a shared lock. And in both cases try to get appropriate access. 04000 // 04001 04002 if (ExclusiveLock) { 04003 04004 DebugTrace(0, Dbg, "Check for write access\n", 0); 04005 04006 AccessGranted = FsRtlPrivateCheckForExclusiveLockAccess( 04007 LockQueue, 04008 &FileLockInfo ); 04009 04010 } else { 04011 04012 DebugTrace(0, Dbg, "Check for read access\n", 0); 04013 04014 AccessGranted = FsRtlPrivateCheckForSharedLockAccess( 04015 LockQueue, 04016 &FileLockInfo ); 04017 } 04018 04019 // 04020 // Now AccessGranted tells us whether we can really get the access 04021 // for the range we want 04022 // 04023 04024 if (!AccessGranted) { 04025 04026 DebugTrace(0, Dbg, "We do not have access\n", 0); 04027 04028 // 04029 // We cannot read/write to the range, so we cannot take out 04030 // the lock. Now if the user wanted to fail immediately then 04031 // we'll complete the Irp, otherwise we'll enqueue this Irp 04032 // to the waiting lock queue 04033 // 04034 04035 if (FailImmediately) { 04036 04037 // 04038 // Set our status and return, the finally clause will 04039 // complete the request 04040 // 04041 04042 DebugTrace(0, Dbg, "And we fail immediately\n", 0); 04043 04044 Iosb->Status = STATUS_LOCK_NOT_GRANTED; 04045 try_return( Results = TRUE ); 04046 04047 } else if (ARGUMENT_PRESENT(Irp)) { 04048 04049 PWAITING_LOCK WaitingLock; 04050 04051 DebugTrace(0, Dbg, "And we enqueue the Irp for later\n", 0); 04052 04053 // 04054 // Allocate a new waiting record, set it to point to the 04055 // waiting Irp, and insert it in the tail of the waiting 04056 // locks queue 04057 // 04058 04059 WaitingLock = FsRtlAllocateWaitingLock(); 04060 04061 // 04062 // Simply raise out if we can't allocate. 04063 // 04064 04065 if (WaitingLock == NULL) { 04066 04067 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 04068 } 04069 04070 WaitingLock->Irp = Irp; 04071 WaitingLock->Context = Context; 04072 IoMarkIrpPending( Irp ); 04073 04074 // 04075 // Add WaitingLock WaitingLockQueue 04076 // 04077 04078 WaitingLock->Link.Next = NULL; 04079 if (LockQueue->WaitingLocks.Next == NULL) { 04080 04081 // 04082 // Create new list 04083 // 04084 04085 LockQueue->WaitingLocks.Next = &WaitingLock->Link; 04086 LockQueue->WaitingLocksTail.Next = &WaitingLock->Link; 04087 04088 } else { 04089 04090 // 04091 // Add waiter to tail of list 04092 // 04093 04094 LockQueue->WaitingLocksTail.Next->Next = &WaitingLock->Link; 04095 LockQueue->WaitingLocksTail.Next = &WaitingLock->Link; 04096 } 04097 04098 04099 // 04100 // Setup IRP in case it's canceled - then set the 04101 // IRP's cancel routine 04102 // 04103 04104 Irp->IoStatus.Information = (ULONG_PTR)LockInfo; 04105 IoSetCancelRoutine( Irp, FsRtlPrivateCancelFileLockIrp ); 04106 04107 if (Irp->Cancel) { 04108 04109 // 04110 // Pull the cancel routine off of the IRP - if it is not 04111 // NULL, this means we won the race with IoCancelIrp and 04112 // will be responsible for cancelling the IRP synchronously. 04113 // If NULL, we lost and our cancel routine is already being 04114 // called for us. 04115 // 04116 // This must be done while holding the lock queue down since 04117 // this is how we synchronize with the cancel. 04118 // 04119 04120 if (IoSetCancelRoutine( Irp, NULL )) { 04121 04122 // 04123 // Irp's cancel routine was not called, do it ourselves. 04124 // Indicate to the cancel routine that he does not need 04125 // to release the cancel spinlock by passing a NULL DO. 04126 // 04127 // The queue will be dropped in order to complete the Irp. 04128 // We communicate the previous IRQL through the Irp itself. 04129 // 04130 04131 Irp->CancelIrql = OldIrql; 04132 FsRtlPrivateCancelFileLockIrp( NULL, Irp ); 04133 ReleaseQueue = FALSE; 04134 } 04135 } 04136 04137 Iosb->Status = STATUS_PENDING; 04138 try_return( Results = TRUE ); 04139 04140 } else { 04141 04142 try_return( Results = FALSE ); 04143 } 04144 } 04145 04146 DebugTrace(0, Dbg, "We have access\n", 0); 04147 04148 if (!FsRtlPrivateInsertLock( LockInfo, FileObject, &FileLockInfo )) { 04149 04150 // 04151 // Resource exhaustion will cause us to fail here. Via the fast call, indicate 04152 // that it may be worthwhile to go around again via the Irp based path. If we 04153 // are already there, simply raise out. 04154 // 04155 04156 if (ViaFastCall) { 04157 04158 try_return( Results = FALSE ); 04159 04160 } else { 04161 04162 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 04163 } 04164 04165 } else { 04166 04167 Iosb->Status = STATUS_SUCCESS; 04168 } 04169 04170 // 04171 // At long last, we're done. 04172 // 04173 04174 Results = TRUE; 04175 04176 try_exit: NOTHING; 04177 } finally { 04178 04179 if (ReleaseQueue) { 04180 04181 FsRtlReleaseLockQueue(LockQueue, OldIrql); 04182 } 04183 04184 // 04185 // Complete the request provided we were given one and it is not a pending status 04186 // 04187 04188 if (!AbnormalTermination() && ARGUMENT_PRESENT(Irp) && (Iosb->Status != STATUS_PENDING)) { 04189 04190 NTSTATUS NewStatus; 04191 04192 // 04193 // We must reference the fileobject for the case that the IRP completion 04194 // fails and we need to lift the lock. Although the only reason we have 04195 // to touch the fileobject in the remove case is to unset the LastLock field, 04196 // we have no way of knowing if we will race with a reference count drop 04197 // and lose. 04198 // 04199 04200 ObReferenceObject( FileObject ); 04201 04202 // 04203 // Complete the request, if the don't get back success then 04204 // we need to possibly remove the lock that we just 04205 // inserted. 04206 // 04207 04208 FsRtlCompleteLockIrp( 04209 LockInfo, 04210 Context, 04211 Irp, 04212 Iosb->Status, 04213 &NewStatus, 04214 FileObject ); 04215 04216 if (!NT_SUCCESS(NewStatus) && NT_SUCCESS(Iosb->Status) ) { 04217 04218 // 04219 // Irp failed, remove the lock which was added 04220 // 04221 04222 FsRtlPrivateRemoveLock ( 04223 LockInfo, 04224 &FileLockInfo, 04225 TRUE ); 04226 } 04227 04228 // 04229 // Lift our private reference to the fileobject. This may induce deletion. 04230 // 04231 04232 ObDereferenceObject( FileObject ); 04233 04234 Iosb->Status = NewStatus; 04235 } 04236 04237 DebugTrace(-1, Dbg, "FsRtlPrivateLock -> %08lx\n", Results); 04238 } 04239 04240 // 04241 // and return to our caller 04242 // 04243 04244 return Results; 04245 }

NTKERNELAPI NTSTATUS FsRtlProcessFileLock IN PFILE_LOCK  FileLock,
IN PIRP  Irp,
IN PVOID Context  OPTIONAL
 

Definition at line 1173 of file filelock.c.

References ASSERT, BooleanFlagOn, Dbg, DebugTrace, FALSE, _IO_STACK_LOCATION::FileObject, _IO_STACK_LOCATION::Flags, FsRtlCompleteLockIrp, FsRtlCompleteRequest, FsRtlFastUnlockAll(), FsRtlFastUnlockAllByKey(), FsRtlFastUnlockSingle(), FsRtlPrivateLock(), IoGetCurrentIrpStackLocation, IoGetRequestorProcess(), Irp, IRP_MJ_LOCK_CONTROL, IRP_MN_LOCK, IRP_MN_UNLOCK_ALL, IRP_MN_UNLOCK_ALL_BY_KEY, IRP_MN_UNLOCK_SINGLE, _IO_STACK_LOCATION::MajorFunction, _IO_STACK_LOCATION::MinorFunction, NTSTATUS(), NULL, _IO_STACK_LOCATION::Parameters, SL_EXCLUSIVE_LOCK, SL_FAIL_IMMEDIATELY, Status, and VOID().

Referenced by UdfCommonLockControl().

01181 : 01182 01183 This routine processes a file lock IRP it does either a lock request, 01184 or an unlock request. It also completes the IRP. Once called the user 01185 (i.e., File System) has relinquished control of the input IRP. 01186 01187 If pool is not available to store the information this routine will raise a 01188 status value indicating insufficient resources. 01189 01190 Arguments: 01191 01192 FileLock - Supplies the File lock being modified/queried. 01193 01194 Irp - Supplies the Irp being processed. 01195 01196 Context - Optionally supplies a context to use when calling the user 01197 alternate IRP completion routine. 01198 01199 Return Value: 01200 01201 NTSTATUS - The return status for the operation. 01202 01203 --*/ 01204 01205 { 01206 PIO_STACK_LOCATION IrpSp; 01207 01208 IO_STATUS_BLOCK Iosb; 01209 NTSTATUS Status; 01210 LARGE_INTEGER ByteOffset; 01211 01212 DebugTrace(+1, Dbg, "FsRtlProcessFileLock, FileLock = %08lx\n", FileLock); 01213 01214 Iosb.Information = 0; 01215 01216 // 01217 // Get a pointer to the current Irp stack location and assert that 01218 // the major function code is for a lock operation 01219 // 01220 01221 IrpSp = IoGetCurrentIrpStackLocation( Irp ); 01222 01223 ASSERT( IrpSp->MajorFunction == IRP_MJ_LOCK_CONTROL ); 01224 01225 // 01226 // Now process the different minor lock operations 01227 // 01228 01229 switch (IrpSp->MinorFunction) { 01230 01231 case IRP_MN_LOCK: 01232 01233 ByteOffset = IrpSp->Parameters.LockControl.ByteOffset; 01234 01235 (VOID) FsRtlPrivateLock( FileLock, 01236 IrpSp->FileObject, 01237 &ByteOffset, 01238 IrpSp->Parameters.LockControl.Length, 01239 IoGetRequestorProcess(Irp), 01240 IrpSp->Parameters.LockControl.Key, 01241 BooleanFlagOn(IrpSp->Flags, SL_FAIL_IMMEDIATELY), 01242 BooleanFlagOn(IrpSp->Flags, SL_EXCLUSIVE_LOCK), 01243 &Iosb, 01244 Irp, 01245 Context, 01246 FALSE ); 01247 01248 break; 01249 01250 case IRP_MN_UNLOCK_SINGLE: 01251 01252 ByteOffset = IrpSp->Parameters.LockControl.ByteOffset; 01253 01254 Iosb.Status = FsRtlFastUnlockSingle( FileLock, 01255 IrpSp->FileObject, 01256 &ByteOffset, 01257 IrpSp->Parameters.LockControl.Length, 01258 IoGetRequestorProcess(Irp), 01259 IrpSp->Parameters.LockControl.Key, 01260 Context, 01261 FALSE ); 01262 01263 FsRtlCompleteLockIrp( FileLock, Context, Irp, Iosb.Status, &Status, NULL ); 01264 break; 01265 01266 case IRP_MN_UNLOCK_ALL: 01267 01268 Iosb.Status = FsRtlFastUnlockAll( FileLock, 01269 IrpSp->FileObject, 01270 IoGetRequestorProcess(Irp), 01271 Context ); 01272 01273 FsRtlCompleteLockIrp( FileLock, Context, Irp, Iosb.Status, &Status, NULL ); 01274 break; 01275 01276 case IRP_MN_UNLOCK_ALL_BY_KEY: 01277 01278 Iosb.Status = FsRtlFastUnlockAllByKey( FileLock, 01279 IrpSp->FileObject, 01280 IoGetRequestorProcess(Irp), 01281 IrpSp->Parameters.LockControl.Key, 01282 Context ); 01283 01284 FsRtlCompleteLockIrp( FileLock, Context, Irp, Iosb.Status, &Status, NULL ); 01285 break; 01286 01287 default: 01288 01289 // 01290 // For all other minor function codes we say they're invalid and 01291 // complete the request. Note that the IRP has not been marked 01292 // pending so this error will be returned directly to the caller. 01293 // 01294 01295 DebugTrace(0, 1, "Invalid LockFile Minor Function Code %08lx\n", IrpSp->MinorFunction); 01296 01297 01298 FsRtlCompleteRequest( Irp, STATUS_INVALID_DEVICE_REQUEST ); 01299 01300 Iosb.Status = STATUS_INVALID_DEVICE_REQUEST; 01301 break; 01302 } 01303 01304 // 01305 // And return to our caller 01306 // 01307 01308 DebugTrace(-1, Dbg, "FsRtlProcessFileLock -> %08lx\n", Iosb.Status); 01309 01310 return Iosb.Status; 01311 }

NTKERNELAPI NTSTATUS FsRtlRegisterUncProvider IN OUT PHANDLE  MupHandle,
IN PUNICODE_STRING  RedirectorDeviceName,
IN BOOLEAN  MailslotsSupported
 

Definition at line 247 of file unc.c.

References DevMup, DevNull, ExAllocatePoolWithTag, Executive, ExFreePool(), FALSE, FsRtlpDRD, FsRtlpIsDfsEnabled(), FsRtlpOpenDev(), FsRtlpRedirs, FsRtlpRegisterProviderWithMUP(), FsRtlpSetSymbolicLink(), FsRtlpUncSemaphore, KeReleaseSemaphore(), KernelMode, KeWaitForSingleObject(), MailslotsSupported, MODULE_POOL_TAG, MupHandle, MupRegKey, NonPagedPool, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, RedirDevName, RtlInitUnicodeString(), VOID(), and ZwLoadDriver().

00254 : 00255 00256 This routine registers a redir as a UNC provider. 00257 00258 Arguments: 00259 00260 Handle - Pointer to a handle. The handle is returned by the routine 00261 to be used when calling FsRtlDeregisterUncProvider. 00262 It is valid only if the routines returns STATUS_SUCCESS. 00263 00264 RedirDevName - The device name of the redir. 00265 00266 MailslotsSupported - If TRUE, this redir supports mailslots. 00267 00268 Return Value: 00269 00270 NTSTATUS - The status of the operation. 00271 00272 --*/ 00273 { 00274 NTSTATUS status; 00275 HANDLE mupHandle = (HANDLE)-1; 00276 UNICODE_STRING mupDriverName; 00277 BOOLEAN dfsEnabled; 00278 00279 PAGED_CODE(); 00280 00281 KeWaitForSingleObject(&FsRtlpUncSemaphore, Executive, KernelMode, FALSE, NULL ); 00282 00283 if (FsRtlpRedirs == 0) { 00284 00285 dfsEnabled = FsRtlpIsDfsEnabled(); 00286 00287 if (dfsEnabled) { 00288 FsRtlpRedirs = 1; 00289 RtlZeroMemory((PVOID) &FsRtlpDRD, sizeof(FsRtlpDRD)); 00290 } 00291 00292 } 00293 00294 switch( FsRtlpRedirs ) { 00295 case 0: 00296 // 00297 // Ok, the MUP isn't there and we don't need to use the 00298 // MUP for the first redir. 00299 // 00300 // We need to return a handle, but we're not really using the MUP yet. 00301 // And we may never use it (if there's only 1 redir). Return 00302 // a handle to the NULL device object, since we're committed to returning 00303 // a handle to our caller. Our caller isn't supposed to do anything with 00304 // the handle except to call FsRtlDeregisterUncProvider() with it. 00305 // 00306 status = FsRtlpOpenDev( &mupHandle, DevNull ); 00307 00308 if( !NT_SUCCESS( status ) ) 00309 break; 00310 00311 // 00312 // Save up enough state to allow us to call the MUP later with 00313 // this registration info if necessary. 00314 // 00315 FsRtlpDRD.RedirDevName.Buffer = ExAllocatePoolWithTag( NonPagedPool, 00316 RedirDevName->MaximumLength, 00317 MODULE_POOL_TAG ); 00318 00319 if( FsRtlpDRD.RedirDevName.Buffer == NULL ) { 00320 status = STATUS_INSUFFICIENT_RESOURCES; 00321 break; 00322 } 00323 00324 FsRtlpDRD.RedirDevName.Length = RedirDevName->Length; 00325 FsRtlpDRD.RedirDevName.MaximumLength = RedirDevName->MaximumLength; 00326 00327 RtlMoveMemory( 00328 (PCHAR)FsRtlpDRD.RedirDevName.Buffer, 00329 RedirDevName->Buffer, 00330 RedirDevName->MaximumLength 00331 ); 00332 00333 FsRtlpDRD.MailslotsSupported = MailslotsSupported; 00334 FsRtlpDRD.ReturnedHandle = mupHandle; 00335 FsRtlpDRD.MupHandle = (HANDLE)-1; 00336 00337 // 00338 // Set the UNC symbolic link to point to the redir we just loaded 00339 // 00340 FsRtlpSetSymbolicLink( RedirDevName ); 00341 00342 break; 00343 00344 default: 00345 // 00346 // This is the second or later redir load -- MUST use the MUP 00347 // 00348 status = FsRtlpOpenDev( &mupHandle, DevMup ); 00349 00350 if( !NT_SUCCESS( status ) ) { 00351 00352 RtlInitUnicodeString( &mupDriverName, MupRegKey ); 00353 00354 (VOID)ZwLoadDriver( &mupDriverName ); 00355 00356 status = FsRtlpOpenDev( &mupHandle, DevMup ); 00357 if( !NT_SUCCESS( status ) ) 00358 break; 00359 } 00360 00361 // 00362 // See if we need to tell the MUP about the first redir that registered 00363 // 00364 if( FsRtlpDRD.RedirDevName.Buffer ) { 00365 00366 status = FsRtlpRegisterProviderWithMUP( mupHandle, 00367 &FsRtlpDRD.RedirDevName, 00368 FsRtlpDRD.MailslotsSupported ); 00369 00370 if( !NT_SUCCESS( status ) ) 00371 break; 00372 00373 FsRtlpDRD.MupHandle = mupHandle; 00374 00375 ExFreePool( FsRtlpDRD.RedirDevName.Buffer ); 00376 FsRtlpDRD.RedirDevName.Buffer = NULL; 00377 00378 // 00379 // Set the UNC symbolic link to point to the MUP 00380 // 00381 RtlInitUnicodeString( &mupDriverName, DevMup ); 00382 FsRtlpSetSymbolicLink( &mupDriverName ); 00383 00384 status = FsRtlpOpenDev( &mupHandle, DevMup ); 00385 00386 if( !NT_SUCCESS( status ) ) 00387 break; 00388 } 00389 00390 // 00391 // Pass the request to the MUP for this redir 00392 // 00393 status = FsRtlpRegisterProviderWithMUP( mupHandle, 00394 RedirDevName, 00395 MailslotsSupported ); 00396 break; 00397 00398 } 00399 00400 if( NT_SUCCESS( status ) ) { 00401 FsRtlpRedirs++; 00402 *MupHandle = mupHandle; 00403 00404 } else { 00405 if( mupHandle != (HANDLE)-1 && mupHandle != NULL ) { 00406 ZwClose( mupHandle ); 00407 } 00408 00409 *MupHandle = (HANDLE)-1; 00410 } 00411 00412 KeReleaseSemaphore(&FsRtlpUncSemaphore, 0, 1, FALSE ); 00413 return status; 00414 }

NTKERNELAPI VOID FsRtlReleaseFile IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 2628 of file fastio.c.

References _DEVICE_OBJECT::DriverObject, ExReleaseResource, _DRIVER_OBJECT::FastIoDispatch, FsRtlExitFileSystem, Header, IoGetBaseFileSystemDeviceObject(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::ReleaseFileForNtCreateSection, and _FAST_IO_DISPATCH::SizeOfFastIoDispatch.

Referenced by CcDeleteSharedCacheMap(), CcWriteBehind(), CcZeroEndOfLastPage(), and MmCreateSection().

02634 : 02635 02636 This routine releases resources acquired by FsRtlAcquireFileExclusive. 02637 02638 Arguments: 02639 02640 FileObject - Pointer to the file object being written. 02641 02642 Return Value: 02643 02644 None. 02645 02646 --*/ 02647 02648 { 02649 PDEVICE_OBJECT DeviceObject; 02650 PFAST_IO_DISPATCH FastIoDispatch; 02651 PFSRTL_COMMON_FCB_HEADER Header; 02652 02653 PAGED_CODE(); 02654 02655 // 02656 // First see if we have to call the file system. 02657 // 02658 02659 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02660 02661 if ((FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch) && 02662 (FastIoDispatch->SizeOfFastIoDispatch > 02663 FIELD_OFFSET( FAST_IO_DISPATCH, ReleaseFileForNtCreateSection )) && 02664 (FastIoDispatch->ReleaseFileForNtCreateSection != NULL)) { 02665 02666 FastIoDispatch->ReleaseFileForNtCreateSection( FileObject ); 02667 FsRtlExitFileSystem(); 02668 return; 02669 } 02670 02671 // 02672 // If there is a main file resource, release that. 02673 // 02674 02675 if ((Header = (PFSRTL_COMMON_FCB_HEADER)FileObject->FsContext) && 02676 (Header->Resource != NULL)) { 02677 02678 ExReleaseResource( Header->Resource ); 02679 FsRtlExitFileSystem(); 02680 return; 02681 } 02682 02683 // 02684 // Nothing to release. 02685 // 02686 02687 return; 02688 }

NTKERNELAPI VOID FsRtlReleaseFileForCcFlush IN PFILE_OBJECT  FileObject  ) 
 

Definition at line 2483 of file fastio.c.

References ASSERT, _DEVICE_OBJECT::DriverObject, ExReleaseResource, _DRIVER_OBJECT::FastIoDispatch, FsRtlExitFileSystem, Header, IoGetBaseFileSystemDeviceObject(), NTSTATUS(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::ReleaseForCcFlush, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, and Status.

Referenced by MiRemoveUnusedSegments(), MmFlushSection(), and MmFlushVirtualMemory().

02489 : 02490 02491 This routine releases a file system resource previously acquired for 02492 the CcFlush. 02493 02494 Arguments: 02495 02496 FileObject - Pointer to the file object being written. 02497 02498 Return Value: 02499 02500 None. 02501 02502 --*/ 02503 02504 { 02505 PDEVICE_OBJECT DeviceObject; 02506 PFAST_IO_DISPATCH FastIoDispatch; 02507 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; 02508 02509 PAGED_CODE(); 02510 02511 // 02512 // First see if we have to call the file system. Note that in the case 02513 // of layered file systems, the layered file system might have the 02514 // dispatch routine, but the file system on which it is layered on may 02515 // not. In that case, the layered file system will return 02516 // STATUS_INVALID_DEVICE_REQUEST. 02517 // 02518 02519 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02520 02521 if ((FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch) && 02522 (FastIoDispatch->SizeOfFastIoDispatch > 02523 FIELD_OFFSET( FAST_IO_DISPATCH, ReleaseForCcFlush )) && 02524 (FastIoDispatch->ReleaseForCcFlush != NULL)) { 02525 02526 Status = FastIoDispatch->ReleaseForCcFlush( FileObject, DeviceObject ); 02527 02528 } 02529 02530 ASSERT( (Status == STATUS_SUCCESS) || (Status == STATUS_INVALID_DEVICE_REQUEST) ); 02531 02532 if (Status == STATUS_INVALID_DEVICE_REQUEST) { 02533 02534 PFSRTL_COMMON_FCB_HEADER Header = FileObject->FsContext; 02535 02536 // 02537 // Free whatever we acquired. 02538 // 02539 02540 if (Header->PagingIoResource != NULL) { 02541 ExReleaseResource( Header->PagingIoResource ); 02542 } 02543 02544 if (Header->Resource != NULL) { 02545 ExReleaseResource( Header->Resource ); 02546 } 02547 } 02548 02549 FsRtlExitFileSystem(); 02550 }

NTKERNELAPI VOID FsRtlReleaseFileForModWrite IN PFILE_OBJECT  FileObject,
IN PERESOURCE  ResourceToRelease
 

Definition at line 2342 of file fastio.c.

References ASSERT, _DEVICE_OBJECT::DriverObject, ExReleaseResource, _DRIVER_OBJECT::FastIoDispatch, IoGetBaseFileSystemDeviceObject(), NTSTATUS(), NULL, PAGED_CODE, _FAST_IO_DISPATCH::ReleaseForModWrite, _FAST_IO_DISPATCH::SizeOfFastIoDispatch, and Status.

Referenced by MiWriteComplete().

02349 : 02350 02351 This routine releases a file system resource previously acquired for 02352 the modified page writer. 02353 02354 Arguments: 02355 02356 FileObject - Pointer to the file object being written. 02357 02358 ResourceToRelease - Supplies the resource to release. Not defined if 02359 FALSE is returned. 02360 02361 Return Value: 02362 02363 None. 02364 02365 --*/ 02366 02367 { 02368 PDEVICE_OBJECT DeviceObject; 02369 PFAST_IO_DISPATCH FastIoDispatch; 02370 NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; 02371 02372 PAGED_CODE(); 02373 02374 // 02375 // First see if we have to call the file system. Note that in the case 02376 // of layered file systems, the layered file system might have the 02377 // dispatch routine, but the file system on which it is layered on may 02378 // not. In that case, the layered file system will return 02379 // STATUS_INVALID_DEVICE_REQUEST. 02380 // 02381 02382 DeviceObject = IoGetBaseFileSystemDeviceObject( FileObject ); 02383 02384 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 02385 if ((FastIoDispatch->SizeOfFastIoDispatch > 02386 FIELD_OFFSET( FAST_IO_DISPATCH, ReleaseForModWrite )) && 02387 (FastIoDispatch->ReleaseForModWrite != NULL)) { 02388 02389 Status = FastIoDispatch->ReleaseForModWrite( FileObject, ResourceToRelease, DeviceObject ); 02390 } 02391 02392 ASSERT( (Status == STATUS_SUCCESS) || (Status == STATUS_INVALID_DEVICE_REQUEST) ); 02393 02394 if (Status == STATUS_INVALID_DEVICE_REQUEST) { 02395 ExReleaseResource( ResourceToRelease ); 02396 } 02397 }

NTKERNELAPI PFSRTL_FILTER_CONTEXT FsRtlRemoveFilterContext IN PFILE_OBJECT  FileObject,
IN PVOID OwnerId  OPTIONAL,
IN PVOID InstanceId  OPTIONAL
 

Definition at line 189 of file filtrctx.c.

References ASSERT, FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS, Header, _FSRTL_FILTER_CONTEXT::InstanceId, _FSRTL_FILTER_CONTEXT::Links, List, MySearchList, NULL, and _FSRTL_FILTER_CONTEXT::OwnerId.

00196 : 00197 00198 This routine deletes filter driver context associated with a stream. 00199 00200 Filter drivers must explicitly remove all context they associate with 00201 a stream (otherwise the underlying filesystem will BugCheck at close). 00202 00203 FsRtlRemoveFilterContext functions identically to FsRtlLookupFilterContext, 00204 except that the returned context has been removed from the list. 00205 00206 Arguments: 00207 00208 FileObject - Specifies the stream of interest. 00209 00210 OwnerId - Used to identify context information belonging to a particular 00211 filter driver. 00212 00213 InstanceId - Used to search for a particular instance of a filter driver 00214 context. If not provided, any of the contexts owned by the filter 00215 driver is removed and returned. 00216 00217 If neither the OwnerId nor the InstanceId is provided, any associated 00218 filter context will be removed and returned. 00219 00220 Return Value: 00221 00222 A pointer to the filter context, or NULL if no match found. 00223 00224 --*/ 00225 00226 { 00227 PFSRTL_COMMON_FCB_HEADER Header; 00228 PFSRTL_FILTER_CONTEXT Ctx, RtnCtx; 00229 PLIST_ENTRY List; 00230 00231 ASSERT(FileObject); 00232 00233 Header = FileObject->FsContext; 00234 00235 if ( !Header || !(Header->Flags2 & FSRTL_FLAG2_SUPPORTS_FILTER_CONTEXTS) ) { 00236 return NULL; 00237 } 00238 00239 ExAcquireFastMutex (Header->FastMutex); 00240 RtnCtx = NULL; 00241 00242 // Use different loops depending on whether we are comparing both Ids or not. 00243 if ( ARGUMENT_PRESENT(InstanceId) ) { 00244 00245 MySearchList (&Header->FilterContexts, List) { 00246 Ctx = CONTAINING_RECORD (List, FSRTL_FILTER_CONTEXT, Links); 00247 if (Ctx->OwnerId == OwnerId && Ctx->InstanceId == InstanceId) { 00248 RtnCtx = Ctx; 00249 break; 00250 } 00251 } 00252 } else if ( ARGUMENT_PRESENT(OwnerId) ) { 00253 00254 MySearchList (&Header->FilterContexts, List) { 00255 Ctx = CONTAINING_RECORD (List, FSRTL_FILTER_CONTEXT, Links); 00256 if (Ctx->OwnerId == OwnerId) { 00257 RtnCtx = Ctx; 00258 break; 00259 } 00260 } 00261 } else if (!IsListEmpty(&Header->FilterContexts)) { 00262 00263 RtnCtx = (PFSRTL_FILTER_CONTEXT) Header->FilterContexts.Flink; 00264 } 00265 00266 if (RtnCtx) { 00267 RemoveEntryList(&RtnCtx->Links); // remove the matched entry 00268 } 00269 ExReleaseFastMutex(Header->FastMutex); 00270 return RtnCtx; 00271 }

NTKERNELAPI VOID FsRtlRemoveLargeMcbEntry IN PLARGE_MCB  Mcb,
IN LONGLONG  Vbn,
IN LONGLONG  SectorCount
 

Definition at line 1528 of file largemcb.c.

References ASSERTMSG, Dbg, DebugTrace, _NONOPAQUE_MCB::FastMutex, FsRtlRemoveMcbEntryPrivate(), PAGED_CODE, PNONOPAQUE_MCB, and VBN.

01536 : 01537 01538 This routine removes a mapping of VBNs to LBNs from an Mcb. The mappings 01539 removed are for 01540 01541 Vbn, 01542 01543 Vbn+1, to 01544 01545 Vbn+(SectorCount-1). 01546 01547 The operation works even if the mapping for a Vbn in the specified range 01548 does not already exist in the Mcb. If the specified range of Vbn includes 01549 the last mapped Vbn in the Mcb then the Mcb mapping shrinks accordingly. 01550 01551 If pool is not available to store the information this routine will raise 01552 a status value indicating insufficient resources. 01553 01554 Arguments: 01555 01556 OpaqueMcb - Supplies the Mcb from which to remove the mapping. 01557 01558 Vbn - Supplies the starting Vbn of the mappings to remove. 01559 01560 SectorCount - Supplies the size of the mappings to remove (in sectors). 01561 01562 Return Value: 01563 01564 None. 01565 01566 --*/ 01567 01568 { 01569 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 01570 01571 VBN Vbn = ((ULONG)LargeVbn); 01572 ULONG SectorCount = ((ULONG)LargeSectorCount); 01573 01574 PAGED_CODE(); 01575 01576 ASSERTMSG("LargeInteger not supported yet ", ((PLARGE_INTEGER)&LargeVbn)->HighPart == 0); 01577 01578 DebugTrace(+1, Dbg, "FsRtlRemoveLargeMcbEntry, Mcb = %08lx\n", Mcb ); 01579 DebugTrace( 0, Dbg, " Vbn = %08lx\n", Vbn ); 01580 DebugTrace( 0, Dbg, " SectorCount = %08lx\n", SectorCount ); 01581 01582 ExAcquireFastMutex( Mcb->FastMutex ); 01583 01584 try { 01585 01586 FsRtlRemoveMcbEntryPrivate( Mcb, Vbn, SectorCount ); 01587 01588 } finally { 01589 01590 ExReleaseFastMutex( Mcb->FastMutex ); 01591 01592 DebugTrace(-1, Dbg, "FsRtlRemoveLargeMcbEntry -> VOID\n", 0 ); 01593 } 01594 01595 return; 01596 }

NTKERNELAPI VOID FsRtlRemoveMcbEntry IN PMCB  Mcb,
IN VBN  Vbn,
IN ULONG  SectorCount
 

Definition at line 392 of file largemcb.c.

References Dbg, DebugTrace, _NONOPAQUE_MCB::FastMutex, FsRtlRemoveMcbEntryPrivate(), PAGED_CODE, and PNONOPAQUE_MCB.

Referenced by UdfAddVmcbMapping(), and UdfRemoveVmcbMapping().

00398 { 00399 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 00400 00401 PAGED_CODE(); 00402 00403 DebugTrace(+1, Dbg, "FsRtlRemoveMcbEntry, Mcb = %08lx\n", Mcb ); 00404 DebugTrace( 0, Dbg, " Vbn = %08lx\n", Vbn ); 00405 DebugTrace( 0, Dbg, " SectorCount = %08lx\n", SectorCount ); 00406 00407 ExAcquireFastMutex( Mcb->FastMutex ); 00408 00409 try { 00410 00411 FsRtlRemoveMcbEntryPrivate( Mcb, 00412 Vbn, 00413 SectorCount ); 00414 00415 } finally { 00416 00417 ExReleaseFastMutex( Mcb->FastMutex ); 00418 00419 DebugTrace(-1, Dbg, "FsRtlRemoveMcbEntry -> VOID\n", 0 ); 00420 } 00421 00422 return; 00423 }

NTKERNELAPI VOID FsRtlResetLargeMcb IN PLARGE_MCB  Mcb,
IN BOOLEAN  SelfSynchronized
 

Definition at line 922 of file largemcb.c.

References _NONOPAQUE_MCB::FastMutex, _NONOPAQUE_MCB::PairCount, and PNONOPAQUE_MCB.

Referenced by UdfInitializeFcbMcb(), and UdfResetVmcb().

00929 : 00930 00931 This routine truncates an Mcb structure to contain zero mapping 00932 pairs. It does not shrink the mapping pairs array. 00933 00934 Arguments: 00935 00936 OpaqueMcb - Supplies a pointer to the Mcb structure to truncate. 00937 00938 SelfSynchronized - Indicates whether the caller is already synchronized 00939 with respect to the Mcb. 00940 00941 Return Value: 00942 00943 None. 00944 00945 --*/ 00946 00947 { 00948 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 00949 00950 if (SelfSynchronized) { 00951 00952 // 00953 // If we are self-synchronized, then all we do is clear out the 00954 // current mapping pair count. 00955 // 00956 00957 Mcb->PairCount = 0; 00958 00959 } else { 00960 00961 // 00962 // Since we are not self-synchronized, we must serialize access to 00963 // the Mcb before clearing the pair count 00964 // 00965 00966 ExAcquireFastMutex( Mcb->FastMutex ); 00967 Mcb->PairCount = 0; 00968 ExReleaseFastMutex( Mcb->FastMutex ); 00969 00970 } 00971 00972 return; 00973 }

NTSTATUS FsRtlSetFileSize IN PFILE_OBJECT  FileObject,
IN OUT PLARGE_INTEGER  FileSize
 

Definition at line 2864 of file fastio.c.

References _IRP::AssociatedIrp, Buffer, _IO_STACK_LOCATION::DeviceObject, Event(), Executive, FALSE, _IO_STACK_LOCATION::FileObject, _IRP::Flags, IoAllocateIrp(), IoCallDriver, IoGetNextIrpStackLocation, IoGetRelatedDeviceObject(), Irp, IRP_MJ_SET_INFORMATION, IRP_PAGING_IO, IRP_SYNCHRONOUS_PAGING_IO, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), _IO_STACK_LOCATION::MajorFunction, NT_SUCCESS, NTSTATUS(), NULL, PAGED_CODE, _IO_STACK_LOCATION::Parameters, PsGetCurrentThread, _IRP::RequestorMode, _DEVICE_OBJECT::StackSize, Status, _IRP::Tail, _IRP::UserEvent, and _IRP::UserIosb.

Referenced by MiCreateDataFileMap(), and MmExtendSection().

02871 : 02872 02873 This routine is used to call the File System to update FileSize 02874 for a file. 02875 02876 It does this without acquiring the file object lock on synchronous file 02877 objects. This routine is therefore safe to call if you already own 02878 file system resources, while IoSetInformation could (and does) lead 02879 to deadlocks. 02880 02881 Arguments: 02882 02883 FileObject - A pointer to a referenced file object. 02884 02885 ValidDataLength - Pointer to new FileSize. 02886 02887 Return Value: 02888 02889 Status of operation. 02890 02891 --*/ 02892 02893 { 02894 PIO_STACK_LOCATION IrpSp; 02895 PDEVICE_OBJECT DeviceObject; 02896 NTSTATUS Status; 02897 FILE_END_OF_FILE_INFORMATION Buffer; 02898 IO_STATUS_BLOCK IoStatus; 02899 KEVENT Event; 02900 PIRP Irp; 02901 02902 PAGED_CODE(); 02903 02904 // 02905 // Copy FileSize to our buffer. 02906 // 02907 02908 Buffer.EndOfFile = *FileSize; 02909 02910 // 02911 // Initialize the event. 02912 // 02913 02914 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 02915 02916 // 02917 // Begin by getting a pointer to the device object that the file resides 02918 // on. 02919 // 02920 02921 DeviceObject = IoGetRelatedDeviceObject( FileObject ); 02922 02923 // 02924 // Allocate an I/O Request Packet (IRP) for this in-page operation. 02925 // 02926 02927 Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); 02928 if (Irp == NULL) { 02929 02930 return STATUS_INSUFFICIENT_RESOURCES; 02931 } 02932 02933 // 02934 // Get a pointer to the first stack location in the packet. This location 02935 // will be used to pass the function codes and parameters to the first 02936 // driver. 02937 // 02938 02939 IrpSp = IoGetNextIrpStackLocation( Irp ); 02940 02941 // 02942 // Fill in the IRP according to this request, setting the flags to 02943 // just cause IO to set the event and deallocate the Irp. 02944 // 02945 02946 Irp->Flags = IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO; 02947 Irp->RequestorMode = KernelMode; 02948 Irp->UserIosb = &IoStatus; 02949 Irp->UserEvent = &Event; 02950 Irp->Tail.Overlay.OriginalFileObject = FileObject; 02951 Irp->Tail.Overlay.Thread = PsGetCurrentThread(); 02952 Irp->AssociatedIrp.SystemBuffer = &Buffer; 02953 02954 // 02955 // Fill in the normal set file parameters. 02956 // 02957 02958 IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION; 02959 IrpSp->FileObject = FileObject; 02960 IrpSp->DeviceObject = DeviceObject; 02961 IrpSp->Parameters.SetFile.Length = sizeof(FILE_END_OF_FILE_INFORMATION); 02962 IrpSp->Parameters.SetFile.FileInformationClass = FileEndOfFileInformation; 02963 02964 // 02965 // Queue the packet to the appropriate driver based on whether or not there 02966 // is a VPB associated with the device. This routine should not raise. 02967 // 02968 02969 Status = IoCallDriver( DeviceObject, Irp ); 02970 02971 // 02972 // If pending is returned (which is a successful status), 02973 // we must wait for the request to complete. 02974 // 02975 02976 if (Status == STATUS_PENDING) { 02977 KeWaitForSingleObject( &Event, 02978 Executive, 02979 KernelMode, 02980 FALSE, 02981 (PLARGE_INTEGER)NULL); 02982 } 02983 02984 // 02985 // If we got an error back in Status, then the Iosb 02986 // was not written, so we will just copy the status 02987 // there, then test the final status after that. 02988 // 02989 02990 if (!NT_SUCCESS(Status)) { 02991 IoStatus.Status = Status; 02992 } 02993 02994 return IoStatus.Status; 02995 } }

NTKERNELAPI BOOLEAN FsRtlSplitLargeMcb IN PLARGE_MCB  Mcb,
IN LONGLONG  Vbn,
IN LONGLONG  Amount
 

Definition at line 2066 of file largemcb.c.

References ASSERTMSG, Dbg, DebugTrace, FALSE, _NONOPAQUE_MCB::FastMutex, FsRtlAddLargeEntry(), FsRtlFindLargeIndex(), Index, LBN, _NONOPAQUE_MCB::Mapping, PAGED_CODE, _NONOPAQUE_MCB::PairCount, PNONOPAQUE_MCB, PreviousEndingLbn, StartingLbn, StartingVbn, TRUE, try_return, UNUSED_LBN, and VBN.

02074 : 02075 02076 This routine is used to create a hole within an MCB, by shifting the 02077 mapping of Vbns. All mappings above the input vbn are shifted by the 02078 amount specified and while keeping their current lbn value. Pictorially 02079 we have as input the following MCB 02080 02081 VBN : LargeVbn-1 LargeVbn N 02082 +-----------------+------------------+ 02083 LBN : X Y 02084 02085 And after the split we have 02086 02087 VBN : LargeVbn-1 LargeVbn+Amount N+Amount 02088 +-----------------+.............+---------------------------+ 02089 LBN : X UnusedLbn Y 02090 02091 When doing the split we have a few cases to consider. They are: 02092 02093 1. The input Vbn is beyond the last run. In this case this operation 02094 is a noop. 02095 02096 2. The input Vbn is within or adjacent to a existing run of unused Lbns. 02097 In this case we simply need to extend the size of the existing hole 02098 and shift succeeding runs. 02099 02100 3. The input Vbn is between two existing runs, including the an input vbn 02101 value of zero. In this case we need to add a new entry for the hole 02102 and shift succeeding runs. 02103 02104 4. The input Vbn is within an existing run. In this case we need to add 02105 two new entries to contain the split run and the hole. 02106 02107 If pool is not available to store the information this routine will raise a 02108 status value indicating insufficient resources. 02109 02110 Arguments: 02111 02112 OpaqueMcb - Supplies the Mcb in which to add the new mapping. 02113 02114 Vbn - Supplies the starting Vbn that is to be shifted. 02115 02116 Amount - Supplies the amount to shift by. 02117 02118 Return Value: 02119 02120 BOOLEAN - TRUE if the mapping was successfully shifted, and FALSE otherwise. 02121 If FALSE is returned then the Mcb is not changed. 02122 02123 --*/ 02124 02125 { 02126 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 02127 02128 VBN Vbn = ((ULONG)LargeVbn); 02129 ULONG Amount = ((ULONG)LargeAmount); 02130 02131 ULONG Index; 02132 02133 BOOLEAN Result; 02134 02135 ULONG i; 02136 02137 PAGED_CODE(); 02138 02139 DebugTrace(+1, Dbg, "FsRtlSplitLargeMcb, Mcb = %08lx\n", Mcb ); 02140 DebugTrace( 0, Dbg, " Vbn = %08lx\n", Vbn ); 02141 DebugTrace( 0, Dbg, " Amount = %08lx\n", Amount ); 02142 02143 ExAcquireFastMutex( Mcb->FastMutex ); 02144 02145 ASSERTMSG("LargeInteger not supported yet ", ((((PLARGE_INTEGER)&LargeVbn)->HighPart == 0) || 02146 (Mcb->PairCount == 0))); 02147 ASSERTMSG("LargeInteger not supported yet ", ((((PLARGE_INTEGER)&LargeAmount)->HighPart == 0) || 02148 (Mcb->PairCount == 0))); 02149 02150 try { 02151 02152 // 02153 // First lookup the index for the entry that we are going to split. 02154 // If we can't find the entry then there is nothing to split. This 02155 // takes care of the case where the input vbn is beyond the last run 02156 // in the mcb 02157 // 02158 02159 if (!FsRtlFindLargeIndex( Mcb, Vbn, &Index)) { 02160 02161 try_return(Result = FALSE); 02162 } 02163 02164 // 02165 // Now check if the input Vbn is within a hole 02166 // 02167 02168 if (StartingLbn(Mcb,Index) == UNUSED_LBN) { 02169 02170 // 02171 // Before: --PreviousRun--||--IndexHole--||--FollowingRun-- 02172 // After: --PreviousRun--||----IndexHole----||--FollowingRun-- 02173 // 02174 // In this case the vbn is somewhere within the hole and we 02175 // simply need to added the amount of each existing run 02176 // beyond the hole. 02177 // 02178 02179 // 02180 // In this case there is really nothing to do here because the 02181 // ending code will already shift the runs by proper amount 02182 // starting at index 02183 // 02184 02185 NOTHING; 02186 02187 // 02188 // Now check if the input vbn is between a hole and an existing run. 02189 // 02190 02191 } else if ((StartingVbn(Mcb,Index) == Vbn) && (Index != 0) && (PreviousEndingLbn(Mcb,Index) == UNUSED_LBN)) { 02192 02193 // 02194 // Before: --Hole--||--IndexRun-- 02195 // After: --Hole------||--IndexRun-- 02196 // 02197 // In this case the vbn points to the start of the existing 02198 // run and we need to do the split between the hole and the 02199 // existing run by simply adding the amount to each existing 02200 // run beyond the hole. 02201 // 02202 02203 // 02204 // In this case we need to decement the index by 1 and then 02205 // fall to the bottom code which will do the shifting for us 02206 // 02207 02208 Index -= 1; 02209 02210 // 02211 // Now check if the input vbn is between two existing runs 02212 // 02213 02214 } else if (StartingVbn(Mcb,Index) == Vbn) { 02215 02216 // 02217 // Before: --PreviousRun--||--IndexRun-- 02218 // After: --PreviousRun--||--NewHole--||--IndexRun-- 02219 // 02220 // Before: 0:|--IndexRun-- 02221 // After: 0:|--NewHole--||--IndexRun-- 02222 // 02223 // In this case the vbn points to the start of an existing 02224 // run and the preceeding is either a real run or the start 02225 // of mapping pairs We simply add a new entry for the hole 02226 // and shift succeeding runs. 02227 // 02228 02229 FsRtlAddLargeEntry( Mcb, Index, 1 ); 02230 02231 (Mcb->Mapping)[Index].Lbn = (LBN)UNUSED_LBN; 02232 (Mcb->Mapping)[Index].NextVbn = Vbn + Amount; 02233 02234 Index += 1; 02235 02236 // 02237 // Otherwise the input vbn is inside an existing run 02238 // 02239 02240 } else { 02241 02242 // 02243 // Before: --IndexRun-- 02244 // After: --SplitRun--||--NewHole--||--SplitRun-- 02245 // 02246 // In this case the vbn points within an existing run 02247 // we need to add two new extries for hole and split 02248 // run and shift succeeding runs 02249 // 02250 02251 FsRtlAddLargeEntry( Mcb, Index, 2 ); 02252 02253 (Mcb->Mapping)[Index].Lbn = (Mcb->Mapping)[Index+2].Lbn; 02254 (Mcb->Mapping)[Index].NextVbn = Vbn; 02255 02256 (Mcb->Mapping)[Index+1].Lbn = (LBN)UNUSED_LBN; 02257 (Mcb->Mapping)[Index+1].NextVbn = Vbn + Amount; 02258 02259 (Mcb->Mapping)[Index+2].Lbn = (Mcb->Mapping)[Index+2].Lbn + 02260 StartingVbn(Mcb, Index+1) - 02261 StartingVbn(Mcb, Index); 02262 02263 Index += 2; 02264 02265 } 02266 02267 // 02268 // At this point we have completed most of the work we now need to 02269 // shift existing runs from the index to the end of the mappings 02270 // by the specified amount 02271 // 02272 02273 for (i = Index; i < Mcb->PairCount; i += 1) { 02274 02275 (Mcb->Mapping)[i].NextVbn += Amount; 02276 } 02277 02278 Result = TRUE; 02279 02280 try_exit: NOTHING; 02281 } finally { 02282 02283 ExReleaseFastMutex( Mcb->FastMutex ); 02284 02285 DebugTrace(-1, Dbg, "FsRtlSplitLargeMcb -> %08lx\n", Result ); 02286 } 02287 02288 return Result; 02289 }

NTKERNELAPI NTSTATUS FsRtlSyncVolumes IN PDEVICE_OBJECT  TargetDevice,
IN PLARGE_INTEGER ByteOffset  OPTIONAL,
IN PLARGE_INTEGER  ByteCount
 

Definition at line 96 of file faulttol.c.

References ASSERT, Event(), Executive, FALSE, IoBuildDeviceIoControlRequest(), IoCallDriver, Irp, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), NTSTATUS(), NULL, Status, and TRUE.

00104 : 00105 00106 This routine signals a device driver that it must sync redundant 00107 members of a mirror from the primary member. This is typically 00108 called after the file system determines that a volume is dirty. 00109 00110 Arguments: 00111 00112 TargetDevice - Supplies the device to sync. 00113 00114 ByteOffset - If specified, gives the location to start syncing 00115 00116 ByteCount - Gives the byte count to sync. Ignored if StartingOffset 00117 not specified. 00118 00119 Return Value: 00120 00121 NTSTATUS - The result of the operation. This will be 00122 STATUS_INVALID_DEVICE_REQUEST is the volume is not a mirror. 00123 00124 --*/ 00125 00126 { 00127 00128 #if 0 // Mike Glass says we no longer need to do this. 3/3/94 00129 00130 PIRP Irp; 00131 KEVENT Event; 00132 IO_STATUS_BLOCK Iosb; 00133 NTSTATUS Status; 00134 BOOLEAN RangeSpecified; 00135 FT_SYNC_INFORMATION SyncInfo; 00136 00137 KeInitializeEvent( &Event, NotificationEvent, FALSE ); 00138 00139 // 00140 // If the user specified a range, capture it. 00141 // 00142 00143 if (ARGUMENT_PRESENT(ByteOffset)) { 00144 00145 SyncInfo.ByteOffset = *ByteOffset; 00146 SyncInfo.ByteCount = *ByteCount; 00147 00148 RangeSpecified = TRUE; 00149 00150 } else { 00151 00152 RangeSpecified = FALSE; 00153 } 00154 00155 Irp = IoBuildDeviceIoControlRequest( FT_SYNC_REDUNDANT_COPY, 00156 TargetDevice, 00157 RangeSpecified ? &SyncInfo : NULL, 00158 RangeSpecified ? 00159 sizeof(FT_SYNC_INFORMATION) : 0, 00160 NULL, 00161 0, 00162 FALSE, 00163 &Event, 00164 &Iosb ); 00165 00166 if ( Irp == NULL ) { 00167 00168 return STATUS_INSUFFICIENT_RESOURCES; 00169 } 00170 00171 Status = IoCallDriver( TargetDevice, Irp ); 00172 00173 00174 if (Status == STATUS_PENDING) { 00175 Status = KeWaitForSingleObject( &Event, 00176 Executive, 00177 KernelMode, 00178 FALSE, 00179 NULL ); 00180 00181 ASSERT( Status == STATUS_SUCCESS ); 00182 00183 Status = Iosb.Status; 00184 } 00185 00186 return Status; 00187 #else 00188 return STATUS_SUCCESS; 00189 00190 #endif //0 00191 }

NTKERNELAPI VOID FsRtlTeardownFilterContexts IN PLIST_ENTRY  FilterContexts  ) 
 

Definition at line 276 of file filtrctx.c.

References _FSRTL_FILTER_CONTEXT::FreeCallback.

00281 : 00282 00283 This routine is called by filesystems to free the filter contexts 00284 associated with an FSRTL_COMMON_FCB_HEADER by calling the FreeCallback 00285 routine for each FilterContext. 00286 00287 It is assumed that we do not need to acquire the FastMutex. 00288 00289 Arguments: 00290 00291 FilterContexts - the address of the FilterContexts field within 00292 the FSRTL_COMMON_FCB_HEADER of the structure being torn down 00293 by the filesystem. 00294 00295 Return Value: 00296 00297 None. 00298 00299 --*/ 00300 00301 { 00302 PFSRTL_FILTER_CONTEXT ctx; 00303 PLIST_ENTRY ptr; 00304 00305 ptr = FilterContexts->Flink; 00306 00307 while ( ptr != FilterContexts ) { 00308 ctx = CONTAINING_RECORD (ptr, FSRTL_FILTER_CONTEXT, Links); 00309 ptr = ptr->Flink; 00310 (*ctx->FreeCallback)(ctx); 00311 } 00312 00313 InitializeListHead( FilterContexts ); 00314 return; 00315 }

NTKERNELAPI VOID FsRtlTruncateLargeMcb IN PLARGE_MCB  Mcb,
IN LONGLONG  Vbn
 

Definition at line 743 of file largemcb.c.

References ASSERTMSG, Dbg, DebugTrace, EXCEPTION_EXECUTE_HANDLER, ExFreePool(), _NONOPAQUE_MCB::FastMutex, FsRtlAllocateFirstMapping, FsRtlFindLargeIndex(), FsRtlpAllocatePool, Index, INITIAL_MAXIMUM_PAIR_COUNT, _NONOPAQUE_MCB::Mapping, _NONOPAQUE_MCB::MaximumPairCount, NextStartingVbn, NULL, PAGED_CODE, PagedPool, _NONOPAQUE_MCB::PairCount, PMAPPING, PNONOPAQUE_MCB, _NONOPAQUE_MCB::PoolType, StartingLbn, UNUSED_LBN, and VBN.

Referenced by FsRtlTruncateMcb().

00750 : 00751 00752 This routine truncates an Mcb structure to the specified Vbn. 00753 After calling this routine the Mcb will only contain mappings 00754 up to and not including the input vbn. 00755 00756 Arguments: 00757 00758 OpaqueMcb - Supplies a pointer to the Mcb structure to truncate. 00759 00760 LargeVbn - Specifies the last Vbn at which is no longer to be 00761 mapped. 00762 00763 Return Value: 00764 00765 None. 00766 00767 --*/ 00768 00769 { 00770 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 00771 00772 VBN Vbn = ((ULONG)LargeVbn); 00773 ULONG Index; 00774 00775 PAGED_CODE(); 00776 00777 DebugTrace(+1, Dbg, "FsRtlTruncateLargeMcb, Mcb = %08lx\n", Mcb ); 00778 00779 ExAcquireFastMutex( Mcb->FastMutex ); 00780 00781 ASSERTMSG("LargeInteger not supported yet ", ((((PLARGE_INTEGER)&LargeVbn)->HighPart == 0) || 00782 (Mcb->PairCount == 0) || 00783 ((((PLARGE_INTEGER)&LargeVbn)->HighPart == 0x7FFFFFFF) && 00784 (((ULONG)LargeVbn) == 0xFFFFFFFF)))); 00785 00786 try { 00787 00788 // 00789 // Do a quick test to see if we are truncating the entire Mcb. 00790 // 00791 00792 if (Vbn == 0) { 00793 00794 Mcb->PairCount = 0; 00795 00796 } else if (Mcb->PairCount > 0) { 00797 00798 // 00799 // Find the index for the entry with the last Vcn we want to keep. 00800 // There is nothing to do if the Mcb already ends prior to 00801 // this point. 00802 // 00803 00804 if (FsRtlFindLargeIndex(Mcb, Vbn - 1, &Index)) { 00805 00806 // 00807 // If this entry currently describes a hole then 00808 // truncate to the previous entry. 00809 // 00810 00811 if (StartingLbn(Mcb, Index) == UNUSED_LBN) { 00812 00813 Mcb->PairCount = Index; 00814 00815 // 00816 // Otherwise we will truncate the Mcb to this point. Truncate 00817 // the number of Vbns of this run if necessary. 00818 // 00819 00820 } else { 00821 00822 Mcb->PairCount = Index + 1; 00823 00824 if (NextStartingVbn(Mcb, Index) > Vbn) { 00825 00826 (Mcb->Mapping)[Index].NextVbn = Vbn; 00827 } 00828 } 00829 } 00830 } 00831 00832 // 00833 // Now see if we can shrink the allocation for the mapping pairs. 00834 // We'll shrink the mapping pair buffer if the new pair count will 00835 // fit within a quarter of the current maximum pair count and the 00836 // current maximum is greater than the initial pair count. 00837 // 00838 00839 if ((Mcb->PairCount < (Mcb->MaximumPairCount / 4)) && 00840 (Mcb->MaximumPairCount > INITIAL_MAXIMUM_PAIR_COUNT)) { 00841 00842 ULONG NewMax; 00843 PMAPPING Mapping; 00844 00845 // 00846 // We need to allocate a new mapping so compute a new maximum pair 00847 // count. We'll allocate double the current pair count, but never 00848 // less than the initial pair count. 00849 // 00850 00851 NewMax = Mcb->PairCount * 2; 00852 00853 if (NewMax < INITIAL_MAXIMUM_PAIR_COUNT) { 00854 NewMax = INITIAL_MAXIMUM_PAIR_COUNT; 00855 } 00856 00857 // 00858 // Be careful to trap failures due to resource exhaustion. 00859 // 00860 00861 try { 00862 00863 if (NewMax == INITIAL_MAXIMUM_PAIR_COUNT && Mcb->PoolType == PagedPool) { 00864 00865 Mapping = FsRtlAllocateFirstMapping(); 00866 00867 } else { 00868 00869 Mapping = FsRtlpAllocatePool( Mcb->PoolType, sizeof(MAPPING) * NewMax ); 00870 } 00871 00872 } except (EXCEPTION_EXECUTE_HANDLER) { 00873 00874 Mapping = NULL; 00875 } 00876 00877 // 00878 // Now check if we really got a new buffer 00879 // 00880 00881 if (Mapping != NULL) { 00882 00883 // 00884 // Now copy over the old mapping to the new buffer 00885 // 00886 00887 RtlCopyMemory( Mapping, Mcb->Mapping, sizeof(MAPPING) * Mcb->PairCount ); 00888 00889 // 00890 // Deallocate the old buffer. This should never be the size of an 00891 // initial mapping ... 00892 // 00893 00894 ExFreePool( Mcb->Mapping ); 00895 00896 // 00897 // And set up the new buffer in the Mcb 00898 // 00899 00900 Mcb->Mapping = Mapping; 00901 Mcb->MaximumPairCount = NewMax; 00902 } 00903 } 00904 00905 } finally { 00906 00907 ExReleaseFastMutex( Mcb->FastMutex ); 00908 } 00909 00910 // 00911 // And return to our caller 00912 // 00913 00914 DebugTrace(-1, Dbg, "FsRtlTruncateLargeMcb -> VOID\n", 0 ); 00915 00916 return; 00917 }

NTKERNELAPI VOID FsRtlTruncateMcb IN PMCB  Mcb,
IN VBN  Vbn
 

Definition at line 361 of file largemcb.c.

References FsRtlTruncateLargeMcb(), and PAGED_CODE.

00365 { 00366 PAGED_CODE(); 00367 00368 FsRtlTruncateLargeMcb( (PLARGE_MCB)Mcb, 00369 (LONGLONG)(Vbn) ); 00370 00371 return; 00372 }

NTKERNELAPI VOID FsRtlUninitializeFileLock IN PFILE_LOCK  FileLock  ) 
 

Definition at line 995 of file filelock.c.

References _IRP::CancelIrql, _WAITING_LOCK::Context, Dbg, DebugTrace, _LOCK_QUEUE::ExclusiveLockTree, FsRtlAcquireLockQueue, FsRtlCompleteLockIrp, FsRtlFreeExclusiveLock(), FsRtlFreeLockInfo(), FsRtlFreeLockTreeNode(), FsRtlFreeSharedLock(), FsRtlFreeWaitingLock(), FsRtlReleaseLockQueue, IoAcquireCancelSpinLock(), IoReleaseCancelSpinLock(), IoSetCancelRoutine, _IRP::IoStatus, _WAITING_LOCK::Irp, Irp, _EX_LOCK::Links, _LOCKTREE_NODE::Links, _LOCK_INFO::LockQueue, _LOCKTREE_NODE::Locks, NTSTATUS(), NULL, PEX_LOCK, PLOCK_INFO, PLOCKTREE_NODE, PSH_LOCK, PWAITING_LOCK, RtlDeleteNoSplay(), _LOCK_QUEUE::SharedLockTree, and _LOCK_QUEUE::WaitingLocks.

Referenced by FsRtlFreeFileLock().

01001 : 01002 01003 This routine uninitializes a FILE_LOCK structure. After calling this 01004 routine the File lock must be reinitialized before being used again. 01005 01006 This routine will free all files locks and completes any outstanding 01007 lock requests as a result of cleaning itself up. 01008 01009 Arguments: 01010 01011 FileLock - Supplies a pointer to the FILE_LOCK struture being 01012 decommissioned. 01013 01014 Return Value: 01015 01016 None. 01017 01018 --*/ 01019 01020 { 01021 PLOCK_INFO LockInfo; 01022 PSH_LOCK ShLock; 01023 PEX_LOCK ExLock; 01024 PSINGLE_LIST_ENTRY Link; 01025 PWAITING_LOCK WaitingLock; 01026 PLOCKTREE_NODE LockTreeNode; 01027 PIRP Irp; 01028 NTSTATUS NewStatus; 01029 KIRQL OldIrql; 01030 PKPRCB Prcb; 01031 01032 DebugTrace(+1, Dbg, "FsRtlUninitializeFileLock, FileLock = %08lx\n", FileLock); 01033 01034 if ((LockInfo = (PLOCK_INFO) FileLock->LockInformation) == NULL) { 01035 return ; 01036 } 01037 01038 // 01039 // Lock the queue 01040 // 01041 01042 FsRtlAcquireLockQueue(&LockInfo->LockQueue, &OldIrql); 01043 01044 // 01045 // Free lock trees 01046 // 01047 01048 while (LockInfo->LockQueue.SharedLockTree != NULL) { 01049 01050 LockTreeNode = CONTAINING_RECORD(LockInfo->LockQueue.SharedLockTree, LOCKTREE_NODE, Links); 01051 01052 // 01053 // Remove all locks associated with the root node 01054 // 01055 01056 while (LockTreeNode->Locks.Next != NULL) { 01057 Link = PopEntryList (&LockTreeNode->Locks); 01058 ShLock = CONTAINING_RECORD( Link, SH_LOCK, Link ); 01059 01060 FsRtlFreeSharedLock(ShLock); 01061 } 01062 01063 // 01064 // Slice off the root node of the tree 01065 // 01066 01067 RtlDeleteNoSplay(&LockTreeNode->Links, &LockInfo->LockQueue.SharedLockTree); 01068 01069 FsRtlFreeLockTreeNode(LockTreeNode); 01070 } 01071 01072 while (LockInfo->LockQueue.ExclusiveLockTree != NULL) { 01073 01074 ExLock = CONTAINING_RECORD(LockInfo->LockQueue.ExclusiveLockTree, EX_LOCK, Links); 01075 01076 RtlDeleteNoSplay(&ExLock->Links, &LockInfo->LockQueue.ExclusiveLockTree); 01077 01078 FsRtlFreeExclusiveLock(ExLock); 01079 } 01080 01081 // 01082 // Free WaitingLockQueue 01083 // 01084 01085 while (LockInfo->LockQueue.WaitingLocks.Next != NULL) { 01086 01087 Link = PopEntryList( &LockInfo->LockQueue.WaitingLocks ); 01088 WaitingLock = CONTAINING_RECORD( Link, WAITING_LOCK, Link ); 01089 01090 Irp = WaitingLock->Irp; 01091 01092 // 01093 // To complete an irp in the waiting queue we need to 01094 // void the cancel routine (protected by a spinlock) before 01095 // we can complete the irp 01096 // 01097 01098 FsRtlReleaseLockQueue (&LockInfo->LockQueue, OldIrql); 01099 01100 IoAcquireCancelSpinLock( &Irp->CancelIrql ); 01101 IoSetCancelRoutine( Irp, NULL ); 01102 IoReleaseCancelSpinLock( Irp->CancelIrql ); 01103 01104 Irp->IoStatus.Information = 0; 01105 01106 FsRtlCompleteLockIrp( 01107 LockInfo, 01108 WaitingLock->Context, 01109 Irp, 01110 STATUS_RANGE_NOT_LOCKED, 01111 &NewStatus, 01112 NULL ); 01113 01114 FsRtlAcquireLockQueue(&LockInfo->LockQueue, &OldIrql); 01115 FsRtlFreeWaitingLock( WaitingLock ); 01116 } 01117 01118 // 01119 // Free pool used to track the lock info on this file 01120 // 01121 01122 FsRtlReleaseLockQueue( &LockInfo->LockQueue, OldIrql ); 01123 FsRtlFreeLockInfo( LockInfo ); 01124 01125 // 01126 // Unlink LockInfo from FileLock 01127 // 01128 01129 FileLock->LockInformation = NULL; 01130 01131 // 01132 // And return to our caller 01133 // 01134 01135 DebugTrace(-1, Dbg, "FsRtlUninitializeFileLock -> VOID\n", 0 ); 01136 return; 01137 }

NTKERNELAPI VOID FsRtlUninitializeLargeMcb IN PLARGE_MCB  Mcb  ) 
 

Definition at line 670 of file largemcb.c.

References Dbg, DebugTrace, ExFreePool(), _NONOPAQUE_MCB::FastMutex, FsRtlFreeFastMutex, FsRtlFreeFirstMapping, INITIAL_MAXIMUM_PAIR_COUNT, _NONOPAQUE_MCB::Mapping, _NONOPAQUE_MCB::MaximumPairCount, NULL, PagedPool, PNONOPAQUE_MCB, and _NONOPAQUE_MCB::PoolType.

Referenced by FsRtlUninitializeMcb(), UdfDeletePcb(), and UdfUninitializeFcbMcb().

00676 : 00677 00678 This routine uninitializes an Mcb structure. After calling this routine 00679 the input Mcb structure must be re-initialized before being used again. 00680 00681 Arguments: 00682 00683 OpaqueMcb - Supplies a pointer to the Mcb structure to uninitialize. 00684 00685 Return Value: 00686 00687 None. 00688 00689 --*/ 00690 00691 { 00692 PNONOPAQUE_MCB Mcb = (PNONOPAQUE_MCB)OpaqueMcb; 00693 00694 DebugTrace(+1, Dbg, "FsRtlUninitializeLargeMcb, Mcb = %08lx\n", Mcb ); 00695 00696 // 00697 // Protect against some user calling us to uninitialize an mcb twice 00698 // 00699 00700 if (Mcb->FastMutex == NULL) { 00701 00702 // ASSERTMSG("Being called to uninitialize an Mcb that is already Uninitialized ", FALSE); 00703 00704 return; 00705 } 00706 00707 // 00708 // Deallocate the FastMutex and mapping buffer 00709 // 00710 00711 FsRtlFreeFastMutex( Mcb->FastMutex ); 00712 00713 Mcb->FastMutex = NULL; 00714 00715 if ((Mcb->PoolType == PagedPool) && (Mcb->MaximumPairCount == INITIAL_MAXIMUM_PAIR_COUNT)) { 00716 00717 FsRtlFreeFirstMapping( Mcb->Mapping ); 00718 00719 } else { 00720 00721 ExFreePool( Mcb->Mapping ); 00722 } 00723 00724 // 00725 // Now zero our all of the fields in the Mcb 00726 // 00727 00728 //**** Mcb->MaximumPairCount = 0; 00729 //**** Mcb->PairCount = 0; 00730 //**** Mcb->Mapping = NULL; 00731 00732 // 00733 // And return to our caller 00734 // 00735 00736 DebugTrace(-1, Dbg, "FsRtlUninitializeLargeMcb -> VOID\n", 0 ); 00737 00738 return; 00739 }

NTKERNELAPI VOID FsRtlUninitializeMcb IN PMCB  Mcb  ) 
 

Definition at line 348 of file largemcb.c.

References FsRtlUninitializeLargeMcb(), and PAGED_CODE.

Referenced by UdfInitializeVmcb(), and UdfUninitializeVmcb().

00352 { 00353 PAGED_CODE(); 00354 00355 FsRtlUninitializeLargeMcb( (PLARGE_MCB)Mcb ); 00356 00357 return; 00358 }

NTKERNELAPI VOID FsRtlUninitializeOplock IN OUT POPLOCK  Oplock  ) 
 

Definition at line 413 of file oplock.c.

References _IRP::CancelIrql, _WAITING_IRP::CompletionRoutine, _WAITING_IRP::Context, Dbg, DebugTrace, ExAcquireFastMutexUnsafe(), ExFreePool(), ExReleaseFastMutexUnsafe(), _NONOPAQUE_OPLOCK::FastMutex, _NONOPAQUE_OPLOCK::FileObject, FsRtlCompleteRequest, IoAcquireCancelSpinLock(), IoGetCurrentIrpStackLocation, IoReleaseCancelSpinLock(), IoSetCancelRoutine, _IRP::IoStatus, _WAITING_IRP::Irp, Irp, _NONOPAQUE_OPLOCK::IrpExclusiveOplock, _NONOPAQUE_OPLOCK::IrpOplocksII, NULL, ObDereferenceObject, PNONOPAQUE_OPLOCK, PWAITING_IRP, and _NONOPAQUE_OPLOCK::WaitingIrps.

Referenced by UdfDeleteFcb().

00419 : 00420 00421 This routine uninitializes an OPLOCK structure. After calling this 00422 routine, the OPLOCK structure must be reinitialized before being 00423 used again. 00424 00425 Arguments: 00426 00427 Oplock - Supplies the address of an opaque OPLOCK structure. 00428 00429 Return Value: 00430 00431 None. 00432 00433 --*/ 00434 00435 00436 { 00437 PNONOPAQUE_OPLOCK ThisOplock; 00438 00439 DebugTrace(+1, Dbg, "FsRtlUninitializeOplock: Oplock -> %08lx\n", *Oplock ); 00440 00441 // 00442 // If the Oplock structure has not been allocated, there is no action 00443 // to take. 00444 // 00445 00446 if (*Oplock != NULL) { 00447 00448 // 00449 // Remove this from the user's structure. 00450 // 00451 00452 ThisOplock = (PNONOPAQUE_OPLOCK) *Oplock; 00453 00454 *Oplock = NULL; 00455 00456 // 00457 // Grab the waiting lock queue mutex to exclude anyone from messing 00458 // with the queue while we're using it 00459 // 00460 00461 ExAcquireFastMutexUnsafe( ThisOplock->FastMutex ); 00462 00463 try { 00464 00465 PIRP Irp; 00466 00467 // 00468 // Release any waiting Irps held. 00469 // 00470 00471 while (!IsListEmpty( &ThisOplock->WaitingIrps )) { 00472 00473 PWAITING_IRP WaitingIrp; 00474 PIRP ThisIrp; 00475 00476 WaitingIrp = CONTAINING_RECORD( ThisOplock->WaitingIrps.Flink, 00477 WAITING_IRP, 00478 Links ); 00479 00480 RemoveHeadList( &ThisOplock->WaitingIrps ); 00481 00482 ThisIrp = WaitingIrp->Irp; 00483 00484 IoAcquireCancelSpinLock( &ThisIrp->CancelIrql ); 00485 00486 IoSetCancelRoutine( ThisIrp, NULL ); 00487 IoReleaseCancelSpinLock( ThisIrp->CancelIrql ); 00488 00489 ThisIrp->IoStatus.Information = 0; 00490 00491 // 00492 // Call the completion routine in the Waiting Irp. 00493 // 00494 00495 WaitingIrp->CompletionRoutine( WaitingIrp->Context, 00496 WaitingIrp->Irp ); 00497 00498 ExFreePool( WaitingIrp ); 00499 } 00500 00501 // 00502 // Release any oplock II irps held. 00503 // 00504 00505 while (!IsListEmpty( &ThisOplock->IrpOplocksII )) { 00506 00507 Irp = CONTAINING_RECORD( ThisOplock->IrpOplocksII.Flink, 00508 IRP, 00509 Tail.Overlay.ListEntry ); 00510 00511 RemoveHeadList( &ThisOplock->IrpOplocksII ); 00512 00513 IoAcquireCancelSpinLock( &Irp->CancelIrql ); 00514 00515 IoSetCancelRoutine( Irp, NULL ); 00516 IoReleaseCancelSpinLock( Irp->CancelIrql ); 00517 00518 // 00519 // Complete the oplock II Irp. 00520 // 00521 00522 ObDereferenceObject( IoGetCurrentIrpStackLocation( Irp )->FileObject ); 00523 00524 Irp->IoStatus.Information = FILE_OPLOCK_BROKEN_TO_NONE; 00525 FsRtlCompleteRequest( Irp, STATUS_SUCCESS ); 00526 } 00527 00528 // 00529 // Release any exclusive oplock held. 00530 // 00531 00532 if (ThisOplock->IrpExclusiveOplock != NULL) { 00533 00534 Irp = ThisOplock->IrpExclusiveOplock; 00535 00536 IoAcquireCancelSpinLock( &Irp->CancelIrql ); 00537 00538 IoSetCancelRoutine( Irp, NULL ); 00539 IoReleaseCancelSpinLock( Irp->CancelIrql ); 00540 00541 Irp->IoStatus.Information = FILE_OPLOCK_BROKEN_TO_NONE; 00542 FsRtlCompleteRequest( Irp, STATUS_SUCCESS ); 00543 00544 ThisOplock->IrpExclusiveOplock = NULL; 00545 00546 if (ThisOplock->FileObject != NULL) { 00547 00548 ObDereferenceObject( ThisOplock->FileObject ); 00549 } 00550 } 00551 00552 } finally { 00553 00554 // 00555 // No matter how we complete the preceding statements we will 00556 // now release the waiting lock queue mutex 00557 // 00558 00559 ExReleaseFastMutexUnsafe( ThisOplock->FastMutex ); 00560 } 00561 00562 // 00563 // Deallocate the mutex. 00564 // 00565 00566 ExFreePool( ThisOplock->FastMutex ); 00567 00568 // 00569 // Deallocate the Oplock structure. 00570 // 00571 00572 ExFreePool( ThisOplock ); 00573 } 00574 00575 DebugTrace( -1, Dbg, "FsRtlUninitializeOplock: Exit\n", 0 ); 00576 return; 00577 }


Variable Documentation

PUCHAR LEGAL_ANSI_CHARACTER_ARRAY
 

Definition at line 928 of file fsrtl.h.

PUSHORT NLS_OEM_LEAD_BYTE_INFO
 

Definition at line 929 of file fsrtl.h.


Generated on Sat May 15 19:43:47 2004 for test by doxygen 1.3.7