| 1 | /*	$OpenBSD: bpb.h,v 1.7 2015/10/23 10:45:31 krw Exp $	*/ |
| 2 | /*	$NetBSD: bpb.h,v 1.6 1997/10/17 11:23:35 ws Exp $	*/ |
| 3 | |
| 4 | /* |
| 5 | * Written by Paul Popelka (paulp@uts.amdahl.com) |
| 6 | * |
| 7 | * You can do anything you want with this software, just don't say you wrote |
| 8 | * it, and don't remove this notice. |
| 9 | * |
| 10 | * This software is provided "as is". |
| 11 | * |
| 12 | * The author supplies this software to be publicly redistributed on the |
| 13 | * understanding that the author is not responsible for the correct |
| 14 | * functioning of this software in any circumstances and is not liable for |
| 15 | * any damages caused by this software. |
| 16 | * |
| 17 | * October 1992 |
| 18 | */ |
| 19 | |
| 20 | /* |
| 21 | * BIOS Parameter Block (BPB) for DOS 3.3 |
| 22 | */ |
| 23 | struct bpb33 { |
| 24 | 	u_int16_t	bpbBytesPerSec;	/* bytes per sector */ |
| 25 | 	u_int8_t	bpbSecPerClust;	/* sectors per cluster */ |
| 26 | 	u_int16_t	bpbResSectors;	/* number of reserved sectors */ |
| 27 | 	u_int8_t	bpbFATs;	/* number of FATs */ |
| 28 | 	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */ |
| 29 | 	u_int16_t	bpbSectors;	/* total number of sectors */ |
| 30 | 	u_int8_t	bpbMedia;	/* media descriptor */ |
| 31 | 	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */ |
| 32 | 	u_int16_t	bpbSecPerTrack;	/* sectors per track */ |
| 33 | 	u_int16_t	bpbHeads;	/* number of heads */ |
| 34 | 	u_int16_t	bpbHiddenSecs;	/* number of hidden sectors */ |
| 35 | }; |
| 36 | |
| 37 | /* |
| 38 | * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, |
| 39 | * and bpbHugeSectors is not in the 3.3 bpb. |
| 40 | */ |
| 41 | struct bpb50 { |
| 42 | 	u_int16_t	bpbBytesPerSec;	/* bytes per sector */ |
| 43 | 	u_int8_t	bpbSecPerClust;	/* sectors per cluster */ |
| 44 | 	u_int16_t	bpbResSectors;	/* number of reserved sectors */ |
| 45 | 	u_int8_t	bpbFATs;	/* number of FATs */ |
| 46 | 	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */ |
| 47 | 	u_int16_t	bpbSectors;	/* total number of sectors */ |
| 48 | 	u_int8_t	bpbMedia;	/* media descriptor */ |
| 49 | 	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */ |
| 50 | 	u_int16_t	bpbSecPerTrack;	/* sectors per track */ |
| 51 | 	u_int16_t	bpbHeads;	/* number of heads */ |
| 52 | 	u_int32_t	bpbHiddenSecs;	/* # of hidden sectors */ |
| 53 | 	u_int32_t	bpbHugeSectors;	/* # of sectors if bpbSectors == 0 */ |
| 54 | }; |
| 55 | |
| 56 | /* |
| 57 | * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. |
| 58 | */ |
| 59 | struct bpb710 { |
| 60 | 	u_int16_t	bpbBytesPerSec;	/* bytes per sector */ |
| 61 | 	u_int8_t	bpbSecPerClust;	/* sectors per cluster */ |
| 62 | 	u_int16_t	bpbResSectors;	/* number of reserved sectors */ |
| 63 | 	u_int8_t	bpbFATs;	/* number of FATs */ |
| 64 | 	u_int16_t	bpbRootDirEnts;	/* number of root directory entries */ |
| 65 | 	u_int16_t	bpbSectors;	/* total number of sectors */ |
| 66 | 	u_int8_t	bpbMedia;	/* media descriptor */ |
| 67 | 	u_int16_t	bpbFATsecs;	/* number of sectors per FAT */ |
| 68 | 	u_int16_t	bpbSecPerTrack;	/* sectors per track */ |
| 69 | 	u_int16_t	bpbHeads;	/* number of heads */ |
| 70 | 	u_int32_t	bpbHiddenSecs;	/* # of hidden sectors */ |
| 71 | 	u_int32_t	bpbHugeSectors;	/* # of sectors if bpbSectors == 0 */ |
| 72 | 	u_int32_t	bpbBigFATsecs;	/* like bpbFATsecs for FAT32 */ |
| 73 | 	u_int16_t	bpbExtFlags;	/* extended flags: */ |
| 74 | #define	FATNUM		0xf		/* mask for numbering active FAT */ |
| 75 | #define	FATMIRROR	0x80		/* FAT is mirrored (like it always was) */ |
| 76 | 	u_int16_t	bpbFSVers;	/* filesystem version */ |
| 77 | #define	FSVERS		0		/* currently only 0 is understood */ |
| 78 | 	u_int32_t	bpbRootClust;	/* start cluster for root directory */ |
| 79 | 	u_int16_t	bpbFSInfo;	/* filesystem info structure sector */ |
| 80 | 	u_int16_t	bpbBackup;	/* backup boot sector */ |
| 81 | 	/* There is a 12 byte filler here, but we ignore it */ |
| 82 | }; |
| 83 | |
| 84 | /* |
| 85 | * The following structures represent how the bpb's look on disk. shorts |
| 86 | * and longs are just character arrays of the appropriate length. This is |
| 87 | * because the compiler forces shorts and longs to align on word or |
| 88 | * halfword boundaries. |
| 89 | * |
| 90 | * XXX The little-endian code here assumes that the processor can access |
| 91 | * 16-bit and 32-bit quantities on byte boundaries. If this is not true, |
| 92 | * use the macros for the big-endian case. |
| 93 | */ |
| 94 | #include <sys/endian.h> |
| 95 | #if (BYTE_ORDER == LITTLE_ENDIAN) && !defined(__STRICT_ALIGNMENT) |
| 96 | #define	getushort(x)	*((u_int16_t *)(x)) |
| 97 | #define	getulong(x)	*((u_int32_t *)(x)) |
| 98 | #define	putushort(p, v)	(*((u_int16_t *)(p)) = (v)) |
| 99 | #define	putulong(p, v)	(*((u_int32_t *)(p)) = (v)) |
| 100 | #else |
| 101 | #define getushort(x)	(((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8)) |
| 102 | #define getulong(x)	(((u_int8_t *)(x))[0] + (((u_int8_t *)(x))[1] << 8) \ |
| 103 | 			 + (((u_int8_t *)(x))[2] << 16)	\ |
| 104 | 			 + (((u_int8_t *)(x))[3] << 24)) |
| 105 | #define putushort(p, v)	(((u_int8_t *)(p))[0] = (v),	\ |
| 106 | 			 ((u_int8_t *)(p))[1] = (v) >> 8) |
| 107 | #define putulong(p, v)	(((u_int8_t *)(p))[0] = (v),	\ |
| 108 | 			 ((u_int8_t *)(p))[1] = (v) >> 8, \ |
| 109 | 			 ((u_int8_t *)(p))[2] = (v) >> 16,\ |
| 110 | 			 ((u_int8_t *)(p))[3] = (v) >> 24) |
| 111 | #endif |
| 112 | |
| 113 | /* |
| 114 | * BIOS Parameter Block (BPB) for DOS 3.3 |
| 115 | */ |
| 116 | struct byte_bpb33 { |
| 117 | 	int8_t bpbBytesPerSec[2];	/* bytes per sector */ |
| 118 | 	int8_t bpbSecPerClust;		/* sectors per cluster */ |
| 119 | 	int8_t bpbResSectors[2];	/* number of reserved sectors */ |
| 120 | 	int8_t bpbFATs;			/* number of FATs */ |
| 121 | 	int8_t bpbRootDirEnts[2];	/* number of root directory entries */ |
| 122 | 	int8_t bpbSectors[2];		/* total number of sectors */ |
| 123 | 	int8_t bpbMedia;		/* media descriptor */ |
| 124 | 	int8_t bpbFATsecs[2];		/* number of sectors per FAT */ |
| 125 | 	int8_t bpbSecPerTrack[2];	/* sectors per track */ |
| 126 | 	int8_t bpbHeads[2];		/* number of heads */ |
| 127 | 	int8_t bpbHiddenSecs[2];	/* number of hidden sectors */ |
| 128 | }; |
| 129 | |
| 130 | /* |
| 131 | * BPB for DOS 5.0 The difference is bpbHiddenSecs is a short for DOS 3.3, |
| 132 | * and bpbHugeSectors is not in the 3.3 bpb. |
| 133 | */ |
| 134 | struct byte_bpb50 { |
| 135 | 	int8_t bpbBytesPerSec[2];	/* bytes per sector */ |
| 136 | 	int8_t bpbSecPerClust;		/* sectors per cluster */ |
| 137 | 	int8_t bpbResSectors[2];	/* number of reserved sectors */ |
| 138 | 	int8_t bpbFATs;			/* number of FATs */ |
| 139 | 	int8_t bpbRootDirEnts[2];	/* number of root directory entries */ |
| 140 | 	int8_t bpbSectors[2];		/* total number of sectors */ |
| 141 | 	int8_t bpbMedia;		/* media descriptor */ |
| 142 | 	int8_t bpbFATsecs[2];		/* number of sectors per FAT */ |
| 143 | 	int8_t bpbSecPerTrack[2];	/* sectors per track */ |
| 144 | 	int8_t bpbHeads[2];		/* number of heads */ |
| 145 | 	int8_t bpbHiddenSecs[4];	/* number of hidden sectors */ |
| 146 | 	int8_t bpbHugeSectors[4];	/* # of sectors if bpbSectors == 0 */ |
| 147 | }; |
| 148 | |
| 149 | /* |
| 150 | * BPB for DOS 7.10 (FAT32). This one has a few extensions to bpb50. |
| 151 | */ |
| 152 | struct byte_bpb710 { |
| 153 | 	u_int8_t bpbBytesPerSec[2];	/* bytes per sector */ |
| 154 | 	u_int8_t bpbSecPerClust;	/* sectors per cluster */ |
| 155 | 	u_int8_t bpbResSectors[2];	/* number of reserved sectors */ |
| 156 | 	u_int8_t bpbFATs;		/* number of FATs */ |
| 157 | 	u_int8_t bpbRootDirEnts[2];	/* number of root directory entries */ |
| 158 | 	u_int8_t bpbSectors[2];		/* total number of sectors */ |
| 159 | 	u_int8_t bpbMedia;		/* media descriptor */ |
| 160 | 	u_int8_t bpbFATsecs[2];		/* number of sectors per FAT */ |
| 161 | 	u_int8_t bpbSecPerTrack[2];	/* sectors per track */ |
| 162 | 	u_int8_t bpbHeads[2];		/* number of heads */ |
| 163 | 	u_int8_t bpbHiddenSecs[4];	/* # of hidden sectors */ |
| 164 | 	u_int8_t bpbHugeSectors[4];	/* # of sectors if bpbSectors == 0 */ |
| 165 | 	u_int8_t bpbBigFATsecs[4];	/* like bpbFATsecs for FAT32 */ |
| 166 | 	u_int8_t bpbExtFlags[2];	/* extended flags: */ |
| 167 | 	u_int8_t bpbFSVers[2];		/* filesystem version */ |
| 168 | 	u_int8_t bpbRootClust[4];	/* start cluster for root directory */ |
| 169 | 	u_int8_t bpbFSInfo[2];		/* filesystem info structure sector */ |
| 170 | 	u_int8_t bpbBackup[2];		/* backup boot sector */ |
| 171 | 	/* There is a 12 byte filler here, but we ignore it */ |
| 172 | }; |
| 173 | |
| 174 | /* |
| 175 | * FAT32 FSInfo block. |
| 176 | */ |
| 177 | struct fsinfo { |
| 178 | 	u_int8_t fsisig1[4]; |
| 179 | 	u_int8_t fsifill1[480]; |
| 180 | 	u_int8_t fsisig2[4]; |
| 181 | 	u_int8_t fsinfree[4]; |
| 182 | 	u_int8_t fsinxtfree[4]; |
| 183 | 	u_int8_t fsifill2[12]; |
| 184 | 	u_int8_t fsisig3[4]; |
| 185 | 	u_int8_t fsifill3[508]; |
| 186 | 	u_int8_t fsisig4[4]; |
| 187 | }; |