windows-nt/Source/XPSP1/NT/com/ole32/stg/ref/h/fat.hxx
2020-09-26 16:20:57 +08:00

439 lines
10 KiB
C++

//+-------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1996.
//
// File: fat.hxx
//
// Contents: Header file for fat classes
//
// Classes: CFatSect - sector sized array of sector info
// CFatVector - resizable array of CFatSect
// CFat - Grouping of FatSect
//
//--------------------------------------------------------------------
#ifndef __FAT_HXX__
#define __FAT_HXX__
#include "vect.hxx"
#define DEB_FAT (DEB_ITRACE|0x00010000)
//+----------------------------------------------------------------------
//
// Class: CFatSect (fs)
//
// Purpose: Holds one sector worth of FAT data
//
// Interface: getsize - Returns the size of the FAT (in sectors)
// contents - Returns contents of any given FAT entry
//
// Notes:
//
//-----------------------------------------------------------------------
class CFatSect
{
public:
SCODE Init(FSOFFSET uEntries);
SCODE InitCopy(USHORT uSize, CFatSect& fsOld);
inline SECT GetSect(const FSOFFSET sect) const;
inline void SetSect(const FSOFFSET sect,const SECT sectNew);
inline SECT GetNextFat(USHORT uSize) const;
inline void SetNextFat(USHORT uSize, const SECT sect);
inline void ByteSwap(USHORT cbSector);
private:
#ifdef _MSC_VER
#pragma warning(disable: 4200)
SECT _asectEntry[];
#pragma warning(default: 4200)
#endif
#ifdef __GNUC__
SECT _asectEntry[0];
#endif
};
inline SECT CFatSect::GetSect(const FSOFFSET sect) const
{
return _asectEntry[sect];
}
inline void CFatSect::SetSect(const FSOFFSET sect,
const SECT sectNew)
{
_asectEntry[sect] = sectNew;
}
inline SECT CFatSect::GetNextFat(USHORT uSize) const
{
return _asectEntry[uSize];
}
inline void CFatSect::SetNextFat(USHORT uSize, const SECT sect)
{
_asectEntry[uSize] = sect;
}
inline void CFatSect::ByteSwap(FSOFFSET cbSector)
{
// swap all sectors in the sector
for (FSOFFSET i=0; i < cbSector; i++)
::ByteSwap(&(_asectEntry[i]));
}
//+-------------------------------------------------------------------------
//
// Class: CFatVector (fv)
//
// Purpose: *finish this*
//
// Interface:
//
// Notes:
//
//--------------------------------------------------------------------------
class CFatVector: public CPagedVector
{
public:
inline CFatVector( const SID sid,
FSOFFSET csectBlock,
FSOFFSET csectTable);
SCODE InitPage(FSINDEX iPage);
inline FSOFFSET GetSectBlock() const;
inline FSOFFSET GetSectTable() const;
inline SCODE GetTable( const FSINDEX iTable,
const DWORD dwFlags,
CFatSect **pfs);
private:
FSOFFSET const _csectTable;
FSOFFSET const _csectBlock;
inline void operator = (const CFatVector &that);
#ifdef _MSC_VER
#pragma warning(disable:4512)
// since there is a const member, there should be no assignment operator
#endif // _MSC_VER
};
#ifdef _MSC_VER
#pragma warning(default:4512)
#endif // _MSC_VER
inline CFatVector::CFatVector(
const SID sid,
FSOFFSET csectBlock,
FSOFFSET csectTable)
: CPagedVector(sid),
_csectTable(csectTable),
_csectBlock(csectBlock)
{
}
//+-------------------------------------------------------------------------
//
// Method: CFatVector::GetSectTable, public
//
// Synopsis: Returns count of sector entries per table
//
// Returns: count of sector entries per table
//
//--------------------------------------------------------------------------
inline FSOFFSET CFatVector::GetSectTable() const
{
return _csectTable;
}
//+-------------------------------------------------------------------------
//
// Method: CFatVector::GetSectTable, public
//
// Synopsis: Returns count of sector entries per block
//
// Returns: count of sector entries per block
//
//--------------------------------------------------------------------------
inline FSOFFSET CFatVector::GetSectBlock() const
{
return _csectBlock;
}
//+-------------------------------------------------------------------------
//
// Method: CFatVector::GetTable, public
//
// Synopsis: Return a pointer to a FatSect for the given index
// into the vector.
//
// Arguments: [iTable] -- index into vector
//
// Returns: Pointer to CFatSect indicated by index
//
// Notes:
//
//--------------------------------------------------------------------------
inline SCODE CFatVector::GetTable(
const FSINDEX iTable,
const DWORD dwFlags,
CFatSect **ppfs)
{
SCODE sc;
sc = CPagedVector::GetTable(iTable, dwFlags, (void **)ppfs);
if (sc == STG_S_NEWPAGE)
{
(*ppfs)->Init(_csectBlock);
}
return sc;
}
//CSEG determines the maximum number of segments that will be
//returned by a single Contig call.
#define CSEG 32
//+-------------------------------------------------------------------------
//
// Class: SSegment (seg)
//
// Purpose: Used for contiguity tables for multi-sector reads and
// writes.
//
// Interface: None.
//
// Notes:
//
//--------------------------------------------------------------------------
struct SSegment {
public:
SECT sectStart;
ULONG cSect;
};
class CMStream;
//+----------------------------------------------------------------------
//
// Class: CFat (fat)
//
// Purpose: Main interface to allocation routines
//
// Interface: Allocate - allocates new chain in the FAT
// Extend - Extends an existing FAT chain
// GetNext - Returns next sector in a chain
// GetSect - Returns nth sector in a chain
// GetESect - Returns nth sector in a chain, extending
// if necessary
// GetLength - Returns the # of sectors in a chain
// setup - Initializes for an existing stream
// setupnew - Initializes for a new stream
//
// checksanity - Debugging routine
//
// Notes:
//
//-----------------------------------------------------------------------
class CFat
{
public:
CFat(SID sid, USHORT cbSector, USHORT uSectorShift);
~CFat();
VOID Empty(VOID);
inline SCODE Allocate(ULONG ulSize, SECT *psectFirst);
SCODE GetNext(const SECT sect, SECT * psRet);
SCODE GetSect(
SECT sectStart,
ULONG ulOffset,
SECT *psectReturn);
SCODE GetESect(
SECT sectStart,
ULONG ulOffset,
SECT *psectReturn);
SCODE SetNext(SECT sectFirst, SECT sectNext);
SCODE GetFree(ULONG ulCount, SECT *sect);
SCODE GetLength(SECT sect, ULONG * pulRet);
SCODE SetChainLength(SECT,ULONG);
SCODE Init(
CMStream *pmsParent,
FSINDEX cFatSect,
BOOL fConvert);
SCODE InitNew(CMStream *pmsParent);
SCODE InitConvert(
CMStream *pmsParent,
ULONG cbSize);
SCODE FindLast(SECT *psectRet);
SCODE FindMaxSect(SECT *psectRet);
inline SCODE GetMaxSect(SECT *psectRet);
SCODE Contig(
SSegment STACKBASED *aseg,
SECT sect,
ULONG ulLength);
inline SCODE Flush(VOID);
inline void SetParent(CMStream *pms);
private:
CFatVector _fv;
CMStream * _pmsParent;
const SID _sid;
const USHORT _uFatShift;
const USHORT _uFatMask;
FSINDEX _cfsTable;
ULONG _ulFreeSects;
SECT _sectFirstFree;
SECT _sectMax;
SCODE CountFree(ULONG * ulRet);
SCODE Resize(ULONG);
SCODE Extend(SECT,ULONG);
inline VOID SectToPair(
SECT sect,
FSINDEX *pipfs,
FSOFFSET *pisect) const;
inline SECT PairToSect(FSINDEX ipfs, FSOFFSET isect) const;
friend class CDIFat;
#ifdef _MSC_VER
#pragma warning(disable:4512)
// since there is a const member, there should be no assignment operator
#endif // _MSC_VER
};
#ifdef _MSC_VER
#pragma warning(default:4512)
#endif // _MSC_VER
inline VOID CFat::SectToPair(SECT sect,FSINDEX *pipfs,FSOFFSET *pisect) const
{
*pipfs = (FSINDEX)(sect >> _uFatShift);
*pisect = (FSOFFSET)(sect & _uFatMask);
}
inline SECT CFat::PairToSect(FSINDEX ipfs, FSOFFSET isect) const
{
return (ipfs << _uFatShift) + isect;
}
inline SCODE CFat::GetMaxSect(SECT *psectRet)
{
SCODE sc;
msfChk(FindMaxSect(&_sectMax));
*psectRet = _sectMax;
Err:
return sc;
}
inline void CFat::SetParent(CMStream *pms)
{
_pmsParent = pms;
_fv.SetParent(pms);
}
//+-------------------------------------------------------------------------
//
// Member: CFat::Flush, public
//
// Synposis: Write all modified FatSects out to stream
//
// Effects: Resets all dirty bit fields on FatSects
//
// Arguments: Void
//
// Returns: S_OK if call completed OK.
// Error code of parent write otherwise.
//
// Algorithm: Linearly scan through FatSects, writing any sector
// that has the dirty bit set. Reset all dirty bits.
//
// Notes:
//
//---------------------------------------------------------------------------
inline SCODE CFat::Flush(VOID)
{
return _fv.Flush();
}
//+-------------------------------------------------------------------------
//
// Member: CFat::Allocate, public
//
// Synposis: Allocates a chain within a FAT
//
// Effects: Modifies a single sector within the fat. Causes a
// one sector stream write.
//
// Arguments: [ulSize] -- Number of sectors to allocate in chain
//
// Returns: Sector ID of first sector in chain
//
// Algorithm: Use repetitive calls to GetFree to construct a new chain
//
// Notes:
//
//---------------------------------------------------------------------------
inline SCODE CFat::Allocate(ULONG ulSize, SECT * psectFirst)
{
return GetFree(ulSize, psectFirst);
}
#endif //__FAT_HXX__