📄 udfprocs.h
字号:
/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
UdfProcs.h
Abstract:
This module defines all of the globally used procedures in the Udfs
file system.
Author:
Dan Lovinger [DanLo] 29-May-1996
Revision History:
--*/
#ifndef _UDFPROCS_
#define _UDFPROCS_
#include <ntifs.h>
#include <ntddcdrm.h>
#include <ntddcdvd.h>
#include <ntdddisk.h>
#ifndef INLINE
#define INLINE __inline
#endif
#include "nodetype.h"
#include "Udf.h"
#include "UdfStruc.h"
#include "UdfData.h"
//
// The Bug check file id for this module
//
#define BugCheckFileId (UDFS_BUG_CHECK_STRUCSUP)
//
// The local debug trace level
//
#define Dbg (UDFS_DEBUG_LEVEL_STRUCSUP)
//
// Miscellaneous support routines/macros
//
//
// Yet another declaration of Min/Max
//
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Max(a, b) ((a) > (b) ? (a) : (b))
//
// Yet another declaration of the basic bit fiddlers
//
#define FlagMask(F,SF) ( \
((F) & (SF)) \
)
#define BooleanFlagOn(F,SF) ( \
(BOOLEAN)(FlagOn(F, SF) != 0) \
)
#define BooleanFlagOff(F,SF) ( \
(BOOLEAN)(FlagOn(F, SF)) == 0) \
)
#define SetFlag(Flags,SingleFlag) ( \
(Flags) |= (SingleFlag) \
)
#define ClearFlag(Flags,SingleFlag) ( \
(Flags) &= ~(SingleFlag) \
)
//
// CAST
// Add2Ptr (
// IN PVOID Pointer,
// IN ULONG Increment
// IN (CAST)
// );
//
// ULONG
// PtrOffset (
// IN PVOID BasePtr,
// IN PVOID OffsetPtr
// );
//
#define Add2Ptr(PTR,INC,CAST) ((CAST)((ULONG_PTR)(PTR) + (INC)))
#define PtrOffset(BASE,OFFSET) ((ULONG)((ULONG)(OFFSET) - (ULONG)(BASE)))
//
// Generic truncation/align/offset/remainder macros for power-of-two units.
//
// The offset and remainder functions range from zero to (unit - 1). The
// re-offset in the remainder performs this work.
//
#define GenericTruncate(B, U) ( \
(B) & ~((U) - 1) \
)
#define GenericAlign(B, U) ( \
GenericTruncate((B) + (U) - 1, U) \
)
#define GenericOffset(B, U) ( \
(B) & ((U) - 1) \
)
#define GenericRemainder(B, U) ( \
GenericOffset( (U) - GenericOffset((B), (U)), (U) ) \
)
#define GenericTruncatePtr(B, U) ( \
(PVOID)(((ULONG_PTR)(B)) & ~((U) - 1)) \
)
#define GenericAlignPtr(B, U) ( \
GenericTruncatePtr((B) + (U) - 1, (U)) \
)
#define GenericOffsetPtr(B, U) ( \
(ULONG)(((ULONG_PTR)(B)) & ((U) - 1)) \
)
#define GenericRemainderPtr(B, U) ( \
(ULONG)GenericOffset( (U) - GenericOffsetPtr((B), (U)), (U) ) \
)
//
// Useful compositions of the defaults for common types.
//
#define WordAlign(B) GenericAlign((B), 2)
#define LongAlign(B) GenericAlign((B), 4)
#define QuadAlign(B) GenericAlign((B), 8)
#define WordOffset(B) GenericOffset((B), 2)
#define LongOffset(B) GenericOffset((B), 4)
#define QuadOffset(B) GenericOffset((B), 8)
#define WordAlignPtr(P) GenericAlignPtr((P), 2)
#define LongAlignPtr(P) GenericAlignPtr((P), 4)
#define QuadAlignPtr(P) GenericAlignPtr((P), 8)
#define WordOffsetPtr(P) GenericOffsetPtr((P), 2)
#define LongOffsetPtr(P) GenericOffsetPtr((P), 4)
#define QuadOffsetPtr(P) GenericOffsetPtr((P), 8)
//
// Macros to round up and down on sector and logical block boundaries. Although
// UDF 1.01 specifies that a physical sector is the logical block size we will
// be general and treat sectors and logical blocks as distinct. Since UDF may
// at some point relax the restriction, these definitions will be the only
// acknowledgement outside of the mount path (which merely checks the volume's
// conformance).
//
//
// Sector
//
#define SectorAlignN(SECTORSIZE, L) ( \
((((ULONG)(L)) + ((SECTORSIZE) - 1)) & ~((SECTORSIZE) - 1)) \
)
#define SectorAlign(V, L) ( \
((((ULONG)(L)) + (((V)->SectorSize) - 1)) & ~(((V)->SectorSize) - 1)) \
)
#define LlSectorAlign(V, L) ( \
((((LONGLONG)(L)) + (((V)->SectorSize) - 1)) & ~(((LONGLONG)(V)->SectorSize) - 1)) \
)
#define SectorTruncate(V, L) ( \
((ULONG)(L)) & ~(((V)->SectorSize) - 1) \
)
#define LlSectorTruncate(V, L) ( \
((LONGLONG)(L)) & ~(((LONGLONG)(V)->SectorSize) - 1) \
)
#define BytesFromSectors(V, L) ( \
((ULONG) (L)) << ((V)->SectorShift) \
)
#define SectorsFromBytes(V, L) ( \
((ULONG) (L)) >> ((V)->SectorShift) \
)
#define LlBytesFromSectors(V, L) ( \
Int64ShllMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \
)
#define LlSectorsFromBytes(V, L) ( \
Int64ShrlMod32( (ULONGLONG)(L), ((V)->SectorShift) ) \
)
#define SectorsFromBlocks(V, B) (B)
#define SectorSize(V) ((V)->SectorSize)
#define SectorOffset(V, L) ( \
((ULONG) (L)) & (((V)->SectorSize) - 1) \
)
//
// Logical Block
//
#define BlockAlignN(BLOCKSIZE, L) ( \
SectorAlighN((BLOCKSIZE), (L)) \
)
#define BlockAlign(V, L) ( \
SectorAlign((V), (L)) \
)
#define LlBlockAlign(V, L) ( \
LlSectorAlign((V), (L)) \
)
#define BlockTruncate(V, L) ( \
SectorTruncate((V), (L)) \
)
#define LlBlockTruncate(V, L) ( \
LlSectorTruncate((V), (L)) \
)
#define BytesFromBlocks(V, L) ( \
BytesFromSectors((V), (L)) \
)
#define BlocksFromBytes(V, L) ( \
SectorsFromBytes((V), (L)) \
)
#define LlBytesFromBlocks(V, L) ( \
LlBytesFromSectors((V), (L)) \
)
#define LlBlocksFromBytes(V, L) ( \
LlSectorsFromBytes((V), (L)) \
)
#define BlocksFromSectors(V, S) (S)
#define BlockSize(V) (SectorSize(V))
#define BlockOffset(V, L) ( \
SectorOffset((V), (L)) \
)
//
// The following types and macros are used to help unpack the packed and
// misaligned fields found in various structures.
//
typedef union _UCHAR1 {
UCHAR Uchar[1];
UCHAR ForceAlignment;
} UCHAR1, *PUCHAR1;
typedef union _UCHAR2 {
UCHAR Uchar[2];
USHORT ForceAlignment;
} UCHAR2, *PUCHAR2;
typedef union _UCHAR4 {
UCHAR Uchar[4];
ULONG ForceAlignment;
} UCHAR4, *PUCHAR4;
typedef union _USHORT2 {
USHORT Ushort[2];
ULONG ForceAlignment;
} USHORT2, *PUSHORT2;
//
// This macro copies an unaligned src byte to an aligned dst byte
//
#define CopyUchar1(Dst,Src) { \
*((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \
}
//
// This macro copies an unaligned src word to an aligned dst word
//
#define CopyUchar2(Dst,Src) { \
*((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \
}
//
// This macro copies an unaligned src word to a dst word,
// performing an little/big endian swap.
//
#define SwapCopyUchar2(Dst,Src) { \
*((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
*((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src)); \
}
//
// This macro copies an unaligned src longword to an aligned dst longword
//
#define CopyUchar4(Dst,Src) { \
*((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)(Src)); \
}
//
// This macro copies an unaligned src longword to a dst longword,
// performing an little/big endian swap.
//
#define SwapCopyUchar4(Dst,Src) { \
*((UNALIGNED UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src) + 3); \
*((UNALIGNED UCHAR1 *)(Dst) + 1) = *((UNALIGNED UCHAR1 *)(Src) + 2); \
*((UNALIGNED UCHAR1 *)(Dst) + 2) = *((UNALIGNED UCHAR1 *)(Src) + 1); \
*((UNALIGNED UCHAR1 *)(Dst) + 3) = *((UNALIGNED UCHAR1 *)(Src)); \
}
//
// This macro copies an unaligned src longword to an aligned dsr longword
// accessing the source on a word boundary.
//
#define CopyUshort2(Dst,Src) { \
*((USHORT2 *)(Dst)) = *((UNALIGNED USHORT2 *)(Src));\
}
//
// The following macro is used to determine if an FSD thread can block
// for I/O or wait for a resource. It returns TRUE if the thread can
// block and FALSE otherwise. This attribute can then be used to call
// the FSD & FSP common work routine with the proper wait value.
//
#define CanFsdWait(I) IoIsOperationSynchronous(I)
//
// The following macro is used to set the fast i/o possible bits in the
// FsRtl header.
//
// FastIoIsNotPossible - If the Fcb is bad or there are oplocks on the file.
//
// FastIoIsQuestionable - If there are file locks.
//
// FastIoIsPossible - In all other cases.
//
//
#define UdfIsFastIoPossible(F) ((BOOLEAN) \
((((F)->Vcb->VcbCondition != VcbMounted ) || \
!FsRtlOplockIsFastIoPossible( &(F)->Oplock )) ? \
\
FastIoIsNotPossible : \
\
((((F)->FileLock != NULL) && FsRtlAreThereCurrentFileLocks( (F)->FileLock )) ? \
\
FastIoIsQuestionable : \
\
FastIoIsPossible)) \
)
//
// The following macros encapsulate the common work of raising exceptions while storing
// the exception in the IrpContext.
//
INLINE
DECLSPEC_NORETURN
VOID
UdfRaiseStatus (
IN PIRP_CONTEXT IrpContext,
IN NTSTATUS Status
)
{
IrpContext->ExceptionStatus = Status;
DebugBreakOnStatus( Status );
ExRaiseStatus( Status );
}
INLINE
VOID
UdfNormalizeAndRaiseStatus (
IN PIRP_CONTEXT IrpContext,
IN NTSTATUS Status
)
{
IrpContext->ExceptionStatus = FsRtlNormalizeNtstatus( Status, STATUS_UNEXPECTED_IO_ERROR );
ExRaiseStatus( IrpContext->ExceptionStatus );
}
//
// The following is a convenience macro to execute a little code before making
// a shortcircuit out of a surrounding try-finally clause. This is usually to
// set a status value.
//
// Note that our compilers support the leave keyword now and we don't have to
// use the old try_exit: labels and goto.
//
#define try_leave(S) { S; leave; }
//
// For debugging purposes we sometimes want to allocate our structures from nonpaged
// pool so that in the kernel debugger we can walk all the structures.
//
#define UdfPagedPool PagedPool
#define UdfNonPagedPool NonPagedPool
#define UdfNonPagedPoolCacheAligned NonPagedPoolCacheAligned
//
// Encapsulate safe pool freeing
//
INLINE
VOID
UdfFreePool(
IN PVOID *Pool
)
{
if (*Pool != NULL) {
ExFreePool(*Pool);
*Pool = NULL;
}
}
//
// Encapsulate counted string compares with uncounted fields. Thanks to a
// very smart compiler, we have to carefully tell it that no matter what it
// thinks, it *cannot* do anything other than a bytewise compare.
//
INLINE
BOOLEAN
UdfEqualCountedString(
IN PSTRING String,
IN PCHAR Field
)
{
return (RtlEqualMemory( (CHAR UNALIGNED *)String->Buffer,
(CHAR UNALIGNED *)Field,
String->Length ) != 0);
}
//
// Type of opens. FilObSup.c depends on this order.
//
typedef enum _TYPE_OF_OPEN {
UnopenedFileObject = 0,
StreamFileOpen,
UserVolumeOpen,
UserDirectoryOpen,
UserFileOpen,
BeyondValidType
} TYPE_OF_OPEN, *PTYPE_OF_OPEN;
//
// Following routines handle entry in and out of the filesystem. They are
// contained in UdfData.c. We also get some very generic utility functions
// here that aren't associated with any particular datastructure.
//
NTSTATUS
UdfFsdDispatch (
IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
IN PIRP Irp
);
LONG
UdfExceptionFilter (
IN PIRP_CONTEXT IrpContext,
IN PEXCEPTION_POINTERS ExceptionPointer
);
NTSTATUS
UdfProcessException (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PIRP Irp,
IN NTSTATUS ExceptionCode
);
VOID
UdfCompleteRequest (
IN PIRP_CONTEXT IrpContext OPTIONAL,
IN PIRP Irp OPTIONAL,
IN NTSTATUS Status
);
//
// Following are the routines to handle the top level thread logic.
//
VOID
UdfSetThreadContext (
IN PIRP_CONTEXT IrpContext,
IN PTHREAD_CONTEXT ThreadContext
);
INLINE
VOID
UdfRestoreThreadContext (
IN PIRP_CONTEXT IrpContext
)
{
IrpContext->ThreadContext->Udfs = 0;
IoSetTopLevelIrp( IrpContext->ThreadContext->SavedTopLevelIrp );
IrpContext->ThreadContext = NULL;
}
//
// Following are some generic utility functions we have to carry along for the ride
//
ULONG
UdfSerial32 (
IN PCHAR Buffer,
IN ULONG ByteCount
);
VOID
UdfInitializeCrc16 (
ULONG Polynomial
);
USHORT
UdfComputeCrc16 (
IN PUCHAR Buffer,
IN ULONG ByteCount
);
USHORT
UdfComputeCrc16Uni (
PWCHAR Buffer,
ULONG CharCount
);
ULONG
UdfHighBit (
ULONG Word
);
//
// Following are the fast entry points.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -