summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/FSKit/HeFS.h
blob: 63725f04b394fcf61b651355734da7f962c1ac4f (plain)
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
/* -------------------------------------------

  Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.

------------------------------------------- */

#pragma once

#include <CompilerKit/CompilerKit.h>
#include <KernelKit/DriveMgr.h>
#include <KernelKit/User.h>
#include <NewKit/Crc32.h>
#include <NewKit/Defines.h>
#include <NewKit/KString.h>
#include <hint/CompilerHint.h>

/// @file HeFS.h
/// @brief HeFS filesystem support.

#define kHeFSVersion (0x0101)
#define kHeFSMagic "  HeFS"
#define kHeFSMagicLen (8)

#define kHeFSFileNameLen (256U)
#define kHeFSPartNameLen (128U)

#define kHeFSMinimumDiskSize (gib_cast(4))

#define kHeFSDefaultVoluneName u"HeFS Volume"

#define kHeFSSearchAllStr u"*"

struct HEFS_BOOT_NODE;
struct HEFS_INDEX_NODE;
struct HEFS_INDEX_NODE_DIRECTORY;

enum {
  kHeFSHardDrive         = 0xC0,  // Hard Drive
  kHeFSSolidStateDrive   = 0xC1,  // Solid State Drive
  kHeFSOpticalDrive      = 0x0C,  // Blu-Ray/DVD
  kHeFSMassStorageDevice = 0xCC,  // USB
  kHeFSScsiDrive         = 0xC4,  // SCSI Hard Drive
  kHeFSFlashDrive        = 0xC6,
  kHeFSUnknown           = 0xFF,  // Unknown device.
  kHeFSDriveCount        = 7,
};

enum {
  kHeFSStatusUnlocked = 0x18,
  kHeFSStatusLocked,
  kHeFSStatusError,
  kHeFSStatusInvalid,
  kHeFSStatusCount,
};

enum {
  kHeFSEncodingUTF8 = 0x00,
  kHeFSEncodingUTF16,
  kHeFSEncodingUTF32,
  kHeFSEncodingUTF16BE,
  kHeFSEncodingUTF16LE,
  kHeFSEncodingUTF32BE,
  kHeFSEncodingUTF32LE,
  kHeFSEncodingUTF8BE,
  kHeFSEncodingUTF8LE,
  kHeFSEncodingCount,
};

inline constexpr UInt16 kHeFSFileKindRegular      = 0x00;
inline constexpr UInt16 kHeFSFileKindDirectory    = 0x01;
inline constexpr UInt16 kHeFSFileKindBlock        = 0x02;
inline constexpr UInt16 kHeFSFileKindCharacter    = 0x03;
inline constexpr UInt16 kHeFSFileKindFIFO         = 0x04;
inline constexpr UInt16 kHeFSFileKindSocket       = 0x05;
inline constexpr UInt16 kHeFSFileKindSymbolicLink = 0x06;
inline constexpr UInt16 kHeFSFileKindUnknown      = 0x07;
inline constexpr UInt16 kHeFSFileKindCount        = 0x08;

/// @brief HeFS blocks are array containing sparse blocks of data.
/// @details The blocks are used to store the data of a file. Each block is a pointer to a block of
/// data on the disk.
inline constexpr UInt16 kHeFSBlockCount = 0x10;

inline constexpr UInt16 kHeFSInvalidVID = 0xFFFF;

namespace Kernel {
/// @brief Access time type.
/// @details Used to keep track of the INode, INodeDir allocation status.
typedef UInt64 ATime;
}  // namespace Kernel

