windows-nt/Source/XPSP1/NT/base/fs/utils/uudf/src/scanfids.cxx
2020-09-26 16:20:57 +08:00

212 lines
4.5 KiB
C++

/*++
Copyright (c) 1990-2000 Microsoft Corporation
Module Name:
ScanFIDs.cxx
Author:
Centis Biks (cbiks) 05-May-2000
Environment:
ULIB, User Mode
--*/
#include "pch.cxx"
#include "UdfLVol.hxx"
#include "ScanFIDs.hxx"
DEFINE_CONSTRUCTOR( SCAN_FIDS, OBJECT );
BOOL
SCAN_FIDS::Initialize
(
PUDF_LVOL UdfLVol,
PICBFILE FileIcbEntry
)
{
BOOL Result = TRUE;
_BytesRemainingInExtent = 0;
_ReadBufferSize = 0;
_ReadBuffer = NULL;
_LogicalBlockNum = 0;
_BufferOffset = 0;
_BytesRemainingInBuffer = 0;
_PreviousReadSize = 0;
_SectorSize = 0;
_UdfLVol = NULL;
Result = _AllocationDescriptors.Initialize( UdfLVol, FileIcbEntry );
if (Result) {
_UdfLVol = UdfLVol;
_SectorSize = _UdfLVol->QuerySectorSize();
_ReadBufferSize = _SectorSize * 2;
_ReadBuffer = (LPBYTE) malloc( _ReadBufferSize );
ULONG StartBlockNum;
ULONG Length;
SHORT Type;
if (_AllocationDescriptors.Next( &StartBlockNum, &Length, &Type)) {
if (Length > 0) {
_BytesRemainingInExtent = Length;
_LogicalBlockNum = StartBlockNum;
UINT NumberOfBlocks = __min( 2, (_BytesRemainingInExtent + _SectorSize - 1) / _SectorSize );
BOOL result = _UdfLVol->Read( StartBlockNum, NumberOfBlocks, _ReadBuffer );
if (result) {
Result = _UdfLVol->MarkBlocksUsed( StartBlockNum, NumberOfBlocks );
_LogicalBlockNum += NumberOfBlocks;
_BufferOffset = 0;
_BytesRemainingInBuffer = __min( _ReadBufferSize, _BytesRemainingInExtent );
}
}
}
}
return Result;
}
LPBYTE
SCAN_FIDS::ProbeRead
(
ULONG ReadSize
)
{
LPBYTE BufferPtr = NULL;
if (ReadSize > _BytesRemainingInBuffer) {
if (ReadSize > _BytesRemainingInExtent) {
ULONG StartBlockNum;
ULONG Length;
SHORT Type;
if (_AllocationDescriptors.Next( &StartBlockNum, &Length, &Type)) {
if (Length > 0) {
if (Type == NSRLENGTH_TYPE_RECORDED) {
_LogicalBlockNum = StartBlockNum;
_BytesRemainingInExtent += Length;
} else if (Type == NSRLENGTH_TYPE_UNRECORDED) {
BOOL result = _UdfLVol->MarkBlocksUsed( StartBlockNum, RoundUp( Length, _SectorSize ) );
} else {
ASSERTMSG( "Unsupported length type",
0 );
}
}
}
}
if (ReadSize < _BytesRemainingInExtent) {
memmove( _ReadBuffer, _ReadBuffer + _SectorSize, _SectorSize );
BOOL result = _UdfLVol->Read( _LogicalBlockNum, 1, _ReadBuffer + _SectorSize );
if (result) {
result = _UdfLVol->MarkBlocksUsed( _LogicalBlockNum, 1 );
_LogicalBlockNum += 1;
_BufferOffset -= _SectorSize;
_BytesRemainingInBuffer = __min( _BytesRemainingInBuffer + _SectorSize, _BytesRemainingInExtent );
BufferPtr = _ReadBuffer + _BufferOffset;
}
}
}
if (ReadSize <= _BytesRemainingInBuffer) {
BufferPtr = _ReadBuffer + _BufferOffset;
}
return BufferPtr;
}
BOOL
SCAN_FIDS::Next
(
PNSR_FID* NsrFid
)
{
BOOL Result = FALSE;
if (_PreviousReadSize != 0) {
LPBYTE BufferPtr = ProbeRead( _PreviousReadSize );
if (BufferPtr != NULL) {
_BufferOffset += _PreviousReadSize;
_BytesRemainingInBuffer -= _PreviousReadSize;
_BytesRemainingInExtent -= _PreviousReadSize;
_PreviousReadSize = 0;
}
}
LPBYTE BufferPtr = ProbeRead( sizeof( DESTAG ) );
if (BufferPtr != NULL) {
Result = VerifyDescriptorTag( BufferPtr, sizeof( DESTAG ), DESTAG_ID_NSR_FID, NULL );
if (Result) {
BufferPtr = ProbeRead( sizeof( NSR_FID) );
if (BufferPtr != NULL) {
BufferPtr = ProbeRead( ISONsrFidSize( PNSR_FID( BufferPtr ) ) );
Result = VerifyDescriptor( BufferPtr, ISONsrFidSize( PNSR_FID( BufferPtr ) ), DESTAG_ID_NSR_FID, NULL );
if (Result) {
_PreviousReadSize = ISONsrFidSize( PNSR_FID( BufferPtr ) );
*NsrFid = PNSR_FID( BufferPtr );
}
}
}
}
return Result;
}