summaryrefslogtreecommitdiffhomepage
path: root/Kernel/FSKit/NewFS.hxx
blob: e2ae81a66add048df5c6e84a120f10fd0ea8dd5d (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
/* -------------------------------------------

	Copyright SoftwareLabs

	File: NewFS.hxx
	Purpose:

	Revision History:

	?/?/?: Added file (amlel)
	12/02/24: Add UUID macro for EPM and GPT partition schemes.
	3/16/24: Add mandatory sector size, kNewFSSectorSz is set to 2048 by
default.

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

#pragma once

#include <CompilerKit/CompilerKit.hxx>
#include <HintKit/CompilerHint.hxx>
#include <KernelKit/DriveManager.hxx>
#include <NewKit/Defines.hpp>

/**
	@brief New File System specification.
	@author Amlal EL Mahrouss
*/

#define kNewFSInvalidFork	 (-1)
#define kNewFSInvalidCatalog (-1)
#define kNewFSNodeNameLen	 (256)

#define kNewFSSectorSz (512)

#define kNewFSIdentLen (8)
#define kNewFSIdent	   " NewFS"
#define kNewFSPadLen   (400)

/// @brief Partition GUID on EPM and GPT disks.
#define kNewFSUUID "@{DD997393-9CCE-4288-A8D5-C0FDE3908DBE}"

#define kNewFSVersionInteger (0x125)
#define kNewFSVerionString	 "1.25"

/// @brief Standard fork types.
#define kNewFSDataFork	   "data"
#define kNewFSResourceFork "rsrc"

#define kNewFSCatalogKindFile  (1)
#define kNewFSCatalogKindDir   (2)
#define kNewFSCatalogKindAlias (3)

#define kNewFSForkSize (8192)

//! shared between network or
//! other filesystems. Export forks as .zip when copying.
#define kNewFSCatalogKindShared (4)

#define kNewFSCatalogKindResource	(5)
#define kNewFSCatalogKindExecutable (6)

#define kNewFSCatalogKindPage (8)

#define kNewFSPartitionTypeStandard (7)
#define kNewFSPartitionTypePage		(8)
#define kNewFSPartitionTypeBoot		(9)

#define kNewFSCatalogKindDevice (9)
#define kNewFSCatalogKindLock	(10)

#define kNewFSSeparator '/'

#define kNewFSUpDir ".."
#define kNewFSRoot	"/"

#define kNewFSLF  '\r'
#define kNewFSEOF (-1)

#define kNewFSBitWidth (sizeof(NewCharType))
#define kNewFSLbaType  (NewOS::Lba)

/// Start After the PM headers, pad 1024 bytes.
#define kNewFSAddressAsLba		  (512)
#define kNewFSCatalogStartAddress (1024 + sizeof(NewPartitionBlock) + sizeof(NewCatalog))

#define kResourceTypeDialog (10)
#define kResourceTypeString (11)
#define kResourceTypeMenu	(12)

#define kConfigLen (64)
#define kPartLen   (32)

#define kNewFSFlagDeleted	  (70)
#define kNewFSFlagUnallocated (0)
#define kNewFSFlagCreated	  (71)

#define kNewFSMimeNameLen (200)

#define kNewFSForkNameLen (200U)

typedef NewOS::Char NewCharType;

enum
{
	kNewFSHardDrive			= 0xC0, // Hard Drive (SSD, HDD)
	kNewFSOpticalDrive		= 0x0C, // Blu-Ray/DVD
	kNewFSMassStorageDevice = 0xCC, // USB
	kNewFSScsi				= 0xC4, // SCSI Hard Drive
	kNewFSUnknown			= 0xFF, // Unknown device. (floppy)
	kNewFSDriveCount		= 5,
};

/// @brief Catalog type.
struct PACKED NewCatalog final
{
	NewCharType Name[kNewFSNodeNameLen];
	NewCharType Mime[kNewFSMimeNameLen];

	/// Catalog status flag.
	NewOS::UInt16 Flags;
	/// Custom catalog flags.
	NewOS::UInt16 FileFlags;
	/// Catalog kind.
	NewOS::Int32 Kind;

	/// Size of the data fork.
	NewOS::Lba DataForkSize;

	/// Size of all resource forks.
	NewOS::Lba ResourceForkSize;

	NewOS::Lba DataFork;
	NewOS::Lba ResourceFork;

	NewOS::Lba NextSibling;
	NewOS::Lba PrevSibling;
};

/// @brief Fork type, contains a data page.
/// @note The way we store is way different than how other filesystems do, specific chunk of code are
/// written into either the data fork or resource fork, the resource fork is reserved for file metadata.
/// whereas the data fork is reserved for file data.
struct PACKED NewFork final
{
	NewCharType ForkName[kNewFSForkNameLen];
	NewOS::Char CatalogName[kNewFSNodeNameLen];

	NewOS::Int32 Flags;
	NewOS::Int32 Kind;

	NewOS::Int64 ResourceId;
	NewOS::Int32 ResourceKind;
	NewOS::Int32 ResourceFlags;

	NewOS::Lba	 DataOffset; // 8 Where to look for this data?
	NewOS::SizeT DataSize;	 /// Data size according using sector count.

	NewOS::Lba NextSibling;
	NewOS::Lba PreviousSibling;
};

/// @brief Partition block type
struct PACKED NewPartitionBlock final
{
	NewCharType Ident[kNewFSIdentLen];
	NewCharType PartitionName[kPartLen];

	NewOS::Int32 Flags;
	NewOS::Int32 Kind;

	NewOS::Lba	 StartCatalog;
	NewOS::SizeT CatalogCount;

	NewOS::SizeT DiskSize;

	NewOS::SizeT FreeCatalog;
	NewOS::SizeT FreeSectors;

	NewOS::SizeT SectorCount;
	NewOS::SizeT SectorSize;

	NewOS::UInt64 Version;

	NewOS::Char Pad[kNewFSPadLen];
};

namespace NewOS
{

	enum
	{
		kNewFSSubDriveA,
		kNewFSSubDriveB,
		kNewFSSubDriveC,
		kNewFSSubDriveD,
		kNewFSSubDriveInvalid,
		kNewFSSubDriveCount,
	};

	/// \brief Resource fork kind.
	enum
	{
		kNewFSRsrcForkKind = 0,
		kNewFSDataForkKind = 1
	};

	///
	/// \name NewFSParser
	/// \brief NewFS parser class. (catalog creation, remove removal, root,
	/// forks...) Designed like the DOM, detects the filesystem automatically.
	///
	class NewFSParser final
	{
	public:
		explicit NewFSParser() = default;
		~NewFSParser()		   = default;

	public:
		NEWOS_COPY_DEFAULT(NewFSParser);

	public:
		/// @brief Creates a new fork inside the New filesystem partition.
		/// @param catalog it's catalog
		/// @param theFork the fork itself.
		/// @return the fork
		_Output NewFork* CreateFork(_Input NewCatalog* catalog,
									_Input NewFork&	   theFork);

		/// @brief Find fork inside New filesystem.
		/// @param catalog the catalog.
		/// @param name the fork name.
		/// @return the fork.
		_Output NewFork* FindFork(_Input NewCatalog* catalog,
								  _Input const Char* name,
								  Boolean			 dataOrRsrc);

		_Output Void RemoveFork(_Input NewFork* fork);

		_Output Void CloseFork(_Input NewFork* fork);

		_Output NewCatalog* FindCatalog(_Input const char* catalogName, Lba& outLba);

		_Output NewCatalog* GetCatalog(_Input const char* name);

		_Output NewCatalog* CreateCatalog(_Input const char*  name,
										  _Input const Int32& flags,
										  _Input const Int32& kind);

		_Output NewCatalog* CreateCatalog(_Input const char* name);

		bool WriteCatalog(_Input _Output NewCatalog* catalog,
						  voidPtr					 data,
						  SizeT						 sizeOfData,
						  _Input const char*		 forkName);

		VoidPtr ReadCatalog(_Input _Output NewCatalog* catalog,
							SizeT					   dataSz,
							_Input const char*		   forkName);

		bool Seek(_Input _Output NewCatalog* catalog, SizeT off);

		SizeT Tell(_Input _Output NewCatalog* catalog);

		bool RemoveCatalog(_Input const Char* catalog);

		bool CloseCatalog(_InOut NewCatalog* catalog);

		/// @brief Make a EPM+NewFS drive out of the disk.
		/// @param drive The drive to write on.
		/// @return If it was sucessful, see DbgLastError().
		bool Format(_Input _Output DriveTrait* drive);

	public:
		Int32 fDriveIndex{kNewFSSubDriveA};
	};

	///
	/// \name NewFilesystemHelper
	/// \brief Filesystem helper and utils.
	///

	class NewFilesystemHelper final
	{
	public:
		static const char* Root();
		static const char* UpDir();
		static const char  Separator();
	};

	namespace Detail
	{
		Boolean fs_init_newfs(Void) noexcept;
	} // namespace Detail
} // namespace NewOS

/// @brief Write to newfs disk.
/// @param Mnt mounted interface.
/// @param DrvTrait drive info
/// @param DrvIndex drive index.
/// @return
NewOS::Int32 fs_newfs_write(NewOS::MountpointInterface* Mnt,
							NewOS::DriveTrait&			DrvTrait,
							NewOS::Int32				DrvIndex);

/// @brief Read from newfs disk.
/// @param Mnt mounted interface.
/// @param DrvTrait drive info
/// @param DrvIndex drive index.
/// @return
NewOS::Int32 fs_newfs_read(NewOS::MountpointInterface* Mnt,
						   NewOS::DriveTrait&		   DrvTrait,
						   NewOS::Int32				   DrvIndex);