/*static char *SCCSID = "@(#)codepage.h	6.1 90/11/18";*/
/*static char *SCCSID = "@(#)codepage.h   13.4 90/01/25";*/
/**	codepage.h - Code Page structures (disk & memory)
 *
 *	HISTORY
 *	    25-Aug-89 by JR (John Rogers, JohnRo@Microsoft)
 *		- Converted HPFS from OS/2 1.2 to run with OS/2 2.0 (really
 *		  changed comment style to not use slash-slash, as it generates
 *		  too many warnings under MSC 5.2 with /W3 switch).
 *	    19-May-1989 15:54:38 Mark Hitch [markh] first draft
 */

/* XLATOFF */
#include "CODEPAGE.NAM"

/***	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, lsn 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.
 *
 *	If no Code Page is specified in Config.Sys, a code page (valid for the
 *	specified or default country) is loaded anyway.  DosGetCP return 0, but
 *	HPFS saves the actual Code Page number.
 */

/**	DBCS_Range - DBCS range byte pairs
 *
 *	(Uses definition from cdib.h)
 */

typedef struct CDIB_DBCS_range_section DBCS_Range;


/**	CPINFOENT - Code Page information entry
 *
 *	For each code page described, contains country code, code page ID,
 *	checksum of code page data, lsn & offset of the code page data and
 *	the count of DBCS ranges.
 */

typedef struct CPInfoEntry { /* CPInfoEntry */
    USHORT   CountryCode;		/* country code */
    USHORT   CodePageID;		/* code page id */
    CHECKSUM cksCP;			/* checksum of code page data */
    LSN      lsnCPData; 		/* lsn containing code page data */
    USHORT   iCPVol;			/* index of code page (on volume) */
    USHORT   cDBCSrange;		/* # of DBCS ranges (0 -> no DBCS) */
} CPInfoEntry;   /* CPInfoEntry */

typedef struct CPInfoEntry CPINFOENTRY;
typedef CPINFOENTRY far * PCPINFOENTRY;


/**	CPINFOSECTOR - Code Page information sector
 *
 *	Each CodePageSector contains information about 31 code pages and
 *	which LSN contains the code page data.	Also contains count
 *	of code pages described by the sector and the next CodePageSector
 *	lsn if there are more code pages.
 */

/* #define CPPERINFOSEC 7 */
#define CPPERINFOSEC 31

typedef struct CodePageInfoSector { /* CodePageInfoSector */
    SIGNATURE	sig;			/* signature of code page descriptor */
    ULONG	cCodePage;		/* count of cp info's in this lsn */
    ULONG	iFirstCP;		/* index of 1st code page in this lsn */
    LSN 	lsnNext;		/* next sector, if more Code Pages */
    CPINFOENTRY CPInfoEnt [CPPERINFOSEC];
					/* array of code page descriptions */
} CodePageInfoSector;   /* CodePageInfoSector */

typedef struct CodePageInfoSector CPINFOSECTOR;
typedef CPINFOSECTOR far *PCPINFOSECTOR;


/**	CPDATASECTOR - Code Page Data Sector header
 *
 *	Header of sector contain 1-3 code page data elements.
 */

#define CPPERDATASEC 3

typedef struct CPDataSector { /* CPDataSector */
    SIGNATURE sig;			/* signature of code page data sector */
    USHORT    cCodePage;		/* count of code pages in this sector */
    USHORT    iFirstCP; 		/* index of first code page in sector */
    CHECKSUM  cksCP [CPPERDATASEC];	/* checksum of code page data area */
    USHORT    offCPData [CPPERDATASEC]; /* offset to each Code Page Data ent. */
} CPDataSector;   /* CPDataSector */

typedef struct CPDataSector CPDATASECTOR;
typedef CPDATASECTOR far * PCPDATASECTOR;

/**	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 { /* CPDataEntry */
    USHORT CountryCode; 		/* country code */
    USHORT CodePageID;			/* code page id */
    USHORT cDBCSrange;			/* # of DBCS ranges */
    BYTE   bCaseMapTable [128]; 	/* case conversion table for byte values
					 * greater than 127 */
    DBCS_Range DBCS_Range [1];		/* variable array of byte pairs
					 * (cDBCSrange + 1, with trailing 0,0)
					 */
} CPDataEntry;   /* CPDataEntry */