/// @brief HeFS Boot node.
/// @details Acts like a superblock, it contains the information about the filesystem.
/// @note The boot node is the first block of the filesystem.
struct PACKED HEFS_BOOT_NODE final {
  Kernel::Char      fMagic[kHeFSMagicLen];       /// @brief Magic number of the filesystem.
  Kernel::Utf16Char fVolName[kHeFSPartNameLen];  /// @brief Volume name.
  Kernel::UInt32    fVersion;                    /// @brief Version of the filesystem.
  Kernel::UInt64    fBadSectors;                 /// @brief Number of bad sectors in the filesystem.
  Kernel::UInt64    fSectorCount;                /// @brief Number of sectors in the filesystem.
  Kernel::UInt64    fSectorSize;                 /// @brief Size of the sector.
  Kernel::UInt32    fChecksum;                   /// @brief Checksum of the boot node.
  Kernel::UInt8 fDiskKind;   /// @brief Kind of the drive. (Hard Drive, Solid State Drive, Optical
                             /// Drive, etc).
  Kernel::UInt8  fEncoding;  /// @brief Encoding of the filesystem. (UTF-8, UTF-16, etc).
  Kernel::UInt64 fStartIND;  /// @brief Start of the INode tree.
  Kernel::UInt64 fEndIND;    /// @brief End of the INode tree.
  Kernel::UInt64 fINDCount;  /// @brief Number of leafs in the INode tree.
  Kernel::UInt64 fDiskSize;  /// @brief Size of the disk. (Could be a virtual size, that is not the
                             /// real size of the disk.)
  Kernel::UInt16 fDiskStatus;  /// @brief Status of the disk. (locked, unlocked, error, invalid).
  Kernel::UInt16 fDiskFlags;   /// @brief Flags of the disk. (read-only, read-write, etc).
  Kernel::UInt16
      fVID;  /// @brief Virtual Identification Number within an EPM disk. (0xFFFF if not used).
  Kernel::UInt64 fReserved;   /// @brief Reserved for future use.
  Kernel::UInt64 fReserved2;  /// @brief Reserved for future use.
  Kernel::UInt64 fReserved3;  /// @brief Reserved for future use.
  Kernel::UInt64 fReserved4;  /// @brief Reserved for future use.
};

inline constexpr Kernel::ATime kHeFSTimeInvalid = 0x0000000000000000;
inline constexpr Kernel::ATime kHeFSTimeMax     = 0xFFFFFFFFFFFFFFFF;

/// @brief HeFS index node.
/// @details This structure is used to store the file information of a file.
/// @note The index node is a special type of INode that contains the file information.
/// @note The index node is used to store the file information of a file.
struct PACKED ALIGN(8) HEFS_INDEX_NODE final {
  Kernel::Utf16Char fName[kHeFSFileNameLen];  /// @brief File name.
  Kernel::UInt32    fFlags;                   /// @brief File flags.
  Kernel::UInt16 fKind;  /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
                         /// Symbolic Link, Unknown).
  Kernel::UInt32 fSize;  /// @brief File size.
  Kernel::UInt32 fChecksum, fRecoverChecksum, fBlockChecksum,
      fLinkChecksum;  /// @brief Checksum of the file, recovery checksum, block checksum, link
                      /// checksum.

  Kernel::ATime  fCreated, fAccessed, fModified, fDeleted;  /// @brief File timestamps.
  Kernel::UInt32 fUID, fGID;  /// @brief User ID and Group ID of the file.
  Kernel::UInt32 fMode;       /// @brief File mode. (read, write, execute, etc).

  Kernel::UInt64 fBlockLinkStart[kHeFSBlockCount];  /// @brief Start of the block link.
  Kernel::UInt64 fBlockLinkEnd[kHeFSBlockCount];    /// @brief End of the block link.

  Kernel::UInt64 fBlockStart[kHeFSBlockCount];  /// @brief Start of the block.
  Kernel::UInt64 fBlockEnd[kHeFSBlockCount];    /// @brief End of the block.

  Kernel::UInt64 fBlockRecoveryStart[kHeFSBlockCount];  /// @brief Start of the block recovery.
  Kernel::UInt64 fBlockRecoveryEnd[kHeFSBlockCount];    /// @brief End of the block recovery.
};

