📄 udfdata.c
字号:
// If NULL then this is the top-level request.
//
CurrentThreadContext = (PTHREAD_CONTEXT) IoGetTopLevelIrp();
if (CurrentThreadContext == NULL) {
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL );
}
//
// Initialize the input context unless we are using the current
// thread context block. We use the new block if our caller
// specified this or the existing block is invalid.
//
// The following must be true for the current to be a valid Udfs context.
//
// Structure must lie within current stack.
// Address must be ULONG aligned.
// Udfs signature must be present.
//
// If this is not a valid Udfs context then use the input thread
// context and store it in the top level context.
//
IoGetStackLimits( &StackTop, &StackBottom);
if (FlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL ) ||
(((ULONG_PTR) CurrentThreadContext > StackBottom - sizeof( THREAD_CONTEXT )) ||
((ULONG_PTR) CurrentThreadContext <= StackTop) ||
LongOffsetPtr( CurrentThreadContext ) ||
(CurrentThreadContext->Udfs != UDFS_SIGNATURE))) {
ThreadContext->Udfs = UDFS_SIGNATURE;
ThreadContext->SavedTopLevelIrp = (PIRP) CurrentThreadContext;
ThreadContext->TopLevelIrpContext = IrpContext;
IoSetTopLevelIrp( (PIRP) ThreadContext );
IrpContext->TopLevel = IrpContext;
IrpContext->ThreadContext = ThreadContext;
SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_TOP_LEVEL_UDFS );
//
// Otherwise use the IrpContext in the thread context.
//
} else {
IrpContext->TopLevel = CurrentThreadContext->TopLevelIrpContext;
}
return;
}
BOOLEAN
UdfFastIoCheckIfPossible (
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Wait,
IN ULONG LockKey,
IN BOOLEAN CheckForReadOperation,
OUT PIO_STATUS_BLOCK IoStatus,
IN PDEVICE_OBJECT DeviceObject
)
/*++
Routine Description:
This routine checks if fast i/o is possible for a read/write operation
Arguments:
FileObject - Supplies the file object used in the query
FileOffset - Supplies the starting byte offset for the read/write operation
Length - Supplies the length, in bytes, of the read/write operation
Wait - Indicates if we can wait
LockKey - Supplies the lock key
CheckForReadOperation - Indicates if this is a check for a read or write
operation
IoStatus - Receives the status of the operation if our return value is
FastIoReturnError
Return Value:
BOOLEAN - TRUE if fast I/O is possible and FALSE if the caller needs
to take the long route.
--*/
{
PAGED_CODE();
return TRUE;
}
ULONG
UdfSerial32 (
IN PCHAR Buffer,
IN ULONG ByteCount
)
/*++
Routine Description:
This routine is called to generate a 32 bit serial number. This is
done by doing four separate checksums into an array of bytes and
then treating the bytes as a ULONG.
Arguments:
Buffer - Pointer to the buffer to generate the ID for.
ByteCount - Number of bytes in the buffer.
Return Value:
ULONG - The 32 bit serial number.
--*/
{
union {
UCHAR Bytes[4];
ULONG SerialId;
} Checksum;
PAGED_CODE();
//
// Initialize the serial number.
//
Checksum.SerialId = 0;
//
// Continue while there are more bytes to use.
//
while (ByteCount--) {
//
// Increment this sub-checksum.
//
Checksum.Bytes[ByteCount & 0x3] += *(Buffer++);
}
//
// Return the checksums as a ULONG.
//
return Checksum.SerialId;
}
VOID
UdfInitializeCrc16 (
ULONG Polynomial
)
/*++
Routine Description:
This routine generates the 16bit CRC Table to be used in CRC calculation.
Arguments:
Polynomial - Starting seed for the generation
Return Value:
None
--*/
{
ULONG n, i, Crc;
//
// All CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories
// and Ned W. Rhodes of Software Systems Group. It has been published in
// "Design and Validation of Computer Protocols", Prentice Hall, Englewood
// Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4.
//
// Copyright is held by AT&T.
//
// AT&T gives permission for the free use of the source code.
//
UdfCrcTable = (PUSHORT) FsRtlAllocatePoolWithTag( UdfPagedPool,
256 * sizeof(USHORT),
TAG_CRC_TABLE );
for (n = 0; n < 256; n++) {
Crc = n << 8;
for (i = 0; i < 8; i++) {
if(Crc & 0x8000) {
Crc = (Crc << 1) ^ Polynomial;
} else {
Crc <<= 1;
}
Crc &= 0xffff;
}
UdfCrcTable[n] = (USHORT) Crc;
}
}
USHORT
UdfComputeCrc16 (
PUCHAR Buffer,
ULONG ByteCount
)
/*++
Routine Description:
This routine generates a 16 bit CRC of the input buffer in accordance
with the precomputed CRC table.
Arguments:
Buffer - Pointer to the buffer to generate the CRC for.
ByteCount - Number of bytes in the buffer.
Return Value:
USHORT - The 16bit CRC
--*/
{
USHORT Crc = 0;
//
// All CRC code was devised by Don P. Mitchell of AT&T Bell Laboratories
// and Ned W. Rhodes of Software Systems Group. It has been published in
// "Design and Validation of Computer Protocols", Prentice Hall, Englewood
// Cliffs, NJ, 1991, Chapter 3, ISBN 0-13-539925-4.
//
// Copyright is held by AT&T.
//
// AT&T gives permission for the free use of the source code.
//
while (ByteCount-- > 0) {
Crc = UdfCrcTable[((Crc >> 8) ^ *Buffer++) & 0xff] ^ (Crc << 8);
}
return Crc;
}
USHORT
UdfComputeCrc16Uni (
PWCHAR Buffer,
ULONG CharCount
)
/*++
Routine Description:
This routine generates a 16 bit CRC of the input buffer in accordance
with the precomputed CRC table.
It performs a byte-order independent crc (hi then lo). This is a bit
suspect, but is called for in the specification.
Arguments:
Buffer - Pointer to the buffer to generate the CRC for.
ShortCount - Number of wide characters in the buffer.
Return Value:
USHORT - The 16bit CRC
--*/
{
USHORT Crc = 0;
//
// Byte order independent CRC, hi byte to low byte per character.
//
while (CharCount-- > 0) {
Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer >> 8)) & 0xff] ^ (Crc << 8);
Crc = UdfCrcTable[((Crc >> 8) ^ (*Buffer++ & 0xff)) & 0xff] ^ (Crc << 8);
}
return Crc;
}
ULONG
UdfHighBit (
ULONG Word
)
/*++
Routine Description:
This routine discovers the highest set bit of the input word. It is
equivalent to the integer logarithim base 2.
Arguments:
Word - word to check
Return Value:
Bit offset of highest set bit. If no bit is set, return is zero.
--*/
{
ULONG Offset = 31;
ULONG Mask = (ULONG)(1 << 31);
if (Word == 0) {
return 0;
}
while ((Word & Mask) == 0) {
Offset--;
Mask >>= 1;
}
return Offset;
}
#ifdef UDF_SANITY
BOOLEAN
UdfDebugTrace (
LONG IndentIncrement,
ULONG TraceMask,
PCHAR Format,
...
)
/*++
Routine Description:
This routine is a simple debug info printer that returns a constant boolean value. This
makes it possible to splice it into the middle of boolean expressions to discover which
elements are firing.
We will use this as our general debug printer. See udfdata.h for how we use the DebugTrace
macro to accomplish the effect.
Arguments:
IndentIncrement - amount to change the indentation by.
TraceMask - specification of what debug trace level this call should be noisy at.
Return Value:
USHORT - The 16bit CRC
--*/
{
va_list Arglist;
LONG i;
UCHAR Buffer[128];
int Bytes;
if (TraceMask == 0 || (UdfDebugTraceLevel & TraceMask) != 0) {
if (IndentIncrement < 0) {
UdfDebugTraceIndent += IndentIncrement;
}
if (UdfDebugTraceIndent < 0) {
UdfDebugTraceIndent = 0;
}
//
// Build the indent in big chunks since calling DbgPrint repeatedly is expensive.
//
for (i = UdfDebugTraceIndent; i > 0; i -= (sizeof(Buffer) - 1)) {
RtlFillMemory( Buffer, Min( i, (sizeof(Buffer) - 1 )), ' ');
*(Buffer + Min( i, (sizeof(Buffer) - 1 ))) = '\0';
DbgPrint( Buffer );
}
//
// Format the output into a buffer and then print it.
//
va_start( Arglist, Format );
Bytes = _vsnprintf( Buffer, sizeof(Buffer), Format, Arglist );
va_end( Arglist );
//
// detect buffer overflow
//
if (Bytes == -1) {
Buffer[sizeof(Buffer) - 1] = '\n';
}
DbgPrint( Buffer );
if (IndentIncrement > 0) {
UdfDebugTraceIndent += IndentIncrement;
}
}
return TRUE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -