NT4/private/utils/uhpfs/inc/cpinfo.hxx
2020-09-30 17:12:29 +02:00

598 lines
11 KiB
C++

/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
codepage.hxx
Abstract:
Container for HPFS Volume Codepage information
Author:
Mark Shavlik (marks) Nov-90
Environment:
Notes:
Revision History:
--*/
#if ! defined( UHPFS_CODEPAGE_DFN )
#define UHPFS_CODEPAGE_DFN
#include "hmem.hxx"
#include "secrun.hxx"
#include "verify.hxx"
//
// Forward references
//
DECLARE_CLASS( UHPFS_CODEPAGE );
DECLARE_CLASS( CPDATA );
DECLARE_CLASS( CODEPAGE_INFO );
DECLARE_CLASS( CASEMAP );
DECLARE_CLASS( HOTFIXLIST );
DECLARE_CLASS( HPFS_BITMAP );
DECLARE_CLASS( HPFS_MAIN_BITMAP );
DECLARE_CLASS( LOG_IO_DP_DRIVE );
//
// Codepage constants:
#define CCS_ROT 7
CONST EntriesPerCPInfoSector = 31;
CONST EntriesPerCPDataSector = 3;
CONST MaximumCodepagesOnVol = 128;
CONST InvalidCountryCode = 0xffff;
CONST InvalidCodepageID = 0xffff;
CONST CaseTableSize = 256;
CONST CharsInCasemap = 128;
class UHPFS_CODEPAGE : public OBJECT {
public:
DECLARE_CONSTRUCTOR( UHPFS_CODEPAGE );
VIRTUAL
~UHPFS_CODEPAGE();
NONVIRTUAL
BOOLEAN
Initialize(
);
NONVIRTUAL
BOOLEAN
Create(
IN OUT PLOG_IO_DP_DRIVE Drive,
IN LBN FirstInfoSectorLbn,
IN LBN DataSectorLbn
);
NONVIRTUAL
VERIFY_RETURN_CODE
VerifyAndFix (
IN PLOG_IO_DP_DRIVE LogicalDrive,
IN PHOTFIXLIST HotfixList,
IN PHPFS_BITMAP Bitmap,
IN LBN FirstInfoSectorLbn,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
NONVIRTUAL
BOOLEAN
Read(
IN PLOG_IO_DP_DRIVE LogicalDrive,
IN LBN FirstInfoSectorLbn
);
NONVIRTUAL
BOOLEAN
TakeCensus(
IN PLOG_IO_DP_DRIVE LogicalDrive,
IN LBN FirstInfoSectorLbn,
IN OUT PHPFS_MAIN_BITMAP HpfsOnlyBitmap
);
UHPFS_EXPORT
NONVIRTUAL
PCASEMAP
GetCasemap(
);
NONVIRTUAL
USHORT
QueryNumberOfCodepages (
);
VOID
Print (
);
private:
NONVIRTUAL
VOID
Construct (
);
NONVIRTUAL
VOID
Destroy(
);
// The CodePage object creates and maintains a _Casemap
// object; it is also responsible for destroying it.
PCASEMAP _Casemap;
USHORT mNumberOfCodepages;
USHORT mNumberOfValidCodepages;
BOOLEAN IsEntryValid[MaximumCodepagesOnVol];
USHORT CountryCodes[MaximumCodepagesOnVol];
USHORT CodepageIDs[MaximumCodepagesOnVol];
};
/*** Code Page - disk image
*
* Each volume has one or more sectors which contain information about
* the code pages stored on the volume. This information contains the
* ordering (index) of each code page, the country code, the code page
* id, lbn and offset of the code page information.
*
* Each Code Page Info sector contains up to 31 code page descriptions
* (including the locations of the code page data).
*
* Each Code Page Data sector contains up to 3 entries of code page data.
*
* Since all code pages case conversion is identical for character
* values 0-127, only 128 bytes are necessary for code page case
* conversion information.
*
* DBCS pairs are packed, with a trailing 0,0 pair terminating the list.
* No DBCS is indicated by a 0,0 pair.
*
* Currently no DBCS Code Page has more than 2 byte pairs, but we don't
* want to limit it to that.
*
* Code Page 850 is only stored once, since the case table is the same for
* ALL countries, and there is never DBCS support. It is stored with a
* 0 country code for easy matching.
*
*/
DEFINE_TYPE( ULONG, CHECKSUM );
/** DBCS_Range - DBCS range byte pairs **/
typedef struct _DBCS_Range {
UCHAR CDIB_DBCS_start;
UCHAR CDIB_DBCS_end;
} DBCS_Range;
typedef struct CPINFOENTRY { // cpinfoent
USHORT CountryCode; /* country code */
USHORT CodePageID; /* code page id */
CHECKSUM cksCP; /* checksum of code page data */
LBN lbnCPData; /* lbn containing code page data */
USHORT iCmphpfs; /* index of code page (on volume) */
USHORT cDBCSrange; /* # of DBCS ranges (0 -> no DBCS) */
} *PCPINFOENTRY;
typedef struct CPINFOSECTORD { // cpinfosecd
ULONG sig; // Data Sector Signature
ULONG cCodePage; // # of info entries in this sector
ULONG iFirstCP; // index on vol. of 1st entry in sector
LBN lbnNext; // lbn of next info sector
CPINFOENTRY cpinfoent[EntriesPerCPInfoSector]; // info entries
} *PCPINFOSECTORD;
/** CPDATAENTRY - Code Page Data entry
*
* For each code page, there is one of these structures. It contains
* the case conversion table for the upper half of the single-byte
* characters (the lower half is always translated using a fixed rule).
*/
typedef struct CPDATAENTRY { // cpdataent
USHORT CountryCode; /* country code */
USHORT CodePageID; /* code page id */
USHORT cDBCSrange; /* # of DBCS ranges */
BYTE bCaseMapTable [CharsInCasemap]; /* case conversion table for byte values
* greater than 127 */
DBCS_Range DBCS_RangeTable [1]; /* variable array of byte pairs
* (cDBCSrange + 1, with trailing 0,0)
*/
} *PCPDATAENTRY;
typedef struct CPDATASECTOR { // cpdatasec
ULONG sig;
USHORT cCodePage;
USHORT iFirstCP;
CHECKSUM cksCP[EntriesPerCPDataSector];
USHORT offCPData[EntriesPerCPDataSector];
BYTE pData[1]; // pointer to first data
} *PCPDATASECTOR;
/***************************************************************************\
CLASS: CPDATA
PURPOSE: Define data used to describe code pages.
INTERFACE: CPDATA Setup for creation or getting
NOTES:
HISTORY: 27-Mar-90 marks
define protocol
KEYWORDS:
SEEALSO:
\***************************************************************************/
class CPDATA : public SECRUN {
public:
DECLARE_CONSTRUCTOR( CPDATA );
BOOLEAN
Initialize(
IN PLOG_IO_DP_DRIVE pliodpdrv
);
BOOLEAN
Create(
OUT PCHECKSUM CheckSum
);
VOID
Flush (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN USHORT Entries,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
BOOLEAN
NextEntryToCheck (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN LBN lbn,
IN PHPFS_BITMAP Bitmap,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
BOOLEAN
ReadNextEntry (
IN LBN lbn
);
CHECKSUM
ComputeChecksum (
);
BOOLEAN
VerifyAndFix (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN PCODEPAGE_INFO CurrentInfoEntry,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
BOOLEAN
IsValid ( );
PCPDATAENTRY
GetEntry(
) CONST;
private:
NONVIRTUAL
VOID
Construct(
);
CHECKSUM ComputeChkSum ( ) CONST;
PCPDATASECTOR pcpdatasecd;
BOOLEAN mIsModified;
BOOLEAN mIsInitialized;
BOOLEAN mValidEntry;
BOOLEAN mSectorIsValid;
LBN mCurrentLbn;
USHORT mCurrentIndexInSector;
USHORT mExpectedOffset;
HMEM _hmem;
};
/***************************************************************************\
CLASS: CODEPAGE_INFO
PURPOSE: Store information about CPs and LBN pointers to CP data. CP
data is described by the CPDATA class.
INTERFACE: CODEPAGE_INFO Setup for creation or getting
NOTES:
HISTORY: 27-Mar-90 marks
define protocol
KEYWORDS:
SEEALSO:
\***************************************************************************/
class CODEPAGE_INFO : public SECRUN {
public:
DECLARE_CONSTRUCTOR( CODEPAGE_INFO );
BOOLEAN
Initialize(
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN LBN lbn
);
NONVIRTUAL
BOOLEAN
Create(
IN LBN DataSectorLbn,
IN CHECKSUM CheckSum
);
VOID
Flush (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN USHORT Entries,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
BOOLEAN
NextEntryToCheck (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN PHOTFIXLIST HotfixList,
IN PHPFS_BITMAP Bitmap,
IN USHORT ExpectedIndex,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
BOOLEAN
ReadNextEntry (
);
VERIFY_RETURN_CODE
VerifyAndFix (
IN PHOTFIXLIST HotfixList,
IN USHORT ExpectedIndex,
OUT PBOOLEAN ErrorsDetected
);
VOID
MarkEntryBad(
);
LBN
QueryDataLbn (
);
LBN
QueryCurrentLbn (
) CONST;
friend
BOOLEAN
CPDATA::VerifyAndFix (
IN PLOG_IO_DP_DRIVE pliodpdrv,
IN PCODEPAGE_INFO CurrentInfoEntry,
IN BOOLEAN UpdateAllowed,
OUT PBOOLEAN ErrorsDetected
);
USHORT
QueryCountry(
);
USHORT
QueryCPID (
);
NONVIRTUAL VOID
Print ( ) CONST;
private:
NONVIRTUAL
VOID
Construct(
);
PCPINFOSECTORD pcpinfosecd;
BOOLEAN mIsInitialized;
BOOLEAN mSectorIsValid;
BOOLEAN mIsModified;
BOOLEAN mFirstEntry;
LBN mCurrentLbn;
USHORT mCurrentIndexInSector;
HMEM _hmem;
};
INLINE
LBN
CODEPAGE_INFO::QueryCurrentLbn(
) CONST
/*++
Routine Description:
This method returns the LBN that contains the current information
entry.
Arguments
None.
Return Value:
The LBN that contains the current information entry. Zero indicates
failure.
--*/
{
return mCurrentLbn;
}
class CASEMAP : public OBJECT {
public:
DECLARE_CONSTRUCTOR( CASEMAP );
VIRTUAL
~CASEMAP (
);
NONVIRTUAL
BOOLEAN
Initialize (
);
NONVIRTUAL
BOOLEAN
HasDBCS(
IN ULONG CodePageIndex
) CONST;
NONVIRTUAL
BOOLEAN
IsDBCS(
ULONG CodePageIndex,
UCHAR Char
) CONST;
NONVIRTUAL
UCHAR
UpperCase(
UCHAR Char,
ULONG CodePageIndex
) CONST;
NONVIRTUAL
BOOLEAN
AddCodepage (
ULONG CodepageIndex,
PCPDATAENTRY pcpdataent
);
NONVIRTUAL
BOOLEAN
IsCodpageIndexValid(
ULONG CodepageIndex
) CONST;
NONVIRTUAL
USHORT
QueryCodepageId(
IN ULONG CodepageIndex
);
private:
NONVIRTUAL
VOID
Construct (
);
NONVIRTUAL
VOID
Destroy(
);
PUCHAR _CaseTable[ MaximumCodepagesOnVol ];
PBOOLEAN _IsDBCS [ MaximumCodepagesOnVol ];
USHORT _CodepageId[ MaximumCodepagesOnVol ];
BOOLEAN _IsValid[ MaximumCodepagesOnVol ];
BOOLEAN _HasDBCS[ MaximumCodepagesOnVol ];
};
INLINE
USHORT
CASEMAP::QueryCodepageId(
IN ULONG CodepageIndex
)
/*++
Routine Description:
This method returns the code page id for the specified
volume codepage.
Arguments:
CodepageIndex -- Supplies the index on the volume of the
desired codepage.
Return Value:
The codepage ID for the specified codepage.
--*/
{
return _CodepageId[CodepageIndex];
}
#endif