typedef struct CPDataEntry CPDATAENTRY;
typedef CPDATAENTRY far * PCPDATAENTRY;

/***	Code Page Sector Signatures
 */

#define VAL_M1		((('M'-'A')*40+('A'-'A'))*40+'H'-'A')
#define VAL_M2		((('M'-'A')*40+('G'-'A'))*40+'H'-'A')

/* Code Page Info sectors */
#define CPINFOVAL	((LONG)VAL_M1*40*40*40 + (LONG)VAL_M2 )

/* Code Page Data sectors */
#define CPDATAVAL	(0x40000000L + (LONG)VAL_M1*40*40*40 + (LONG)VAL_M2)


/***	Code Page Information - Global Memory
 *
 *	For each system code page and each code page described, HPFS keeps
 *	a table (in heap).  Full case conversion XLAT tables (256 bytes) are
 *	built from the 128 byte table (from system or volume).	If a code page
 *	is DBCS, another 256 bytes table is built (from (start,end) pairs for
 *	flagging the valid lead bytes.
 *
 *	DBCS pairs are only used to build the tables.  But this information
 *	must be added to mounting volumes, if the code page is not already
 *	on that volume.  At this time the DBCS pairs are obtained from the
 *	system information.
 */

/* XLATON */

/**	CodePage - Case conversion & DBCS information
 *
 *	For each known country/code page combination (code page 850 applies
 *	to all countries, and is only stored once), the case conversion table
 *	and DBCS lead byte information are needed.
 */

typedef struct CPENTRY { /* CPENTRY */
    USHORT CountryCode; 	    /* Country Code identifier */
    USHORT CodePageID;		    /* Code Page identifier */
    unsigned char far *pCaseTable;  /* pointer to Case conversion table (256
				     * bytes) used for XLAT */
    unsigned oDBCSTable;	    /* offset to DBCS lead byte table (256
				     * bytes) - valid only if CPF_REQUIRED is
				     * set.  Segment is the same as pCaseTable
				     */
    BYTE bFlags;		    /* Bit flags (See CPF_xxx below) */
    BYTE Dummy [5];		    /* filler to bring to power of 2 */
} CPENTRY;   /* CPENTRY */

typedef CPENTRY far *PCPENTRY;


/* bFlags bit values */

#define CPF_REQUIRED 0x01   /* System code page - must be added to each volume
			     * if not already present.	Currently at most 2
			     */
#define CPF_DBCS     0x02   /* DBCS code page - pDBCSInfo is valid */

/* XLATOFF */


/*  DBCSTable bit values */

#define DBCSLead     0x01   /* Byte is a valid lead byte of DBCS pair */


/*  Maximum number of code pages supported */

#define CMAXCODEPAGES 128   /* only 128 code pages supported - for now */


/*  CodePage global variables */

extern USHORT SelCDIB;			/* selector of system codepage
					 * shared-mem seg */

extern USHORT usCountry;		/* Current country code */

extern USHORT cCodePage;		/* count of code pages (current system
					 * and from all mounted volumes) */

extern PBYTE pCodePageSeg;		/* pointer past end of segment (used
					 * as selector & sizeof segment) */

extern PCPENTRY paCodePageEnt;		/* pointer to array of code page info
					 * (used for case mapping and during
					 * volume mounts. */

PBYTE pbCaseCmpBuf;			/* temp buffer (in same segment as XLAT
					 * tables - used for upcase & compare
					 * operations. */

PUSHORT pcurCodePage;			/* pointer to get the current code
					 * page (dirty hook into PTDA, which is
					 * in the current stack */


/* Prototypes for all Code Page / UpCase functions */

	extern SHORT NameUpCaseCmp (PBYTE    pbCandidate,
				    USHORT   cbCandidate,
				    PBYTE    pbSubject,
				    USHORT   cbSubject,
				    PCPENTRY pCPEnt);

	extern void NameUpCase	   (PBYTE    pbDirEnt,
				    USHORT   cbDirEnt,
				    PCPENTRY pCPEnt,
				    PBYTE    pbDest);
#include "CODEPAGE.SEG"
