212 lines
4.5 KiB
C++
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;
|
|
}
|