windows-nt/Source/XPSP1/NT/base/fs/utils/ufat/inc/cvfexts.hxx
2020-09-26 16:20:57 +08:00

295 lines
6.2 KiB
C++

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
cvfexts.hxx
Abstract:
A class to manage the CVF_FAT_EXTENSIONS (otherwise known as
the MDFAT) part of the doublespace volume.
Author:
Matthew Bradburn (mattbr) 27-Sep-93
--*/
#ifndef CVF_EXTS_DEFN
#define CVF_EXTS_DEFN
//
// secStart : 21 starting sector number, minus 1
// Reserved : 1 unused
// csecCoded : 4 number of compressed sectors required, minus 1
// csecPlain : 4 number of uncompressed sectors required, minus 1
// fUncoded : 1 0: data stored compressed 1: data uncompressed
// fUsed : 1 0: mdfat entry not in use 1: mdfat entry in use
//
#define CFE_START_SHIFT 0
#define CFE_START_MASK 0x001fffff
#define CFE_RESVD_SHIFT 21
#define CFE_RESVD_MASK 0x00200000
#define CFE_CODED_SHIFT 22
#define CFE_CODED_MASK 0x03c00000
#define CFE_PLAIN_SHIFT 26
#define CFE_PLAIN_MASK 0x3c000000
#define CFE_UNCODED_SHIFT 30
#define CFE_UNCODED_MASK 0x40000000
#define CFE_USED_SHIFT 31
#define CFE_USED_MASK 0x80000000
DECLARE_CLASS( CVF_FAT_EXTENS );
class CVF_FAT_EXTENS : public SECRUN {
public:
DECLARE_CONSTRUCTOR(CVF_FAT_EXTENS);
NONVIRTUAL
~CVF_FAT_EXTENS();
NONVIRTUAL
BOOLEAN
Initialize(
IN OUT PMEM Mem,
IN OUT PLOG_IO_DP_DRIVE Drive,
IN LBN StartSetor,
IN ULONG NumberOfEntries,
IN ULONG FirstEntry
);
NONVIRTUAL
BOOLEAN
Create(
);
NONVIRTUAL
BOOLEAN
IsClusterInUse(
IN ULONG Cluster
) CONST;
NONVIRTUAL
VOID
SetClusterInUse(
IN ULONG Cluster,
IN BOOLEAN fInUse
);
NONVIRTUAL
ULONG
QuerySectorFromCluster(
IN ULONG Cluster,
OUT PUCHAR NumSectors DEFAULT NULL
);
NONVIRTUAL
VOID
SetSectorForCluster(
IN ULONG Cluster,
IN ULONG Sector,
IN UCHAR SectorCount
);
NONVIRTUAL
BOOLEAN
IsClusterCompressed(
IN ULONG Cluster
) CONST;
NONVIRTUAL
VOID
SetClusterCompressed(
IN ULONG Cluster,
IN BOOLEAN fCompressed
);
NONVIRTUAL
UCHAR
QuerySectorsRequiredForPlainData(
IN ULONG Cluster
) CONST;
NONVIRTUAL
VOID
SetSectorsRequiredForPlainData(
IN ULONG Cluster,
IN UCHAR SectorsRequired
);
private:
NONVIRTUAL
VOID
Construct(
);
NONVIRTUAL
VOID
Destroy(
);
PULONG _mdfat;
ULONG _num_entries;
ULONG _first_entry;
};
INLINE BOOLEAN
CVF_FAT_EXTENS::IsClusterInUse(
IN ULONG Cluster
) CONST
{
ULONG CfeEntry = _mdfat[Cluster];
return BOOLEAN((CfeEntry & CFE_USED_MASK) >> CFE_USED_SHIFT);
}
INLINE VOID
CVF_FAT_EXTENS::SetClusterInUse(
IN ULONG Cluster,
IN BOOLEAN fInUse
)
{
ULONG CfeEntry = _mdfat[Cluster];
CfeEntry &= ~CFE_USED_MASK;
CfeEntry |= fInUse << CFE_USED_SHIFT;
_mdfat[Cluster] = CfeEntry;
}
INLINE ULONG
CVF_FAT_EXTENS::QuerySectorFromCluster(
IN ULONG Cluster,
OUT PUCHAR NumSectors
)
/*++
Routine Description:
This routine takes a cluster number and uses the mdfat to return
the sector number in which the data starts. Also the number of
sectors used to store the cluster data is returned. Works for
compressed and uncompressed sectors as well, and for clusters
whether they're "In Use" or not. The number returned is the
value from the CVF_FAT_EXTENSIONS plus 1.
Arguments:
Cluster - the cluster to get info for.
Return Value:
ULONG - the CVF starting sector number.
--*/
{
ULONG CfeEntry = _mdfat[Cluster];
if (NULL != NumSectors) {
*NumSectors = (UCHAR)((CfeEntry & CFE_CODED_MASK) >> CFE_CODED_SHIFT) + 1;
}
return ((CfeEntry & CFE_START_MASK) >> CFE_START_SHIFT) + 1;
}
INLINE VOID
CVF_FAT_EXTENS::SetSectorForCluster(
IN ULONG Cluster,
IN ULONG Sector,
IN UCHAR SectorCount
)
/*++
Routine Description:
This routine sets the cluster->sector mapping, as well as
the number of sectors required to store the compressed cluster.
Arguments:
Cluster - cluster number
Sector - starting CVF sector number
SectorCount - number of sectors required
Return Value:
None.
--*/
{
ULONG CfeEntry = _mdfat[Cluster];
DbgAssert(Sector > 0);
DbgAssert(SectorCount > 0);
CfeEntry &= ~CFE_START_MASK;
CfeEntry |= (Sector - 1) << CFE_START_SHIFT;
CfeEntry &= ~CFE_CODED_MASK;
CfeEntry |= ((ULONG)(SectorCount - 1) << CFE_CODED_SHIFT);
_mdfat[Cluster] = CfeEntry;
}
INLINE UCHAR
CVF_FAT_EXTENS::QuerySectorsRequiredForPlainData(
IN ULONG Cluster
) CONST
{
ULONG CfeEntry = _mdfat[Cluster];
return (UCHAR)((CfeEntry & CFE_PLAIN_MASK) >> CFE_PLAIN_SHIFT) + 1;
}
INLINE VOID
CVF_FAT_EXTENS::SetSectorsRequiredForPlainData(
IN ULONG Cluster,
IN UCHAR SectorsRequired
)
{
ULONG CfeEntry = _mdfat[Cluster];
DbgAssert(SectorsRequired > 0);
CfeEntry &= ~CFE_PLAIN_MASK;
CfeEntry |= (ULONG)(SectorsRequired - 1) << CFE_PLAIN_SHIFT;
_mdfat[Cluster] = CfeEntry;
}
INLINE BOOLEAN
CVF_FAT_EXTENS::IsClusterCompressed(
IN ULONG Cluster
) CONST
{
ULONG CfeEntry = _mdfat[Cluster];
return ! ((CfeEntry & CFE_UNCODED_MASK) >> CFE_UNCODED_SHIFT);
}
INLINE VOID
CVF_FAT_EXTENS::SetClusterCompressed(
IN ULONG Cluster,
IN BOOLEAN fCompressed
)
{
ULONG CfeEntry = _mdfat[Cluster];
CfeEntry &= ~CFE_UNCODED_MASK;
CfeEntry |= (ULONG)!fCompressed << CFE_UNCODED_SHIFT;
_mdfat[Cluster] = CfeEntry;
}
#endif // CVF_EXTS_DEFN