enum {
  kHeFSRed = 100,
  kHeFSBlack,
  kHeFSColorCount,
};

/// @brief HeFS directory node.
/// @details This structure is used to store the directory information of a file.
/// @note The directory node is a special type of INode that contains the directory entries.
struct PACKED ALIGN(8) HEFS_INDEX_NODE_DIRECTORY final {
  Kernel::Utf16Char fName[kHeFSFileNameLen];  /// @brief Directory name.

  Kernel::UInt32 fFlags;  /// @brief File flags.
  Kernel::UInt16 fKind;   /// @brief File kind. (Regular, Directory, Block, Character, FIFO, Socket,
                          /// Symbolic Link, Unknown).
  Kernel::UInt32 fEntryCount;  /// @brief Entry Count of this directory inode.
  Kernel::UInt32 fChecksum,
      fIndexNodeChecksum;  /// @brief Checksum of the file, index node checksum.

  Kernel::ATime  fCreated, fAccessed, fModified, fDeleted;  /// @brief File timestamps.
  Kernel::UInt32 fUID, fGID;  /// @brief User ID and Group ID of the file.
  Kernel::UInt32 fMode;       /// @brief File mode. (read, write, execute, etc).

  /// @note These slices are organized as:
  /// [0] = OFFSET
  /// [1] = SIZE
  /// @note Thus the += 2 when iterating over them.
  Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount];  /// @brief Start of the index node.
  Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount];    /// @brief End of the index node.

  Kernel::UInt8 fColor;                         /// @brief Color of the node. (Red or Black).
  Kernel::Lba   fNext, fPrev, fChild, fParent;  /// @brief Red-black tree pointers.
};

