mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 12:51:13 +00:00
238 lines
6.8 KiB
C++
238 lines
6.8 KiB
C++
/*
|
|
* Copyright (c) 2018-2020 Atmosphère-NX
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms and conditions of the GNU General Public License,
|
|
* version 2, as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#pragma once
|
|
#include <vapours/prfile2/prfile2_common.hpp>
|
|
#include <vapours/prfile2/prfile2_cache.hpp>
|
|
#include <vapours/prfile2/prfile2_critical_section.hpp>
|
|
#include <vapours/prfile2/prfile2_drv.hpp>
|
|
#include <vapours/prfile2/prfile2_entry.hpp>
|
|
#include <vapours/prfile2/prfile2_fat.hpp>
|
|
|
|
namespace ams::prfile2 {
|
|
|
|
constexpr inline const auto MaxVolumes = 5;
|
|
|
|
struct Cursor {
|
|
u64 position;
|
|
u32 sector;
|
|
u32 file_sector_index;
|
|
u16 offset_in_sector;
|
|
};
|
|
|
|
struct DirectoryCursor {
|
|
u32 physical_entry_index;
|
|
u32 logical_entry_index;
|
|
u32 logical_seek_index;
|
|
};
|
|
|
|
struct File;
|
|
|
|
struct FileLock {
|
|
u16 mode;
|
|
u16 count;
|
|
u16 waiting_count;
|
|
File *owner;
|
|
u32 resource;
|
|
};
|
|
|
|
struct SystemFileDescriptor {
|
|
u32 status;
|
|
FatFileDescriptor ffd;
|
|
DirectoryEntry dir_entry;
|
|
FileLock lock;
|
|
u16 num_handlers;
|
|
SystemFileDescriptor *next_sfd;
|
|
};
|
|
|
|
struct SystemDirectoryDescriptor {
|
|
u32 status;
|
|
u16 num_handlers;
|
|
FatFileDescriptor ffd;
|
|
DirectoryEntry dir_entry;
|
|
/* ... */
|
|
u64 context_id;
|
|
/* ... */
|
|
};
|
|
|
|
struct File {
|
|
u32 status;
|
|
/* TODO OpenMode */ u32 open_mode;
|
|
SystemFileDescriptor *sfd;
|
|
FatHint hint;
|
|
LastAccess last_access;
|
|
pf::Error last_error;
|
|
Cursor cursor;
|
|
u16 lock_count;
|
|
};
|
|
|
|
struct Directory {
|
|
u32 stat;
|
|
SystemDirectoryDescriptor *sdd;
|
|
FatHint hint;
|
|
DirectoryCursor cursor;
|
|
/* ... */
|
|
};
|
|
|
|
struct BiosParameterBlock {
|
|
u16 bytes_per_sector;
|
|
u32 num_reserved_sectors;
|
|
u16 num_root_dir_entries;
|
|
u32 sectors_per_cluster;
|
|
u8 num_fats;
|
|
u32 total_sectors;
|
|
u32 sectors_per_fat;
|
|
u32 root_dir_cluster;
|
|
u16 fs_info_sector;
|
|
u16 backup_boot_sector;
|
|
u16 ext_flags;
|
|
u16 ext_flags_;
|
|
u8 media;
|
|
FatFormat fat_fmt;
|
|
u8 log2_bytes_per_sector;
|
|
u8 log2_sectors_per_cluster;
|
|
u8 num_active_fats;
|
|
u8 num_active_fats_;
|
|
u16 num_root_dir_sectors;
|
|
u32 active_fat_sector;
|
|
u32 active_fat_sector_;
|
|
u32 first_root_dir_sector;
|
|
u32 first_data_sector;
|
|
u32 num_clusters;
|
|
/* ... */
|
|
};
|
|
|
|
using VolumeCallback = void (*)();
|
|
|
|
struct VolumeContext {
|
|
u64 context_id;
|
|
u32 volume_id;
|
|
DirectoryEntry dir_entries[MaxVolumes];
|
|
pf::Error last_error;
|
|
pf::Error last_driver_error[MaxVolumes];
|
|
pf::Error last_unk_error[MaxVolumes];
|
|
/* ... */
|
|
VolumeContext *next_used_context;
|
|
union {
|
|
VolumeContext *prev_used_context;
|
|
VolumeContext *next_free_context;
|
|
};
|
|
};
|
|
|
|
namespace pdm {
|
|
|
|
struct Partition;
|
|
|
|
}
|
|
|
|
struct Volume {
|
|
BiosParameterBlock bpb;
|
|
u32 num_free_clusters;
|
|
u32 num_free_clusters_;
|
|
u32 last_free_cluster;
|
|
u32 last_free_cluster_;
|
|
SystemFileDescriptor sfds[MaximumOpenFileCountSystem];
|
|
File ufds[MaximumOpenFileCountUser];
|
|
SystemDirectoryDescriptor sdds[MaximumOpenDirectoryCountSystem];
|
|
Directory udds[MaximumOpenDirectoryCountUser];
|
|
u32 num_open_files;
|
|
u32 num_open_directories;
|
|
/* ... */
|
|
SectorCache cache;
|
|
VolumeContext *context;
|
|
u64 context_id;
|
|
DirectoryTail tail_entry;
|
|
u32 volume_config;
|
|
u32 file_config;
|
|
u32 flags;
|
|
pf::DriveCharacter drive_char;
|
|
CriticalSection critical_section;
|
|
u16 fsi_flag;
|
|
ClusterLinkForVolume cluster_link;
|
|
pf::Error last_error;
|
|
pf::Error last_driver_error;
|
|
/* ... */
|
|
HandleType partition_handle;
|
|
VolumeCallback callback;
|
|
const u8 *format_param;
|
|
/* ... */
|
|
/* TODO: ExtensionTable extension_table; */
|
|
/* TODO: ExtensionData ext; */
|
|
/* ... */
|
|
|
|
template<size_t Ix>
|
|
constexpr ALWAYS_INLINE bool GetFlagsBit() const {
|
|
constexpr u32 Mask = (1u << Ix);
|
|
return (this->flags & Mask) != 0;
|
|
}
|
|
|
|
template<size_t Ix>
|
|
constexpr ALWAYS_INLINE void SetFlagsBit(bool en) {
|
|
constexpr u32 Mask = (1u << Ix);
|
|
if (en) {
|
|
this->flags |= Mask;
|
|
} else {
|
|
this->flags &= ~Mask;
|
|
}
|
|
}
|
|
|
|
constexpr bool IsAttached() const { return this->GetFlagsBit<0>(); }
|
|
constexpr void SetAttached(bool en) { this->SetFlagsBit<0>(en); }
|
|
|
|
constexpr bool IsMounted() const { return this->GetFlagsBit<1>(); }
|
|
constexpr void SetMounted(bool en) { this->SetFlagsBit<1>(en); }
|
|
|
|
constexpr bool IsFormatAfterMountRequested() const { return this->GetFlagsBit<4>(); }
|
|
constexpr void SetFormatAfterMountRequested(bool en) { this->SetFlagsBit<4>(en); }
|
|
|
|
constexpr bool IsNoFormattingByFatFsLayer() const { return this->GetFlagsBit<5>(); }
|
|
constexpr void SetNoFormattingByFatFsLayer(bool en) { this->SetFlagsBit<5>(en); }
|
|
|
|
constexpr bool IsDataEraseRequested() const { return this->GetFlagsBit<6>(); }
|
|
constexpr void SetDataEraseRequested(bool en) { this->SetFlagsBit<6>(en); }
|
|
|
|
constexpr bool IsFlag12() const { return this->GetFlagsBit<12>(); }
|
|
constexpr void SetFlag12(bool en) { this->SetFlagsBit<12>(en); }
|
|
};
|
|
|
|
struct VolumeSet {
|
|
bool initialized;
|
|
u32 num_attached_drives;
|
|
u32 num_mounted_volumes;
|
|
u32 config;
|
|
void *param;
|
|
/* TODO: CodeSet codeset; */
|
|
u32 setting;
|
|
CriticalSection critical_section;
|
|
VolumeContext default_context;
|
|
VolumeContext contexts[MaxVolumes];
|
|
VolumeContext *used_context_head;
|
|
VolumeContext *used_context_tail;
|
|
VolumeContext *free_context_head;
|
|
Volume volumes[MaxVolumes];
|
|
};
|
|
|
|
}
|
|
|
|
namespace ams::prfile2::vol {
|
|
|
|
pf::Error Initialize(u32 config, void *param);
|
|
|
|
pf::Error Attach(pf::DriveTable *drive_table);
|
|
|
|
VolumeContext *RegisterContext(u64 *out_context_id);
|
|
pf::Error UnregisterContext();
|
|
|
|
}
|