summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/FSKit/HeFS.h
blob: 8fdf933e4679745f4b144577ac6663d0df346734 (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
/* -------------------------------------------

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

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

#pragma once

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

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

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

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

#define kHeFSMinimumDiskSize (gib_cast(4))

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;

struct PACKED HeFS_BOOT_NODE final
{
	Kernel::Char	  fMagic[kHeFSMagicLen];
	Kernel::Utf16Char fVolName[kHeFSPartNameLen];
	Kernel::UInt32	  fVersion;
	Kernel::UInt64	  fBadSectors;
	Kernel::UInt64	  fSectorCount;
	Kernel::UInt64	  fSectorSize;
	Kernel::UInt32	  fChecksum;
	Kernel::UInt8	  fDriveKind;
	Kernel::UInt8	  fEncoding;
	Kernel::UInt64	  fStartIND;
	Kernel::UInt64	  fEndIND;
	Kernel::UInt64	  fINodeCount;
	Kernel::UInt64	  fDiskSize;
	Kernel::UInt16	  fDiskStatus;
	Kernel::UInt16	  fDiskFlags;
	Kernel::UInt16	  fVID; // virtual identification number within an EPM disk.
};

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

inline constexpr ATime kHeFSTimeInvalid = 0x0000000000000000;
inline constexpr 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 HeFS_INDEX_NODE final
{
	Kernel::Utf16Char fName[kHeFSFileNameLen];
	Kernel::UInt32	  fFlags;
	Kernel::UInt16	  fKind;
	Kernel::UInt32	  fSize;
	Kernel::UInt32	  fChecksum, fRecoverChecksum, fBlockChecksum, fLinkChecksum;

	ATime		   fCreated, fAccessed, fModified, fDeleted;
	Kernel::UInt32 fUID, fGID;
	Kernel::UInt32 fMode;

	Kernel::UInt64 fBlockLinkStart[kHeFSBlockCount];
	Kernel::UInt64 fBlockLinkEnd[kHeFSBlockCount];

	Kernel::UInt64 fBlockStart[kHeFSBlockCount];
	Kernel::UInt64 fBlockEnd[kHeFSBlockCount];

	Kernel::UInt64 fBlockRecoveryStart[kHeFSBlockCount];
	Kernel::UInt64 fBlockRecoveryEnd[kHeFSBlockCount];

	/// @brief Red-black tree pointers.
	Kernel::Lba fNext, fPrev, fChild, fParent;
};

/// @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 HeFS_INDEX_NODE_DIRECTORY final
{
	Kernel::Utf16Char fName[kHeFSFileNameLen];

	Kernel::UInt32 fFlags;
	Kernel::UInt16 fKind;
	Kernel::UInt32 fSize;
	Kernel::UInt32 fChecksum, fIndexNodeChecksum;

	ATime		   fCreated, fAccessed, fModified, fDeleted;
	Kernel::UInt32 fUID, fGID;
	Kernel::UInt32 fMode;

	Kernel::UInt64 fIndexNodeStart[kHeFSBlockCount];
	Kernel::UInt64 fIndexNodeEnd[kHeFSBlockCount];

	/// @brief Red-black tree pointers.
	Kernel::Lba fNext, fPrev, fChild, fParent;
};

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

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

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

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

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

	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;
} // namespace Kernel::Detail