Max OS 0.3
Loading...
Searching...
No Matches
fat32.cpp
Go to the documentation of this file.
1
10#include <memory/memoryIO.h>
11
12using namespace MaxOS;
13using namespace MaxOS::common;
14using namespace MaxOS::drivers;
15using namespace MaxOS::drivers::disk;
16using namespace MaxOS::filesystem;
17using namespace MaxOS::filesystem::format;
18using namespace MaxOS::memory;
19
26Fat32Volume::Fat32Volume(Disk* disk, uint32_t partition_offset)
27 : disk(disk) {
28
29 // Read the BIOS parameter block
30 buffer_t bpb_buffer(&bpb, sizeof(bpb32_t));
31 disk->read(partition_offset, &bpb_buffer);
32
33 // Parse the FAT info
35 bpb.total_sectors_32 - (bpb.reserved_sectors + (bpb.table_copies * bpb.table_size_32));
36 fat_total_clusters = total_data_sectors / bpb.sectors_per_cluster;
37 fat_lba = partition_offset + bpb.reserved_sectors;
38 fat_copies = bpb.table_copies;
39 fat_info_lba = partition_offset + bpb.fat_info;
40 data_lba = fat_lba + (bpb.table_copies * bpb.table_size_32);
41 root_lba = data_lba + bpb.sectors_per_cluster * (bpb.root_cluster - 2);
42
43 // Read the fs info
46
47 // Validate the fat information
48 if(fsinfo.lead_signature != 0x41615252 || fsinfo.structure_signature != 0x61417272 ||
49 fsinfo.trail_signature != 0xAA550000) {
50 Logger::ERROR() << "Invalid FAT32 filesystem information TODO: Handle this\n";
51 return;
52 }
53}
54
55Fat32Volume::~Fat32Volume() = default;
56
66
67 // Get the location in the FAT table
68 lba_t offset = cluster * sizeof(uint32_t);
69 lba_t sector = fat_lba + (offset / bpb.bytes_per_sector);
70 uint32_t entry_index = offset % bpb.bytes_per_sector;
71
72 // Read the FAT entry
73 buffer_t fat(bpb.bytes_per_sector);
74 disk->read(sector, &fat);
75
76 // Get the next cluster info (mask the upper 4 bits)
77 auto entry = (uint32_t*) (&(fat.raw()[entry_index]));
78 return *entry & 0x0FFFFFFF;
79}
80
91
92 // Get the location in the FAT table
93 lba_t offset = cluster * sizeof(uint32_t);
94
95 for(uint32_t i = 0; i < fat_copies; ++i) {
96
97 lba_t sector = (fat_lba + i * bpb.table_size_32) + (offset / bpb.bytes_per_sector);
98 uint32_t entry_index = offset % bpb.bytes_per_sector;
99
100 // Read the FAT entry
101 buffer_t fat(bpb.bytes_per_sector);
102 disk->read(sector, &fat);
103
104 // Set the next cluster info (mask the upper 4 bits)
105 auto entry = (uint32_t*) (&(fat.raw()[entry_index]));
106 *entry = next_cluster & 0x0FFFFFFF;
107 disk->write(sector, &fat);
108
109 }
110
111 return next_cluster;
112}
113
120
121 // Get the first free cluster
122 for(uint32_t start = fsinfo.next_free_cluster; start < fat_total_clusters + 1; start++)
123 if(next_cluster(start) == 0)
124 return start;
125
126 // Check any clusters before the first free cluster
127 for(uint32_t start = 2; start < fsinfo.next_free_cluster; start++)
128 if(next_cluster(start) == 0)
129 return start;
130
131 ASSERT(false, "No free clusters found in the FAT table");
132 return 0;
133}
134
142
143 // Allocate 1 cluster
144 return allocate_cluster(cluster, 1);
145}
146
155
156 // Make sure within bounds
158 return 0;
159
160 // Go through allocating the clusters
161 for(size_t i = 0; i < amount; i++) {
163
164 // Update the fsinfo
165 fsinfo.next_free_cluster = next_cluster + 1;
166 fsinfo.free_cluster_count -= 1;
167
168 // If there is an existing chain it needs to be updated
169 if(cluster != 0)
171
173 }
174
175 // Once all the updates are done flush the changes to the disk
178
179 // Finish the chain
180 set_next_cluster(cluster, (uint32_t) ClusterState::END_OF_CHAIN);
181 return cluster;
182}
183
190
191 // Free 1 cluster
193
194}
195
203
204 // Make sure within bounds
206 return;
207
208 // Go through freeing the clusters
209 for(size_t i = 0; i < amount; i++) {
210
211 // Find the next cluster before it is removed from the chain
213
214 // Update the fsinfo
215 fsinfo.next_free_cluster = cluster;
216 fsinfo.free_cluster_count += 1;
217
218 // Update the chain
219 set_next_cluster(cluster, (lba_t) ClusterState::FREE);
221 }
222
223 // Save the fsinfo
226
227 // Mark the end of the chain
228 set_next_cluster(cluster, (uint32_t) ClusterState::END_OF_CHAIN);
229}
230
240 : m_volume(volume),
241 m_parent_directory(parent),
242 m_entry(info),
243 m_first_cluster((info->first_cluster_high << 16) | info->first_cluster_low) {
244
245 m_name = name;
246 m_size = info->size;
247 m_offset = 0;
248}
249
250Fat32File::~Fat32File() = default;
251
260void Fat32File::write(buffer_t* data, size_t amount) {
261
262 size_t buffer_space = m_volume->bpb.bytes_per_sector * m_volume->bpb.sectors_per_cluster;
263 buffer_t buffer(buffer_space);
264 buffer.clear();
265
268 uint32_t last = m_first_cluster;
269
270 // Read the file
271 for(uint32_t cluster = last;
272 cluster != (uint32_t) ClusterState::END_OF_CHAIN; cluster = m_volume->next_cluster(cluster)) {
273 last = cluster;
274
275 // No cluster to read from (blank file)
276 if(cluster == 0)
277 break;
278
279 // Skip clusters before the offset
282 continue;
283 }
284
285 // Read each sector in the cluster (prevent overwriting the data)
286 lba_t lba = m_volume->data_lba + (cluster - 2) * m_volume->bpb.sectors_per_cluster;
287 for(size_t sector = 0; sector < m_volume->bpb.sectors_per_cluster; sector++)
288 m_volume->disk->read(lba + sector, &buffer, m_volume->bpb.bytes_per_sector);
289 buffer.set_offset(0);
290
291 // If the offset is in the middle of the cluster
292 size_t buffer_offset = 0;
295
296 // Calculate how many bytes are being copied (read from cluster at offset?
297 // or read part of cluster?)
303
304 // Update the data
308 buffer.set_offset(0);
309
310 // Write the data back to the disk
311 for(size_t sector = 0; sector < m_volume->bpb.sectors_per_cluster; sector++)
312 m_volume->disk->write(lba + sector, &buffer, m_volume->bpb.bytes_per_sector);
313 }
314
315 // Extend the file
316 while(bytes_written < amount) {
317 // Allocate a new cluster
319 if(new_cluster == 0)
320 break;
321
322 if(last == 0)
323 m_first_cluster = new_cluster;
324
325 // Update the data
327 buffer.copy_from(data, bytes_to_copy, 0, bytes_written);
330 buffer.set_offset(0);
331
332 // Write the data back to the disk
333 lba_t lba = m_volume->data_lba + (new_cluster - 2) * m_volume->bpb.sectors_per_cluster;
334 for(size_t sector = 0; sector < m_volume->bpb.sectors_per_cluster; sector++)
335 m_volume->disk->write(lba + sector, &buffer, m_volume->bpb.bytes_per_sector);
336
337 // Go to the next cluster
339 }
340
341 // Update file size
343 if(m_offset > m_size)
345
346 // Update entry info
347 m_entry->size = m_size;
348 m_entry->first_cluster_high = (m_first_cluster >> 16) & 0xFFFF;
349 m_entry->first_cluster_low = m_first_cluster & 0xFFFF;
350
351 m_parent_directory->save_entry_to_disk(m_entry);
352
353}
354
361void Fat32File::read(buffer_t* data, size_t amount) {
362 size_t buffer_space = m_volume->bpb.bytes_per_sector * m_volume->bpb.sectors_per_cluster;
363 buffer_t buffer(buffer_space);
364 buffer.clear();
365
368
369 // Read the file
370 for(uint32_t cluster = m_first_cluster;
371 cluster != (uint32_t) ClusterState::END_OF_CHAIN; cluster = m_volume->next_cluster(cluster)) {
372
373 // Skip clusters before the offset
376 continue;
377 }
378
379 // Read each sector in the cluster
380 lba_t lba = m_volume->data_lba + (cluster - 2) * m_volume->bpb.sectors_per_cluster;
381 for(size_t sector = 0; sector < m_volume->bpb.sectors_per_cluster; sector++)
382 m_volume->disk->read(lba + sector, &buffer, m_volume->bpb.bytes_per_sector);
383 buffer.set_offset(0);
384
385 // If the offset is in the middle of the cluster
386 size_t buffer_offset = 0;
389
390 // Calculate how many bytes are being copied (read from cluster at offset? or read part of cluster?)
396
397 // Read the data
401
402 // Dont read more than needed
403 if(bytes_read >= amount)
404 break;
405 }
406
408}
409
414 File::flush();
415}
416
425 : m_volume(volume),
426 m_first_cluster(cluster) {
427 m_name = name;
428}
429
430Fat32Directory::~Fat32Directory() = default;
431
439dir_entry_t* Fat32Directory::create_entry(const string& name, bool is_directory) {
440
441 // Allocate a cluster for the new entry
442 uint32_t cluster = m_volume->allocate_cluster(0);
443 if(cluster == 0)
444 return nullptr;
445
446 // Store the name
448 char short_name[8];
449 char short_extension[3];
450 for(size_t i = 0; i < 8; i++)
451 short_name[i] = (i < name.length()) ? name[i] : ' ';
452 for(size_t i = 0; i < 3; i++)
453 short_extension[i] = (8 + i < name.length()) ? name[8 + i] : ' ';
454
455 // Create the directory entry
456 dir_entry_t entry = { };
457 memcpy(entry.name, short_name, sizeof(short_name));
458 memcpy(entry.extension, short_extension, sizeof(short_extension));
459 entry.attributes = is_directory ? (uint8_t) DirectoryEntryAttributes::DIRECTORY
461 entry.first_cluster_high = (cluster >> 16) & 0xFFFF;
462 entry.first_cluster_low = cluster & 0xFFFF;
463
464 // Find free space for the new entry and the name
465 size_t entries_needed = 1 + lfn_entries.size();
466 int entry_index = find_free_entries(entries_needed);
467 if(entry_index == -1)
468 entry_index = expand_directory(entries_needed);
469
470 // Store the entries in the cache
471 for(size_t i = 0; i < entries_needed; i++)
472 m_entries[entry_index + i] = i == 0 ? entry : *(dir_entry_t*) &lfn_entries[i - 1];
473
474 // Write the long file name entries
475 for(size_t index = entry_index + lfn_entries.size() - 1; index >= entry_index; index--)
477
478 // Creating the file is done
479 if(!is_directory)
480 return &m_entries[entry_index];
481
482 // Create the "." in the directory
484 memcpy(current_dir_entry.name, ".", 1);
485 current_dir_entry.attributes = 0x10;
486 current_dir_entry.first_cluster_high = (cluster >> 16) & 0xFFFF;
487 current_dir_entry.first_cluster_low = cluster & 0xFFFF;
488
489 // Create the ".." in the directory
491 memcpy(parent_dir_entry.name, "..", 2);
492 parent_dir_entry.attributes = 0x10;
493 parent_dir_entry.first_cluster_high = (m_first_cluster >> 16) & 0xFFFF;
494 parent_dir_entry.first_cluster_low = m_first_cluster & 0xFFFF;
495
496 // Write the entries to the disk
497 uint32_t bytes_per_sector = m_volume->bpb.bytes_per_sector;
498 lba_t child_lba = m_volume->data_lba + (cluster - 2) * bytes_per_sector;
499 buffer_t buffer(bytes_per_sector);
500 buffer.clear();
501 buffer.copy_from(&current_dir_entry, sizeof(dir_entry_t));
502 buffer.copy_from(&parent_dir_entry, sizeof(dir_entry_t));
503 m_volume->disk->write(child_lba, &buffer);
504
505 // Directory created
506 return &m_entries[entry_index];
507}
508
514void Fat32Directory::remove_entry(uint32_t cluster) {
515
516 // Find the entry in the directory
517 int64_t entry = entry_index(cluster);
518 if(entry == -1)
519 return;
520
521 // Find any long file name entries that belong to this entry
523 while(delete_entry_index > 0 &&
524 m_entries[delete_entry_index - 1].attributes == (uint8_t) DirectoryEntryAttributes::LONG_NAME)
526
527 // Mark the entries as free
528 for(int64_t i = delete_entry_index; i < entry; i++)
529 m_entries[i].name[0] = (uint8_t) DirectoryEntryType::FREE;
530
531 // Update the entries on the disk
532 for(int64_t i = delete_entry_index; i <= entry; i++)
534
535 // Count the number of clusters in the chain
536 size_t cluster_count = 0;
537 for(uint32_t next_cluster = cluster;
538 next_cluster < (lba_t) ClusterState::BAD; next_cluster = m_volume->next_cluster(next_cluster))
540
541 // Free all the clusters in the chain
543}
544
548void Fat32Directory::read_all_entries() {
549 m_entries.clear();
550
551 size_t buffer_space = m_volume->bpb.bytes_per_sector * m_volume->bpb.sectors_per_cluster;
552 buffer_t buffer(buffer_space);
553 buffer.clear();
554
555 // Read the directory
556 for(uint32_t cluster = m_first_cluster;
557 cluster != (uint32_t) ClusterState::END_OF_CHAIN; cluster = m_volume->next_cluster(cluster)) {
558
559 // Cache info to prevent re-traversing the chain
560 m_last_cluster = cluster;
561 m_current_cluster_length++;
562
563 // Read each sector in the cluster
564 lba_t lba = m_volume->data_lba + (cluster - 2) * m_volume->bpb.sectors_per_cluster;
565 for(size_t sector = 0; sector < m_volume->bpb.sectors_per_cluster; sector++)
566 m_volume->disk->read(lba + sector, &buffer, m_volume->bpb.bytes_per_sector);
567
568 // Parse the directory entries (each entry is 32 bytes)
569 for(size_t entry_offset = 0; entry_offset < buffer_space; entry_offset += 32) {
570
571 // Store the entry
572 auto entry = (dir_entry_t*) &(buffer.raw()[entry_offset]);
573 m_entries.push_back(*entry);
574
575 // Check if the entry is the end of the directory
576 if(entry->name[0] == (uint8_t) DirectoryEntryType::LAST)
577 return;
578 }
579
580 }
581}
582
583
590
591 int index = 0;
592 for(auto& m_entry : m_entries) {
593 if(&m_entry == entry)
594 break;
595 index++;
596 }
597
599}
600
606
607 // Get the entry
608 auto entry = m_entries[index];
609
610 // Determine sector offset and in-sector byte offset
611 uint32_t bytes_per_sector = m_volume->bpb.bytes_per_sector;
612 uint32_t entry_offset = index * sizeof(dir_entry_t);
613 uint32_t sector_offset = entry_offset / bytes_per_sector;
614 uint32_t in_sector_offset = entry_offset % bytes_per_sector;
615
616 // Find which cluster has the entry
617 uint32_t cluster = m_first_cluster;
619 offset_remaining >= bytes_per_sector; offset_remaining -= bytes_per_sector)
620 cluster = m_volume->next_cluster(cluster);
621
622 // Read the full sector into a buffer
623 lba_t base_lba = m_volume->data_lba + (cluster - 2) * m_volume->bpb.sectors_per_cluster;
624 buffer_t sector_buffer(bytes_per_sector, false);
626
627 // Update the entry in the buffer
628 sector_buffer.copy_from(&entry, sizeof(dir_entry_t), in_sector_offset);
630}
631
638uint32_t Fat32Directory::entry_index(lba_t cluster) {
639
640 uint32_t entry_index = 0;
641 for(; entry_index < m_entries.size(); entry_index++) {
642 auto& entry = m_entries[entry_index];
643
644 // End of directory means no more entries
645 if(entry.name[0] == (uint8_t) DirectoryEntryType::LAST)
646 return -1;
647
648 // Skip free entries
649 if(entry.name[0] == (uint8_t) DirectoryEntryType::FREE)
650 continue;
651
652 // Check if the entry is the one
653 uint32_t start_cluster = (entry.first_cluster_high << 16) | entry.first_cluster_low;
655 break;
656 }
657
658 // Make sure the entry is valid
659 if(entry_index >= m_entries.size())
660 return -1;
661
662 return entry_index;
663
664}
665
673int64_t Fat32Directory::find_free_entries(size_t amount) {
674
675 for(uint32_t entry_index = 0; entry_index < m_entries.size(); entry_index++) {
676 // Check if there are enough free entries in a row
677 bool found = true;
678 for(size_t j = 0; j < amount; j++)
679 if(m_entries[entry_index + j].name[0] != (uint8_t) DirectoryEntryType::FREE)
680 found = false;
681
682 if(found)
683 return entry_index;
684 }
685
686 return -1;
687}
688
689
700int Fat32Directory::expand_directory(size_t amount) {
701
702 // Remove the old end of directory marker
703 int64_t free_start = m_entries.size() - 1;
704 ASSERT(m_entries[free_start].name[0] == (uint8_t) DirectoryEntryType::LAST, "Last entry is not marked");
705 m_entries[free_start].name[0] = (uint8_t) DirectoryEntryType::FREE;
706
707 // Count how many free entries there is before the end
708 for(int64_t i = free_start; i >= 0; --i) {
709 if(m_entries[i].name[0] == (uint8_t) DirectoryEntryType::FREE)
710 free_start = i;
711 else
712 break;
713 }
714
715 // Calculate how many entries are need to be created (ie was there enough free entries already)
716 uint32_t found = m_entries.size() - free_start;
721
722 // Find the length of the current cluster chain
725 (m_volume->bpb.bytes_per_sector * m_volume->bpb.sectors_per_cluster);
726
727 // Expand the cluster chain if needed
728 if(total_clusters > m_current_cluster_length) {
729 m_volume->allocate_cluster(m_last_cluster, total_clusters - m_current_cluster_length);
730 m_current_cluster_length = total_clusters;
731 }
732
733 // Expand the directory to fit the remaining entries
734 for(uint32_t i = 0; i < additional_entries; ++i) {
735 dir_entry_t free = { };
736 free.name[0] = (uint8_t) DirectoryEntryType::FREE;
737 m_entries.push_back(free);
738 }
739
740 // Write the updated end of entries
741 m_entries[m_entries.size() - 1].name[0] = (uint8_t) DirectoryEntryType::LAST;
742 update_entry_on_disk(m_entries.size() - 1);
743
744 return free_start;
745}
746
754Vector<long_file_name_entry_t> Fat32Directory::to_long_filenames(string name) {
755
756 size_t lfn_count = (name.length() + 12) / 13;
758
759 // Create the long file name entries (in reverse order)
760 for(size_t i = lfn_count; i-- > 0;) {
761
762 // Create the long file name entry
764 lfn_entry.order = i + 1;
765 lfn_entry.attributes = 0x0F;
766 lfn_entry.type = 0;
767 lfn_entry.checksum = 0;
768
769 // If it is the last entry, set the last bit
770 if(i == lfn_entries.size() - 1)
771 lfn_entry.order |= 0x40;
772
773 // Set the name
774 for(int j = 0; j < 13; j++) {
775
776 // Get the character info (0xFFFF if out of bounds)
777 size_t char_index = i * 13 + j;
778 char c = (char_index < name.length()) ? name[char_index] : 0xFFFF;
779
780 // Set the character in the entry
781 if(j < 5)
782 lfn_entry.name1[j] = c;
783 else if(j < 11)
784 lfn_entry.name2[j - 5] = c;
785 else
786 lfn_entry.name3[j - 11] = c;
787 }
788 lfn_entries.push_back(lfn_entry);
789 }
790
791 return lfn_entries;
792}
793
802string Fat32Directory::parse_long_filename(long_file_name_entry_t* entry, const string& current) {
803
804 // Extract the long name from each part (in reverse order)
805 string current_long_name = "";
806 for(int i = 0; i < 13; i++) {
807
808 // Get the character (in utf8 encoding)
809 char c;
810 if(i < 5)
811 c = entry->name1[i] & 0xFF;
812 else if(i < 11)
813 c = entry->name2[i - 5] & 0xFF;
814 else
815 c = entry->name3[i - 11] & 0xFF;
816
817 // Padding / invalid or end of string
818 if(c == (char) 0xFF || c == '\0')
819 break;
820
821 // Add to the start as the entries are stored in reverse
823 }
824
825 // Entry parsed (prepend name)
826 return current_long_name + current;
827}
828
830
831 for(auto& file : m_files)
832 delete file;
833 m_files.clear();
834
835 for(auto& directory : m_subdirectories)
836 delete directory;
837 m_subdirectories.clear();
838
839 // Load the entries from the disk into memory
840 read_all_entries();
841
842 // Parse the entries
843 string long_name = "";
844 for(auto& entry : m_entries) {
845
846 // Skip free entries and volume labels
847 if(entry.name[0] == (uint8_t) DirectoryEntryType::FREE
848 || entry.attributes == (uint8_t) DirectoryEntryAttributes::FREE
849 || entry.attributes == (uint8_t) DirectoryEntryAttributes::VOLUME_ID)
850 continue;
851
852 // Extract the long name
853 if(entry.attributes == (uint8_t) DirectoryEntryAttributes::LONG_NAME) {
854 long_name = parse_long_filename((long_file_name_entry_t*) &entry, long_name);
855 continue;
856 }
857
858 bool is_directory = entry.attributes == (uint8_t) DirectoryEntryAttributes::DIRECTORY;
859
860 // Get the name of the entry
861 string name = long_name;
862 if(long_name == "") {
863 name = string(entry.name, 8);
864
865 // Add the extension
866 if(!is_directory)
867 name = name.strip() + "." + string(entry.extension, 3);
868 }
869
870 long_name = "";
871
872 // Get the starting cluster
873 uint32_t start_cluster = (entry.first_cluster_high << 16) | entry.first_cluster_low;
874
875 // Store the file or directory
876 if(is_directory)
877 m_subdirectories.push_back(new Fat32Directory(m_volume, start_cluster, name.strip()));
878 else
879 m_files.push_back(new Fat32File(m_volume, this, &entry, name));
880
881 }
882}
883
890File* Fat32Directory::create_file(const string& name) {
891
892 // Check if the file already exists
893 for(auto& file : m_files)
894 if(file->name() == name)
895 return nullptr;
896
897 // Check if the name is too long
898 if(name.length() > MAX_NAME_LENGTH)
899 return nullptr;
900
901 // Create the file
902 auto file = new Fat32File(m_volume, this, create_entry(name, false), name);
903 m_files.push_back(file);
904 return file;
905}
906
912void Fat32Directory::remove_file(const string& name) {
913 // Find the file if it exists
914 for(auto& file : m_files)
915 if(file->name() == name) {
916
917 // Remove the file from the directory
918 m_files.erase(file);
919 remove_entry(((Fat32File*) file)->first_cluster());
920
921 // Delete the file reference
922 delete file;
923 return;
924 }
925}
926
934
935 // Check if the directory already exists
936 for(auto& subdirectory : m_subdirectories)
937 if(subdirectory->name() == name)
938 return nullptr;
939
940 // Check if the name is too long
941 if(name.length() > MAX_NAME_LENGTH)
942 return nullptr;
943
944 // Create the directory
945 auto entry = create_entry(name, true);
946 uint32_t cluster = ((entry->first_cluster_high << 16) | entry->first_cluster_low);
947
948 // Store the directory
949 auto directory = new Fat32Directory(m_volume, cluster, name);
950 m_subdirectories.push_back(directory);
951 return directory;
952}
953
959void Fat32Directory::remove_subdirectory(const string& name) {
960 // Find the directory if it exists
961 for(auto& subdirectory : m_subdirectories) {
962 if(subdirectory->name() != name)
963 continue;
964
965 // Remove all the files in the directory
966 for(auto& file : subdirectory->files())
967 subdirectory->remove_file(file->name());
968
969 // Remove all the subdirectories in the directory
970 for(auto& child_dir : subdirectory->subdirectories())
971 child_dir->remove_subdirectory(child_dir->name());
972
973 // Remove the entry
975 remove_entry(((Fat32Directory*) subdirectory)->first_cluster());
976
977 // Delete the directory
978 delete subdirectory;
979 return;
980 }
981}
982
990 : m_volume(disk, partition_offset) {
991
992 // Create the root directory
993 m_root_directory = new Fat32Directory(&m_volume, m_volume.bpb.root_cluster, "/");
995
996}
997
998Fat32FileSystem::~Fat32FileSystem() = default;
static Logger ERROR()
Gets active logger set to ERROR level.
Definition logger.cpp:216
Wrapper class for a region of bytes in memor in an attempt to add some memory safety....
Definition buffer.h:25
void set_offset(size_t offset)
Set the offset for where operations should begin from.
Definition buffer.cpp:128
void copy_from(const Buffer *buffer)
Copies all the bytes from another buffer into this buffer.
Definition buffer.cpp:195
void clear()
Fulls the buffer with 0's and resets the offset.
Definition buffer.cpp:65
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
uint32_t size() const
Returns the number of elements in the Vector.
Definition vector.h:273
void clear()
Removes all elements from the Vector.
Definition vector.h:461
iterator push_back(Type)
Adds an element to the end of the vector and returns the iterator of the element.
Definition vector.h:333
Generic Disk, handles the reading and writing of data to the hard drive.
Definition disk.h:24
void write(uint32_t sector, common::buffer_t *data)
write data to the disk from a buffer (max capacity 512 bytes)
Definition disk.cpp:50
void read(uint32_t sector, common::buffer_t *data_buffer)
read data from the disk into a buffer (max capacity 512 bytes)
Definition disk.cpp:26
Handles a group of files (directory)
Definition filesystem.h:57
common::Vector< Directory * > m_subdirectories
The subdirectories in this directory.
Definition filesystem.h:60
string m_name
The name of this directory.
Definition filesystem.h:62
common::Vector< File * > m_files
The files in this directory.
Definition filesystem.h:59
virtual void read_from_disk()
read the directory from the disk
string name()
Get the name of the directory.
Directory * m_root_directory
The fist directory in the file system (not be confused with the system root)
Definition filesystem.h:98
Handles file operations and information.
Definition filesystem.h:31
size_t m_size
The size of the file.
Definition filesystem.h:36
string m_name
The name of the file.
Definition filesystem.h:35
uint32_t m_offset
The current offset in the file.
Definition filesystem.h:34
string name()
Get the name of the file.
virtual void flush()
Flush the file to the disk.
Handles the directory operations on the FAT32 filesystem.
Definition fat32.h:235
void remove_file(const string &name) final
Delete a file from the subdirectory.
Definition fat32.cpp:912
Fat32Directory(Fat32Volume *volume, lba_t cluster, const string &name)
Construct a new Fat32 Directory object.
Definition fat32.cpp:424
File * create_file(const string &name) final
Create a new file in the directory.
Definition fat32.cpp:890
void update_entry_on_disk(size_t index)
Save the directory entry at the given index to the disk.
Definition fat32.cpp:605
Directory * create_subdirectory(const string &name) final
Create a new directory in the directory.
Definition fat32.cpp:933
void read_from_disk() final
read the directory from the disk
Definition fat32.cpp:829
void remove_subdirectory(const string &name) final
Remove a directory entry from the directory.
Definition fat32.cpp:959
void save_entry_to_disk(dir_entry_t *entry)
Writes an updated directory entry to the disk.
Definition fat32.cpp:589
lba_t first_cluster() const
Get the first cluster of the directory.
Definition fat32.h:279
Fat32FileSystem(drivers::disk::Disk *disk, uint32_t partition_offset)
Construct a new Fat32 File System object.
Definition fat32.cpp:989
Handles the file operations on the FAT32 filesystem.
Definition fat32.h:207
Fat32File(Fat32Volume *volume, Fat32Directory *parent, dir_entry_t *info, const string &name)
Construct a new Fat32 File object.
Definition fat32.cpp:239
void read(common::buffer_t *data, size_t amount) final
read data from the file (at the current seek position, updated to be += amount)
Definition fat32.cpp:361
void write(common::buffer_t *data, size_t amount) final
write data to the file (at the current seek position, updated to be += amount)
Definition fat32.cpp:260
void flush() final
Flush the file to the disk.
Definition fat32.cpp:413
Handles the FAT table that stores the information about the files on the disk and operations on the d...
Definition fat32.h:171
uint32_t next_cluster(uint32_t cluster) const
Take the cluster and gets the next cluster in the chain.
Definition fat32.cpp:65
uint32_t find_free_cluster() const
Searches the fat table for a free cluster starting from the first free cluster in the fsinfo,...
Definition fat32.cpp:119
uint32_t allocate_cluster(uint32_t cluster)
Allocate a cluster in the FAT table.
Definition fat32.cpp:141
fs_info_t fsinfo
The FSInfo structure for the FAT32 volume.
Definition fat32.h:177
void free_cluster(uint32_t cluster)
Free a cluster in the FAT table.
Definition fat32.cpp:189
Fat32Volume(drivers::disk::Disk *disk, lba_t partition_offset)
Construct a new Fat32 Volume object.
Definition fat32.cpp:26
lba_t fat_lba
The starting LBA of the FAT table.
Definition fat32.h:180
drivers::disk::Disk * disk
The disk that this volume is on.
Definition fat32.h:187
bpb32_t bpb
The BIOS Parameter Block for the FAT32 volume.
Definition fat32.h:176
lba_t fat_info_lba
The LBA of the FSInfo structure.
Definition fat32.h:181
lba_t root_lba
The starting LBA of the root directory.
Definition fat32.h:185
lba_t fat_copies
How many FAT tables are present.
Definition fat32.h:182
lba_t data_lba
The starting LBA of the data region.
Definition fat32.h:184
size_t fat_total_clusters
How many clusters are in the FAT table.
Definition fat32.h:179
uint32_t set_next_cluster(uint32_t cluster, uint32_t next_cluster) const
Sets the next cluster in the chain (where the base cluster should point)
Definition fat32.cpp:90
Defines structures and constants for the File Allocation Table 32 (FAT32) filesystem format and the r...
struct PACKED MaxOS::filesystem::format::BiosParameterBlock32 bpb32_t
Alias for BiosParameterBlock32 struct.
struct PACKED MaxOS::filesystem::format::LongFileNameEntry long_file_name_entry_t
Alias for LongFileNameEntry struct.
DirectoryEntryAttributes
Flags for a directory entry in a FAT32 System.
Definition fat32.h:115
struct PACKED MaxOS::filesystem::format::FSInfo fs_info_t
Alias for FSInfo struct.
constexpr uint16_t MAX_NAME_LENGTH
Highest number of characters in a file/directory name.
Definition fat32.h:165
struct PACKED MaxOS::filesystem::format::DirectoryEntry dir_entry_t
Alias for DirectoryEntry struct.
uint32_t lba_t
Logical Block Addressing type.
Definition filesystem.h:24
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.
Definition logger.h:100
Defines classes for memory input and output operations of various bit widths (8, 16,...
void * memcpy(void *destination, const void *source, uint64_t num)
Copies a block of memory from one location to another.
Definition memoryIO.cpp:165
class MaxOS::String string
Typedef for String.
Stores information about a file or directory.
Definition fat32.h:88