namespace Kernel::Detail {
/// @brief HeFS get year from Kernel::ATime.
/// @param raw_atime the raw Kernel::ATime value.
/// @return the year value.
/// @note The year is stored in the upper 32 bits of the Kernel::ATime value.
inline UInt32 hefs_year_get(Kernel::ATime raw_atime) noexcept {
  return (raw_atime) >> 32;
}

/// @brief HeFS get month from Kernel::ATime.
/// @param raw_atime the raw Kernel::ATime value.
/// @return the month value.
/// @note The month is stored in the upper 24 bits of the Kernel::ATime value.
inline UInt32 hefs_month_get(Kernel::ATime raw_atime) noexcept {
  return (raw_atime) >> 24;
}

/// @brief HeFS get day from Kernel::ATime.
/// @param raw_atime the raw Kernel::ATime value.
/// @return the day value.
/// @note The day is stored in the upper 16 bits of the Kernel::ATime value.
inline UInt32 hefs_day_get(Kernel::ATime raw_atime) noexcept {
  return (raw_atime) >> 16;
}

/// @brief HeFS get hour from Kernel::ATime.
/// @param raw_atime the raw Kernel::ATime value.
/// @return the hour value.
/// @note The hour is stored in the upper 8 bits of the Kernel::ATime value.
inline UInt32 hefs_hour_get(Kernel::ATime raw_atime) noexcept {
  return (raw_atime) >> 8;
}

/// @brief HeFS get minute from Kernel::ATime.
/// @param raw_atime the raw Kernel::ATime value.
/// @return the minute value.
/// @note The minute is stored in the lower 8 bits of the Kernel::ATime value.
inline UInt32 hefs_minute_get(Kernel::ATime raw_atime) noexcept {
  return (raw_atime) & 0xFF;
}

inline constexpr UInt32 kHeFSBaseYear   = 1970;
inline constexpr UInt32 kHeFSBaseMonth  = 1;
inline constexpr UInt32 kHeFSBaseDay    = 1;
inline constexpr UInt32 kHeFSBaseHour   = 0;
inline constexpr UInt32 kHeFSBaseMinute = 0;

inline const Char* hefs_status_to_string(UInt16 status) noexcept {
  switch (status) {
    case kHeFSStatusUnlocked:
      return "Unlocked";
    case kHeFSStatusLocked:
      return "Locked";
    case kHeFSStatusError:
      return "Error";
    case kHeFSStatusInvalid:
      return "Invalid";
    default:
      return "Unknown";
  }
}

inline const Char* hefs_drive_kind_to_string(UInt8 kind) noexcept {
  switch (kind) {
    case kHeFSHardDrive:
      return "Hard Drive";
    case kHeFSSolidStateDrive:
      return "Solid State Drive";
    case kHeFSOpticalDrive:
      return "Optical Drive";
    case kHeFSMassStorageDevice:
      return "Mass Storage Device";
    case kHeFSScsiDrive:
      return "SCSI/SAS Drive";
    case kHeFSFlashDrive:
      return "Flash Drive";
    case kHeFSUnknown:
    default:
      return "Unknown";
  }
}

inline const Char* hefs_encoding_to_string(UInt8 encoding) noexcept {
  switch (encoding) {
    case kHeFSEncodingUTF8:
      return "UTF-8";
    case kHeFSEncodingUTF16:
      return "UTF-16";
    case kHeFSEncodingUTF32:
      return "UTF-32";
    case kHeFSEncodingUTF16BE:
      return "UTF-16BE";
    case kHeFSEncodingUTF16LE:
      return "UTF-16LE";
    case kHeFSEncodingUTF32BE:
      return "UTF-32BE";
    case kHeFSEncodingUTF32LE:
      return "UTF-32LE";
    case kHeFSEncodingUTF8BE:
      return "UTF-8BE";
    case kHeFSEncodingUTF8LE:
      return "UTF-8LE";
    default:
      return "Unknown";
  }
}

inline const Char* hefs_file_kind_to_string(UInt16 kind) noexcept {
  switch (kind) {
    case kHeFSFileKindRegular:
      return "Regular File";
    case kHeFSFileKindDirectory:
      return "Directory";
    case kHeFSFileKindBlock:
      return "Block Device";
    case kHeFSFileKindCharacter:
      return "Character Device";
    case kHeFSFileKindFIFO:
      return "FIFO";
    case kHeFSFileKindSocket:
      return "Socket";
    case kHeFSFileKindSymbolicLink:
      return "Symbolic Link";
    case kHeFSFileKindUnknown:
    default:
      return "Unknown";
  }
}

inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept {
  switch (flags) {
    case 0x00:
      return "No Flags";
    case 0x01:
      return "Read Only";
    case 0x02:
      return "Hidden";
    case 0x04:
      return "System";
    case 0x08:
      return "Archive";
    case 0x10:
      return "Device";
    default:
      return "Unknown";
  }
}
}  // namespace Kernel::Detail

namespace Kernel::HeFS {
/// @brief HeFS filesystem parser class.
/// @details This class is used to parse the HeFS filesystem.
class HeFileSystemParser final {
 public:
  HeFileSystemParser()  = default;
  ~HeFileSystemParser() = default;

 public:
  HeFileSystemParser(const HeFileSystemParser&)            = delete;
  HeFileSystemParser& operator=(const HeFileSystemParser&) = delete;

  HeFileSystemParser(HeFileSystemParser&&)            = delete;
  HeFileSystemParser& operator=(HeFileSystemParser&&) = delete;

 public:
  /// @brief Make a EPM+HeFS drive out of the disk.
  /// @param drive The drive to write on.
  /// @return If it was sucessful, see err_local_get().
  _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Int32 flags,
                      const Utf16Char* part_name);

 public:
  UInt32 mDriveIndex{MountpointInterface::kDriveIndexA};  /// @brief The drive index which this
                                                          /// filesystem is mounted on.
};

Boolean fs_init_hefs(Void) noexcept;
}  // namespace Kernel::HeFS