/*++ Copyright (c) 1993 Microsoft Corporation Module Name: bpb.hxx Abstract: This module contains the declarations for packed and unpacked Bios Parameter Block Author: Bill McJohn [BillMc] 24-September-1993 Revision History: --*/ #if !defined( _IFSUTIL_BPB_DEFN_ ) #define _IFSUTIL_BPB_DEFN_ #define cOEM 8 #define cLABEL 11 #define cSYSID 8 typedef struct _PACKED_BIOS_PARAMETER_BLOCK { UCHAR BytesPerSector[2]; // offset = 0x000 UCHAR SectorsPerCluster[1]; // offset = 0x002 UCHAR ReservedSectors[2]; // offset = 0x003 UCHAR Fats[1]; // offset = 0x005 UCHAR RootEntries[2]; // offset = 0x006 UCHAR Sectors[2]; // offset = 0x008 UCHAR Media[1]; // offset = 0x00A UCHAR SectorsPerFat[2]; // offset = 0x00B UCHAR SectorsPerTrack[2]; // offset = 0x00D UCHAR Heads[2]; // offset = 0x00F UCHAR HiddenSectors[4]; // offset = 0x011 UCHAR LargeSectors[4]; // offset = 0x015 UCHAR BigSectorsPerFat[4]; // offset = 0x019 25 UCHAR ExtFlags[2]; // offset = 0x01D 29 UCHAR FS_Version[2]; // offset = 0x01F 31 UCHAR RootDirStrtClus[4]; // offset = 0x021 33 UCHAR FSInfoSec[2]; // offset = 0x025 37 UCHAR BkUpBootSec[2]; // offset = 0x027 39 UCHAR Reserved[12]; // offset = 0x029 41 } PACKED_BIOS_PARAMETER_BLOCK; // sizeof = 0x035 53 typedef PACKED_BIOS_PARAMETER_BLOCK *PPACKED_BIOS_PARAMETER_BLOCK; // DEFINE THIS UNCHANGED PBPB for use on NTFS drive PBootSector typedef struct _OLD_PACKED_BIOS_PARAMETER_BLOCK { UCHAR BytesPerSector[2]; // offset = 0x000 UCHAR SectorsPerCluster[1]; // offset = 0x002 UCHAR ReservedSectors[2]; // offset = 0x003 UCHAR Fats[1]; // offset = 0x005 UCHAR RootEntries[2]; // offset = 0x006 UCHAR Sectors[2]; // offset = 0x008 UCHAR Media[1]; // offset = 0x00A UCHAR SectorsPerFat[2]; // offset = 0x00B UCHAR SectorsPerTrack[2]; // offset = 0x00D UCHAR Heads[2]; // offset = 0x00F UCHAR HiddenSectors[4]; // offset = 0x011 UCHAR LargeSectors[4]; // offset = 0x015 } OLD_PACKED_BIOS_PARAMETER_BLOCK; // sizeof = 0x019 typedef struct BIOS_PARAMETER_BLOCK { USHORT BytesPerSector; UCHAR SectorsPerCluster; USHORT ReservedSectors; UCHAR Fats; USHORT RootEntries; USHORT Sectors; UCHAR Media; USHORT SectorsPerFat; USHORT SectorsPerTrack; USHORT Heads; ULONG HiddenSectors; ULONG LargeSectors; ULONG BigSectorsPerFat; USHORT ExtFlags; USHORT FS_Version; ULONG RootDirStrtClus; USHORT FSInfoSec; USHORT BkUpBootSec; } BIOS_PARAMETER_BLOCK; typedef BIOS_PARAMETER_BLOCK *PBIOS_PARAMETER_BLOCK; #if !defined( _UCHAR_DEFINED_ ) #define _UCHAR_DEFINED_ // // The following types and macros are used to help unpack the packed and // misaligned fields found in the Bios parameter block // typedef union _UCHAR1 { UCHAR Uchar[1]; UCHAR ForceAlignment; } UCHAR1, *PUCHAR1; typedef union _UCHAR2 { UCHAR Uchar[2]; USHORT ForceAlignment; } UCHAR2, *PUCHAR2; typedef union _UCHAR4 { UCHAR Uchar[4]; ULONG ForceAlignment; } UCHAR4, *PUCHAR4; #define CopyUchar1(Dst,Src) { \ *((UCHAR1 *)(Dst)) = *((UNALIGNED UCHAR1 *)(Src)); \ } #define CopyUchar2(Dst,Src) { \ *((UCHAR2 *)(Dst)) = *((UNALIGNED UCHAR2 *)(Src)); \ } #define CopyU2char(Dst,Src) { \ *((UNALIGNED UCHAR2 *)(Dst)) = *((UCHAR2 *)(Src)); \ } #define CopyUchar4(Dst,Src) { \ *((UCHAR4 *)(Dst)) = *((UNALIGNED UCHAR4 *)((ULONG_PTR)(Src))); \ } #define CopyU4char(Dst, Src) { \ *((UNALIGNED UCHAR4 *)(Dst)) = *((UCHAR4 *)(Src)); \ } #endif // _UCHAR_DEFINED_ // // This macro takes a Packed BPB and fills in its Unpacked equivalent // #define UnpackBiosExt32(Bios,Pbios) { \ CopyUchar2(&((Bios)->BytesPerSector), (Pbios)->BytesPerSector ); \ CopyUchar1(&((Bios)->SectorsPerCluster), (Pbios)->SectorsPerCluster); \ CopyUchar2(&((Bios)->ReservedSectors), (Pbios)->ReservedSectors ); \ CopyUchar1(&((Bios)->Fats), (Pbios)->Fats ); \ CopyUchar2(&((Bios)->RootEntries), (Pbios)->RootEntries ); \ CopyUchar2(&((Bios)->Sectors), (Pbios)->Sectors ); \ CopyUchar1(&((Bios)->Media), (Pbios)->Media ); \ CopyUchar2(&((Bios)->SectorsPerFat), (Pbios)->SectorsPerFat ); \ CopyUchar2(&((Bios)->SectorsPerTrack), (Pbios)->SectorsPerTrack ); \ CopyUchar2(&((Bios)->Heads), (Pbios)->Heads ); \ CopyUchar4(&((Bios)->HiddenSectors), (Pbios)->HiddenSectors ); \ CopyUchar4(&((Bios)->LargeSectors), (Pbios)->LargeSectors ); \ CopyUchar4(&((Bios)->BigSectorsPerFat), (Pbios)->BigSectorsPerFat ); \ CopyUchar2(&((Bios)->ExtFlags), (Pbios)->ExtFlags ); \ CopyUchar2(&((Bios)->FS_Version), (Pbios)->FS_Version ); \ CopyUchar4(&((Bios)->RootDirStrtClus), (Pbios)->RootDirStrtClus ); \ CopyUchar2(&((Bios)->FSInfoSec), (Pbios)->FSInfoSec ); \ CopyUchar2(&((Bios)->BkUpBootSec), (Pbios)->BkUpBootSec ); \ } #define UnpackBios(Bios,Pbios) { \ CopyUchar2(&((Bios)->BytesPerSector), (Pbios)->BytesPerSector ); \ CopyUchar1(&((Bios)->SectorsPerCluster), (Pbios)->SectorsPerCluster); \ CopyUchar2(&((Bios)->ReservedSectors), (Pbios)->ReservedSectors ); \ CopyUchar1(&((Bios)->Fats), (Pbios)->Fats ); \ CopyUchar2(&((Bios)->RootEntries), (Pbios)->RootEntries ); \ CopyUchar2(&((Bios)->Sectors), (Pbios)->Sectors ); \ CopyUchar1(&((Bios)->Media), (Pbios)->Media ); \ CopyUchar2(&((Bios)->SectorsPerFat), (Pbios)->SectorsPerFat ); \ CopyUchar2(&((Bios)->SectorsPerTrack), (Pbios)->SectorsPerTrack ); \ CopyUchar2(&((Bios)->Heads), (Pbios)->Heads ); \ CopyUchar4(&((Bios)->HiddenSectors), (Pbios)->HiddenSectors ); \ CopyUchar4(&((Bios)->LargeSectors), (Pbios)->LargeSectors ); \ } // // This macro takes an Unpacked BPB and fills in its Packed equivalent // #define PackBios32(Bios,Pbios) { \ CopyU2char((Pbios)->BytesPerSector, &((Bios)->BytesPerSector) ); \ CopyUchar1((Pbios)->SectorsPerCluster, &((Bios)->SectorsPerCluster)); \ CopyU2char((Pbios)->ReservedSectors, &((Bios)->ReservedSectors) ); \ CopyUchar1((Pbios)->Fats, &((Bios)->Fats) ); \ CopyU2char((Pbios)->RootEntries, &((Bios)->RootEntries) ); \ CopyU2char((Pbios)->Sectors, &((Bios)->Sectors) ); \ CopyUchar1((Pbios)->Media, &((Bios)->Media) ); \ CopyU2char((Pbios)->SectorsPerFat, &((Bios)->SectorsPerFat) ); \ CopyU2char((Pbios)->SectorsPerTrack, &((Bios)->SectorsPerTrack) ); \ CopyU2char((Pbios)->Heads, &((Bios)->Heads) ); \ CopyU4char((Pbios)->HiddenSectors, &((Bios)->HiddenSectors) ); \ CopyU4char((Pbios)->LargeSectors, &((Bios)->LargeSectors) ); \ CopyU4char((Pbios)->BigSectorsPerFat, &((Bios)->BigSectorsPerFat) ); \ CopyU2char((Pbios)->ExtFlags, &((Bios)->ExtFlags) ); \ CopyU2char((Pbios)->FS_Version, &((Bios)->FS_Version) ); \ CopyU4char((Pbios)->RootDirStrtClus, &((Bios)->RootDirStrtClus) ); \ CopyU2char((Pbios)->FSInfoSec, &((Bios)->FSInfoSec) ); \ CopyU2char((Pbios)->BkUpBootSec, &((Bios)->BkUpBootSec) ); \ } #define PackBios(Bios,Pbios) { \ CopyU2char((Pbios)->BytesPerSector, &((Bios)->BytesPerSector) ); \ CopyUchar1((Pbios)->SectorsPerCluster, &((Bios)->SectorsPerCluster)); \ CopyU2char((Pbios)->ReservedSectors, &((Bios)->ReservedSectors) ); \ CopyUchar1((Pbios)->Fats, &((Bios)->Fats) ); \ CopyU2char((Pbios)->RootEntries, &((Bios)->RootEntries) ); \ CopyU2char((Pbios)->Sectors, &((Bios)->Sectors) ); \ CopyUchar1((Pbios)->Media, &((Bios)->Media) ); \ CopyU2char((Pbios)->SectorsPerFat, &((Bios)->SectorsPerFat) ); \ CopyU2char((Pbios)->SectorsPerTrack, &((Bios)->SectorsPerTrack) ); \ CopyU2char((Pbios)->Heads, &((Bios)->Heads) ); \ CopyU4char((Pbios)->HiddenSectors, &((Bios)->HiddenSectors) ); \ CopyU4char((Pbios)->LargeSectors, &((Bios)->LargeSectors) ); \ } // // And now, an extended BPB: // typedef struct _PACKED_EXTENDED_BIOS_PARAMETER_BLOCK { UCHAR IntelNearJumpCommand[1]; UCHAR BootStrapJumpOffset[2]; UCHAR OemData[cOEM]; PACKED_BIOS_PARAMETER_BLOCK Bpb; UCHAR PhysicalDrive[1]; // 0 = removable, 80h = fixed UCHAR CurrentHead[1]; // used for dirty partition info UCHAR Signature[1]; // boot signature UCHAR SerialNumber[4]; // volume serial number UCHAR Label[cLABEL]; // volume label, padded with spaces UCHAR SystemIdText[cSYSID]; // system ID, (e.g. FAT or HPFS) UCHAR StartBootCode; // first byte of boot code } PACKED_EXTENDED_BIOS_PARAMETER_BLOCK, *PPACKED_EXTENDED_BIOS_PARAMETER_BLOCK; typedef struct _OLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK { UCHAR IntelNearJumpCommand[1]; UCHAR BootStrapJumpOffset[2]; UCHAR OemData[cOEM]; OLD_PACKED_BIOS_PARAMETER_BLOCK Bpb; UCHAR PhysicalDrive[1]; // 0 = removable, 80h = fixed UCHAR CurrentHead[1]; // used for dirty partition info UCHAR Signature[1]; // boot signature UCHAR SerialNumber[4]; // volume serial number UCHAR Label[cLABEL]; // volume label, padded with spaces UCHAR SystemIdText[cSYSID]; // system ID, (e.g. FAT or HPFS) UCHAR StartBootCode; // first byte of boot code } OLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK, *POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK; typedef struct _EXTENDED_BIOS_PARAMETER_BLOCK { UCHAR IntelNearJumpCommand; USHORT BootStrapJumpOffset; UCHAR OemData[cOEM]; BIOS_PARAMETER_BLOCK Bpb; UCHAR PhysicalDrive; UCHAR CurrentHead; UCHAR Signature; ULONG SerialNumber; UCHAR Label[11]; UCHAR SystemIdText[8]; } EXTENDED_BIOS_PARAMETER_BLOCK, *PEXTENDED_BIOS_PARAMETER_BLOCK; // // This macro unpacks a Packed Extended BPB. // // The UnPACK with SectorsPerFat gets FAT 16 boot sector elements properly loaded for ChkDsk #define UnpackExtendedBios( Bios, Pbios ) { \ CopyUchar1( &((Bios)->IntelNearJumpCommand), (Pbios)->IntelNearJumpCommand ); \ CopyUchar2( &((Bios)->BootStrapJumpOffset), (Pbios)->BootStrapJumpOffset ); \ memcpy( (Bios)->OemData, (Pbios)->OemData, cOEM ); \ UnpackBiosExt32( &((Bios)->Bpb), &((Pbios)->Bpb)); \ if ((Bios)->Bpb.SectorsPerFat) { \ CopyUchar1( &((Bios)->PhysicalDrive), ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->PhysicalDrive ); \ CopyUchar1( &((Bios)->CurrentHead), ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->CurrentHead ); \ CopyUchar1( &((Bios)->Signature), ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->Signature ); \ CopyUchar4( &((Bios)->SerialNumber), ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->SerialNumber ); \ memcpy( (Bios)->Label, ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->Label, cLABEL ); \ memcpy( (Bios)->SystemIdText, ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->SystemIdText, cSYSID ); \ } else { \ CopyUchar1( &((Bios)->PhysicalDrive), (Pbios)->PhysicalDrive ); \ CopyUchar1( &((Bios)->CurrentHead), (Pbios)->CurrentHead ); \ CopyUchar1( &((Bios)->Signature), (Pbios)->Signature ); \ CopyUchar4( &((Bios)->SerialNumber), (Pbios)->SerialNumber ); \ memcpy( (Bios)->Label, (Pbios)->Label, cLABEL ); \ memcpy( (Bios)->SystemIdText, (Pbios)->SystemIdText, cSYSID ); \ } \ } // // This macro packs a Packed Extended BPB. // // The PACK with SectorsPerFat keeps FAT 16 boot sector unchanged on FORMAT #define PackExtendedBios( Bios, Pbios ) { \ if ((Bios)->Bpb.SectorsPerFat) { \ PackBios( &((Bios)->Bpb), &((Pbios)->Bpb)); \ CopyUchar1( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->PhysicalDrive, &((Bios)->PhysicalDrive )); \ CopyUchar1( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->CurrentHead, &((Bios)->CurrentHead )); \ CopyUchar1( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->Signature, &((Bios)->Signature)); \ CopyU4char( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->SerialNumber, &((Bios)->SerialNumber )); \ memcpy( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->Label, (Bios)->Label, cLABEL ); \ memcpy( ((POLD_PACKED_EXTENDED_BIOS_PARAMETER_BLOCK)(Pbios))->SystemIdText, (Bios)->SystemIdText, cSYSID ); \ } else { \ PackBios32( &((Bios)->Bpb), &((Pbios)->Bpb)); \ CopyUchar1( (Pbios)->PhysicalDrive, &((Bios)->PhysicalDrive )); \ CopyUchar1( (Pbios)->CurrentHead, &((Bios)->CurrentHead )); \ CopyUchar1( (Pbios)->Signature, &((Bios)->Signature)); \ CopyU4char( (Pbios)->SerialNumber, &((Bios)->SerialNumber )); \ memcpy( (Pbios)->Label, (Bios)->Label, cLABEL ); \ memcpy( (Pbios)->SystemIdText, (Bios)->SystemIdText, cSYSID ); \ } \ CopyUchar1( (Pbios)->IntelNearJumpCommand, &((Bios)->IntelNearJumpCommand) ); \ CopyU2char( (Pbios)->BootStrapJumpOffset, &((Bios)->BootStrapJumpOffset) ); \ memcpy( (Pbios)->OemData, (Bios)->OemData, cOEM ); \ } #endif