mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-10 14:11:43 +00:00
fs.mitm: Implement FileStorage
This commit is contained in:
parent
8c3dae846e
commit
348345340d
2 changed files with 166 additions and 0 deletions
112
stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp
Normal file
112
stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.cpp
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#include "../utils.hpp"
|
||||||
|
#include "fs_file_storage.hpp"
|
||||||
|
|
||||||
|
Result FileStorage::UpdateSize() {
|
||||||
|
if (this->size == InvalidSize) {
|
||||||
|
return this->file->GetSize(&this->size);
|
||||||
|
}
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::Read(void *buffer, size_t size, u64 offset) {
|
||||||
|
Result rc;
|
||||||
|
u64 read_size;
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return ResultFsNullptrArgument;
|
||||||
|
}
|
||||||
|
if (R_FAILED((rc = this->UpdateSize()))) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (!IStorage::IsRangeValid(offset, size, this->size)) {
|
||||||
|
return ResultFsOutOfRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->file->Read(&read_size, offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::Write(void *buffer, size_t size, u64 offset) {
|
||||||
|
Result rc;
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
if (buffer == nullptr) {
|
||||||
|
return ResultFsNullptrArgument;
|
||||||
|
}
|
||||||
|
if (R_FAILED((rc = this->UpdateSize()))) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
if (!IStorage::IsRangeValid(offset, size, this->size)) {
|
||||||
|
return ResultFsOutOfRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this->file->Write(offset, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::Flush() {
|
||||||
|
return this->file->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::GetSize(u64 *out_size) {
|
||||||
|
Result rc = this->UpdateSize();
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
*out_size = this->size;
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::SetSize(u64 size) {
|
||||||
|
this->size = InvalidSize;
|
||||||
|
return this->file->SetSize(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result FileStorage::OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) {
|
||||||
|
Result rc;
|
||||||
|
|
||||||
|
switch (operation_type) {
|
||||||
|
case 2: /* TODO: OperationType_Invalidate */
|
||||||
|
case 3: /* TODO: OperationType_Query */
|
||||||
|
if (size == 0) {
|
||||||
|
if (operation_type == 3) {
|
||||||
|
if (out_range_info == nullptr) {
|
||||||
|
return ResultFsNullptrArgument;
|
||||||
|
}
|
||||||
|
/* N checks for size == sizeof(*out_range_info) here, but that's because their wrapper api is bad. */
|
||||||
|
std::memset(out_range_info, 0, sizeof(*out_range_info));
|
||||||
|
}
|
||||||
|
return ResultSuccess;
|
||||||
|
}
|
||||||
|
if (R_FAILED((rc = this->UpdateSize()))) {
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
/* N checks for positivity + signed overflow on offset/size here, but we're using unsigned types... */
|
||||||
|
return this->file->OperateRange(operation_type, offset, size, out_range_info);
|
||||||
|
default:
|
||||||
|
return ResultFsUnsupportedOperation;
|
||||||
|
}
|
||||||
|
}
|
54
stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp
Normal file
54
stratosphere/ams_mitm/source/fs_mitm/fs_file_storage.hpp
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018-2019 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 <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
#include "fs_shim.h"
|
||||||
|
|
||||||
|
#include "../debug.hpp"
|
||||||
|
#include "fs_istorage.hpp"
|
||||||
|
#include "fs_ifile.hpp"
|
||||||
|
|
||||||
|
class FileStorage : public IStorage {
|
||||||
|
public:
|
||||||
|
static constexpr u64 InvalidSize = UINT64_MAX;
|
||||||
|
private:
|
||||||
|
std::shared_ptr<IFile> base_file;
|
||||||
|
IFile *file;
|
||||||
|
u64 size;
|
||||||
|
public:
|
||||||
|
FileStorage(IFile *f) : base_file(f) {
|
||||||
|
this->file = this->base_file.get();
|
||||||
|
this->size = InvalidSize;
|
||||||
|
};
|
||||||
|
FileStorage(std::shared_ptr<IFile> f) : base_file(f) {
|
||||||
|
this->file = this->base_file.get();
|
||||||
|
this->size = InvalidSize;
|
||||||
|
};
|
||||||
|
virtual ~FileStorage() {
|
||||||
|
/* ... */
|
||||||
|
};
|
||||||
|
protected:
|
||||||
|
Result UpdateSize();
|
||||||
|
public:
|
||||||
|
virtual Result Read(void *buffer, size_t size, u64 offset) override;
|
||||||
|
virtual Result Write(void *buffer, size_t size, u64 offset) override;
|
||||||
|
virtual Result Flush() override;
|
||||||
|
virtual Result GetSize(u64 *out_size) override;
|
||||||
|
virtual Result SetSize(u64 size) override;
|
||||||
|
virtual Result OperateRange(u32 operation_type, u64 offset, u64 size, FsRangeInfo *out_range_info) override;
|
||||||
|
};
|
Loading…
Reference in a new issue