srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 1 | /* bsd.h -- BSD disklabel data structure definitions, types, and functions */ |
| 2 | |
| 3 | /* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed |
| 4 | under the terms of the GNU GPL version 2, as detailed in the COPYING file. */ |
| 5 | |
| 6 | #include <stdint.h> |
| 7 | #include <sys/types.h> |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 8 | #include "gptpart.h" |
srs5694 | 546a9c7 | 2010-01-26 16:00:26 -0500 | [diff] [blame] | 9 | #include "diskio.h" |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 10 | |
| 11 | #ifndef __BSD_STRUCTS |
| 12 | #define __BSD_STRUCTS |
| 13 | |
srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 14 | #define BSD_SIGNATURE UINT32_C(0x82564557) /* BSD disklabel signature ("magic") */ |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 15 | |
srs5694 | 546a9c7 | 2010-01-26 16:00:26 -0500 | [diff] [blame] | 16 | // BSD disklabels can start at offsets of 64 or the sector size -- at least, |
| 17 | // I *THINK* that's what's going on. I've seen them at 64 or 512 on disks |
| 18 | // with 512-byte blocks and at 2048 on disks with 2048-byte blocks. The |
| 19 | // LABEL_OFFSET2 value will be replaced by the block size in the |
| 20 | // ReadBSDData() function.... |
| 21 | #define LABEL_OFFSET1 64 |
| 22 | #define LABEL_OFFSET2 512 |
| 23 | #define NUM_OFFSETS 2 |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 24 | |
| 25 | // FreeBSD documents a maximum # of partitions of 8, but I saw 16 on a NetBSD |
| 26 | // disk. I'm quadrupling that for further safety. Note that BSDReadData() |
srs5694 | ba00fed | 2010-01-12 18:18:36 -0500 | [diff] [blame] | 27 | // uses a 4096-byte I/O buffer. In combination with LABEL_OFFSET3 and the |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 28 | // additional 148-byte offset to the actual partition data, that gives a |
srs5694 | ba00fed | 2010-01-12 18:18:36 -0500 | [diff] [blame] | 29 | // theoretical maximum of 118.75 partitions that the program can handle before |
| 30 | // memory errors will occur. |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 31 | #define MAX_BSD_PARTS 64 |
| 32 | |
| 33 | |
| 34 | using namespace std; |
| 35 | |
| 36 | /**************************************** |
| 37 | * * |
| 38 | * BSDData class and related structures * |
| 39 | * * |
| 40 | ****************************************/ |
| 41 | |
| 42 | // Possible states of the MBR |
| 43 | enum BSDValidity {unknown, bsd_invalid, bsd}; |
| 44 | |
| 45 | // Data for a single BSD partition record |
srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 46 | // Create entries for all fields, although we only use lengthLBA, firstLBA, |
| 47 | // and fsType, to simplify loading the data from disk.... |
| 48 | struct BSDRecord { // the partition table |
| 49 | uint32_t lengthLBA; // number of sectors in partition |
| 50 | uint32_t firstLBA; // starting sector |
| 51 | uint32_t fragSize; // filesystem basic fragment size |
| 52 | uint8_t fsType; // filesystem type, see below |
| 53 | uint8_t frag; // filesystem fragments per block |
| 54 | uint16_t pcpg; // filesystem cylinders per group |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 55 | }; |
| 56 | |
srs5694 | ba00fed | 2010-01-12 18:18:36 -0500 | [diff] [blame] | 57 | // Full data in tweaked BSD format |
srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 58 | // For some reason this has to be packed or MS Visual C++'s debugger complains |
| 59 | // about memory errors whenever a BSDData variable is destroyed. |
| 60 | #pragma pack (8) |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 61 | class BSDData { |
| 62 | protected: |
| 63 | // We only need a few items from the main BSD disklabel data structure.... |
srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 64 | uint32_t signature; // the magic number |
| 65 | uint32_t sectorSize; // # of bytes per sector |
| 66 | uint32_t signature2; // the magic number (again) |
| 67 | uint16_t numParts; // number of partitions in table |
srs5694 | 08bb0da | 2010-02-19 17:19:55 -0500 | [diff] [blame] | 68 | struct BSDRecord* partitions; // partition array |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 69 | |
| 70 | // Above are basic BSD disklabel data; now add more stuff.... |
srs5694 | e4ac11e | 2009-08-31 10:13:04 -0400 | [diff] [blame] | 71 | uint64_t labelFirstLBA; // first sector of BSD disklabel (partition or disk) |
| 72 | uint64_t labelLastLBA; // final sector of BSD disklabel |
| 73 | uint64_t labelStart; // BSD disklabel start point in bytes from labelFirstLBA |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 74 | BSDValidity state; |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 75 | public: |
| 76 | BSDData(void); |
| 77 | ~BSDData(void); |
srs5694 | 0a69731 | 2010-01-28 21:10:52 -0500 | [diff] [blame] | 78 | int ReadBSDData(const string & deviceFilename, uint64_t startSector, uint64_t endSector); |
srs5694 | fed16d0 | 2010-01-27 23:03:40 -0500 | [diff] [blame] | 79 | int ReadBSDData(DiskIO *myDisk, uint64_t startSector, uint64_t endSector); |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 80 | void ReverseMetaBytes(void); |
| 81 | void DisplayBSDData(void); |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 82 | int ShowState(void); // returns 1 if BSD disklabel detected |
srs5694 | a6022b0 | 2010-01-19 16:17:20 -0500 | [diff] [blame] | 83 | int IsDisklabel(void); |
srs5694 | a0eb11a | 2009-08-29 15:00:08 -0400 | [diff] [blame] | 84 | |
| 85 | // Functions to extract data on specific partitions.... |
| 86 | uint8_t GetType(int i); |
| 87 | uint64_t GetFirstSector(int i); |
| 88 | uint64_t GetLength(int i); |
| 89 | int GetNumParts(void); |
| 90 | GPTPart AsGPT(int i); // Return BSD part. as GPT part. |
| 91 | }; // struct MBRData |
| 92 | |
| 93 | #endif |