-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpartition.h
145 lines (117 loc) · 4.61 KB
/
partition.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*-*-C++-*-*/
#ifndef _PARTITION_H_
#define _PARTITION_H_
#include "vfs.h"
#include "device.h"
#ifdef RAWPOD_BIG_ENDIAN
#ifdef __APPLE__
#define bswap_32(x) OSSwapInt32(x)
#else
#include <byteswap.h>
#endif
#endif
class Partition
{
public:
Partition() {}
virtual ~Partition() {}
enum Type { Firmware, FAT32, Ext2, HFS, Other };
virtual Type type() = 0;
virtual unsigned int offset() = 0;
virtual unsigned int length() = 0;
virtual bool active() { return false; }
virtual void setType (Type t) = 0;
virtual void setOffset (unsigned int off) = 0;
virtual void setLength (unsigned int len) = 0;
virtual void setActive (bool act) { (void)act; }
};
typedef struct
{
unsigned char active;
char chs1[3];
unsigned char type;
char chs2[3];
unsigned int offset; // sectors
unsigned int length; // sectors
} DOSPartitionDesc;
class DOSPartition : public Partition
{
public:
DOSPartition (DOSPartitionDesc *desc)
: Partition(), _desc (desc)
{
}
virtual ~DOSPartition() {}
virtual Type type() { return ((_desc->type == 0)? Firmware : (_desc->type == 0xB)? FAT32 :
(_desc->type == 0x83)? Ext2 : Other); }
virtual bool active() { return (_desc->active == 0x80); }
#ifdef RAWPOD_BIG_ENDIAN
virtual unsigned int offset() { return bswap_32 (_desc->offset); }
virtual unsigned int length() { return bswap_32 (_desc->length); }
virtual void setOffset (unsigned int off) { _desc->offset = bswap_32 (off); }
virtual void setLength (unsigned int len) { _desc->length = bswap_32 (len); }
#else
virtual unsigned int offset() { return _desc->offset; }
virtual unsigned int length() { return _desc->length; }
virtual void setOffset (unsigned int off) { _desc->offset = off; }
virtual void setLength (unsigned int len) { _desc->length = len; }
#endif
virtual void setType (Type t);
virtual void setActive (bool act) { _desc->active = (act? 0x80 : 0); }
protected:
DOSPartitionDesc *_desc;
};
class PartitionTable
{
public:
PartitionTable() : parts (0), valid (false) {}
virtual ~PartitionTable() { delete[] parts; }
Partition **parts;
bool valid;
Partition *operator[](int idx) { return parts[idx]; }
operator bool() { return valid; }
unsigned int length (int idx) { return parts[idx]->length(); }
unsigned int offset (int idx) { return parts[idx]->offset(); }
Partition::Type type (int idx) { return parts[idx]->type(); }
bool active (int idx) { return parts[idx]->active(); }
void setLength (int idx, unsigned int length) { parts[idx]->setLength (length); }
void setOffset (int idx, unsigned int offset) { parts[idx]->setOffset (offset); }
void setType (int idx, Partition::Type type) { parts[idx]->setType (type); }
void setActive (int idx, bool active) { parts[idx]->setActive (active); }
virtual void readFrom (VFS::Device *dev) = 0;
virtual int writeTo (VFS::Device *dev) = 0;
virtual int figureOutType (unsigned char *mbr) = 0;
int shrinkAndAdd (int oldnr, int newnr, Partition::Type newtype, unsigned int newsize);
static PartitionTable *create (int devnr, bool writable) { LocalRawDevice dev (devnr, writable); return create (&dev); }
static PartitionTable *create (VFS::Device *dev);
protected:
PartitionTable (int nptns) { parts = new Partition*[nptns]; }
};
class DOSPartitionTable : public PartitionTable
{
public:
DOSPartitionTable() : PartitionTable() {}
DOSPartitionTable (VFS::Device *dev) : PartitionTable (4) { readFrom (dev); }
~DOSPartitionTable() { for (int i = 0; i < 4; i++) { delete parts[i]; } }
virtual void readFrom (VFS::Device *dev);
virtual int writeTo (VFS::Device *dev);
#define PART_NOT_IPOD 0
#define PART_WINPOD 1 // p1 = firmware, p2 = music
#define PART_MACPOD 2 // p1 = pmap, p2 = firmware, p3 = music
#define PART_SLINPOD 3 // LinPod with p3 after p1, before p2, using space from firmware partition
#define PART_BLINPOD 4 // LinPod with p3 after p2, or between p's 1&2 but taking space out of music ptn
virtual int figureOutType (unsigned char *mbr);
protected:
DOSPartitionDesc _pdata[4];
};
// return 0 for success, nonzero for failure
int devReadMBR (int devnr, unsigned char *buf);
int devWriteMBR (int devnr, unsigned char *buf);
// returns the size in 512-byte sectors for success, 0 or negative for failure
u64 devGetSize (int devnr);
// returns -1 for failure, or the devnr
int find_iPod();
// returns 0 for failure and prints a message
VFS::Device *setup_partition (int disknr, int partnr);
VFS::Device *setup_partition (VFS::Device *disk, int partnr);
#endif