1 /*
2     SPDX-FileCopyrightText: 2008-2012 Volker Lanz <vl@fidra.de>
3     SPDX-FileCopyrightText: 2008 Laurent Montel <montel@kde.org>
4     SPDX-FileCopyrightText: 2015 Chris Campbell <c.j.campbell@ed.ac.uk>
5     SPDX-FileCopyrightText: 2016-2019 Andrius Štikonas <andrius@stikonas.eu>
6     SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org>
7     SPDX-FileCopyrightText: 2016 Chantara Tith <tith.chantara@gmail.com>
8 
9     SPDX-License-Identifier: GPL-3.0-or-later
10 */
11 
12 #ifndef KPMCORE_PARTITIONTABLE_H
13 #define KPMCORE_PARTITIONTABLE_H
14 
15 #include "util/libpartitionmanagerexport.h"
16 
17 #include "core/partitionnode.h"
18 #include "core/partitionrole.h"
19 
20 #include <QList>
21 #include <QtGlobal>
22 
23 class Device;
24 class Partition;
25 class CoreBackend;
26 
27 class QTextStream;
28 
29 /** The partition table (a.k.a Disk Label)
30 
31     PartitionTable represents a partition table (or disk label).
32 
33     PartitionTable has child nodes that represent Partitions.
34 
35     @author Volker Lanz <vl@fidra.de>
36 */
37 class LIBKPMCORE_EXPORT PartitionTable : public PartitionNode
38 {
39     PartitionTable &operator=(const PartitionTable &) = delete;
40 
41     friend class CoreBackend;
42     friend LIBKPMCORE_EXPORT QTextStream& operator<<(QTextStream& stream, const PartitionTable& ptable);
43 
44 public:
45     enum TableType : int8_t {
46         unknownTableType = -1,
47 
48         aix,
49         bsd,
50         dasd,
51         msdos,
52         msdos_sectorbased,
53         dvh,
54         gpt,
55         loop,
56         mac,
57         pc98,
58         amiga,
59         sun,
60         vmd,  /* Volume Manager Device */
61         none, /* Single FileSystem devices */
62     };
63 
64     /** Partition flags */
65     enum Flag : uint32_t {
66         None = 0x0,
67         Boot = 0x1,
68         Root = 0x2,
69         Swap = 0x4,
70         Hidden = 0x8,
71         Raid = 0x10,
72         Lvm = 0x20,
73         Lba = 0x40,
74         HpService = 0x80,
75         Palo = 0x100,
76         Prep = 0x200,
77         MsftReserved = 0x400,
78         BiosGrub = 0x800,
79         AppleTvRecovery = 0x1000,
80         Diag = 0x2000,
81         LegacyBoot = 0x4000,
82         MsftData = 0x8000,
83         Irst = 0x100000,
84         FlagNone [[deprecated("Use PartitionTable::Flag::None")]] = None,
85         FlagBoot [[deprecated("Use PartitionTable::Flag::Boot")]] = Boot,
86         FlagRoot [[deprecated("Use PartitionTable::Flag::Root")]] = Root,
87         FlagSwap [[deprecated("Use PartitionTable::Flag::Swap")]] = Swap,
88         FlagHidden [[deprecated("Use PartitionTable::Flag::Hidden")]] = Hidden,
89         FlagRaid [[deprecated("Use PartitionTable::Flag::Raid")]] = Raid,
90         FlagLvm [[deprecated("Use PartitionTable::Flag::Lvm")]] = Lvm,
91         FlagLba [[deprecated("Use PartitionTable::Flag::Lba")]] = Lba,
92         FlagHpService [[deprecated("Use PartitionTable::Flag::HpService")]] = HpService,
93         FlagPalo [[deprecated("Use PartitionTable::Flag::Palo")]] = Palo,
94         FlagPrep [[deprecated("Use PartitionTable::Flag::Prep")]] = Prep,
95         FlagMsftReserved [[deprecated("Use PartitionTable::Flag::MsftReserved")]] = MsftReserved,
96         FlagBiosGrub [[deprecated("Use PartitionTable::Flag::BiosGrub")]] = BiosGrub,
97         FlagAppleTvRecovery [[deprecated("Use PartitionTable::Flag::AppleTvRecovery")]] = AppleTvRecovery,
98         FlagDiag [[deprecated("Use PartitionTable::Flag::Diag")]] = Diag,
99         FlagLegacyBoot [[deprecated("Use PartitionTable::Flag::LegacyBoot")]] = LegacyBoot,
100         FlagMsftData [[deprecated("Use PartitionTable::Flag::MsftData")]] = MsftData,
101         FlagIrst [[deprecated("Use PartitionTable::Flag::Irst")]] = Irst,
102         FlagEsp [[deprecated("Use PartitionTable::Flag::Boot")]] = Boot
103     };
104 
105     Q_DECLARE_FLAGS(Flags, Flag)
106 
107 public:
108     PartitionTable(TableType type, qint64 firstUsable, qint64 lastUsable);
109     PartitionTable(const PartitionTable& other);
110     ~PartitionTable() override;
111 
112 public:
parent()113     PartitionNode* parent() override {
114         return nullptr;    /**< @return always nullptr for PartitionTable */
115     }
parent()116     const PartitionNode* parent() const override {
117         return nullptr;    /**< @return always nullptr for PartitionTable */
118     }
119 
isRoot()120     bool isRoot() const override {
121         return true;    /**< @return always true for PartitionTable */
122     }
isReadOnly()123     bool isReadOnly() const {
124         return tableTypeIsReadOnly(type());    /**< @return true if the PartitionTable is read only */
125     }
126 
children()127     Partitions& children() override {
128         return m_Children;    /**< @return the children in this PartitionTable */
129     }
children()130     const Partitions& children() const override {
131         return m_Children;    /**< @return the children in this PartitionTable */
132     }
133 
134     void setType(const Device& d, TableType t);
135 
136     void append(Partition* partition) override;
137 
138     qint64 freeSectorsBefore(const Partition& p) const;
139     qint64 freeSectorsAfter(const Partition& p) const;
140     qint64 freeSectors() const;
141 
142     bool hasExtended() const;
143     Partition* extended() const;
144 
145     PartitionRole::Roles childRoles(const Partition& p) const;
146 
147     qint32 numPrimaries() const;
maxPrimaries()148     qint32 maxPrimaries() const {
149         return m_MaxPrimaries;    /**< @return max number of primary partitions this PartitionTable can handle */
150     }
151 
type()152     PartitionTable::TableType type() const {
153         return m_Type;    /**< @return the PartitionTable's type */
154     }
typeName()155     const QString typeName() const {
156         return tableTypeToName(type());    /**< @return the name of this PartitionTable type */
157     }
158 
firstUsable()159     qint64 firstUsable() const {
160         return m_FirstUsable;
161     }
lastUsable()162     qint64 lastUsable() const {
163         return m_LastUsable;
164     }
165 
setFirstUsableSector(qint64 s)166     void setFirstUsableSector(qint64 s) {
167         m_FirstUsable = s;
168     }
setLastUsableSector(qint64 s)169     void setLastUsableSector(qint64 s) {
170         m_LastUsable = s;
171     }
172 
173     void updateUnallocated(const Device& d);
174     void insertUnallocated(const Device& d, PartitionNode* p, qint64 start);
175 
176     bool isSectorBased(const Device& d) const;
177 
178     static const QList<Flag> flagList();
179     static QString flagName(Flag f);
180     static QStringList flagNames(Flags f);
181     static PartitionTable::Flags flagsFromList(const QStringList list);
182 
183     static bool getUnallocatedRange(const Device& device, PartitionNode& parent, qint64& start, qint64& end);
184 
185     static void removeUnallocated(PartitionNode* p);
186     void removeUnallocated();
187 
188     static qint64 defaultFirstUsable(const Device& d, TableType t);
189     static qint64 defaultLastUsable(const Device& d, TableType t);
190 
191     static PartitionTable::TableType nameToTableType(const QString& n);
192     static QString tableTypeToName(TableType l);
193     static qint32 maxPrimariesForTableType(TableType l);
194     static bool tableTypeSupportsExtended(TableType l);
195     static bool tableTypeIsReadOnly(TableType l);
196 
197 protected:
setMaxPrimaries(qint32 n)198     void setMaxPrimaries(qint32 n) {
199         m_MaxPrimaries = n;
200     }
201 
202 private:
203     Partitions m_Children;
204     qint32 m_MaxPrimaries;
205     TableType m_Type;
206     qint64 m_FirstUsable;
207     qint64 m_LastUsable;
208 };
209 
210 Q_DECLARE_OPERATORS_FOR_FLAGS(PartitionTable::Flags)
211 
212 QTextStream& operator<<(QTextStream& stream, const PartitionTable& ptable);
213 
214 #endif
215 
216