Merge pull request #571 from davidgiven/vfs

Allow formatting disks.
This commit is contained in:
David Given
2022-08-31 13:08:02 +02:00
committed by GitHub
8 changed files with 115 additions and 9 deletions

View File

@@ -1,6 +1,8 @@
#include "lib/globals.h"
#include "lib/vfs/vfs.h"
#include "lib/config.pb.h"
#include "lib/proto.h"
#include "lib/layout.h"
#include <fmt/format.h>
#include "adflib.h"
@@ -54,6 +56,26 @@ public:
{
}
void create(bool quick, const std::string& volumeName)
{
if (!quick)
eraseEverythingOnDisk();
AdfMount m(this);
struct Device dev = {};
dev.readOnly = false;
dev.isNativeDev = true;
dev.devType = DEVTYPE_FLOPDD;
dev.cylinders = config.layout().tracks();
dev.heads = config.layout().sides();
dev.sectors =
Layout::getSectorsInTrack(Layout::getLayoutOfTrack(0, 0)).size();
adfInitDevice(&dev, nullptr, false);
int res = adfCreateFlop(&dev, (char*)volumeName.c_str(), 0);
if (res != RC_OK)
throw CannotWriteException();
}
FilesystemStatus check()
{
return FS_OK;
@@ -65,7 +87,7 @@ public:
std::vector<std::unique_ptr<Dirent>> results;
auto* vol = m.getVolume();
auto* vol = m.mount();
changeDir(vol, path);
auto list = AdfList(adfGetDirEnt(vol, vol->curDirPtr));
@@ -93,7 +115,7 @@ public:
if (path.size() == 0)
throw BadPathException();
auto* vol = m.getVolume();
auto* vol = m.mount();
changeDirButOne(vol, path);
auto entry = AdfEntry(adfFindEntry(vol, (char*)path.back().c_str()));
@@ -126,7 +148,7 @@ public:
if (path.size() == 0)
throw BadPathException();
auto* vol = m.getVolume();
auto* vol = m.mount();
changeDirButOne(vol, path);
auto* file = adfOpenFile(vol, (char*)path.back().c_str(), (char*)"r");
@@ -153,7 +175,7 @@ public:
if (path.size() == 0)
throw BadPathException();
auto* vol = m.getVolume();
auto* vol = m.mount();
changeDirButOne(vol, path);
auto* file = adfOpenFile(vol, (char*)path.back().c_str(), (char*)"w");
@@ -229,19 +251,21 @@ private:
AdfMount(AmigaFfsFilesystem* self): self(self)
{
currentAmigaFfs = self;
self->_ffs = nullptr;
adfEnvInitDefault();
self->_ffs = adfMountDev(nullptr, false);
}
~AdfMount()
{
adfUnMountDev(self->_ffs);
if (self->_ffs)
adfUnMountDev(self->_ffs);
adfEnvCleanUp();
}
struct Volume* getVolume()
struct Volume* mount()
{
self->_ffs = adfMountDev(nullptr, false);
return adfMount(self->_ffs, 0, false);
}

View File

@@ -36,6 +36,20 @@ public:
{
}
void create(bool quick, const std::string& volumeName)
{
if (!quick)
eraseEverythingOnDisk();
char buffer[FF_MAX_SS * 2];
currentFatFs = this;
FRESULT res = f_mkfs("", nullptr, buffer, sizeof(buffer));
throwError(res);
mount();
f_setlabel(volumeName.c_str());
}
FilesystemStatus check()
{
return FS_OK;
@@ -162,9 +176,14 @@ public:
case GET_SECTOR_SIZE:
*(DWORD*)buffer = getLogicalSectorSize();
break;
case GET_SECTOR_COUNT:
*(DWORD*)buffer = getLogicalSectorCount();
break;
case CTRL_SYNC:
break;
default:
return RES_PARERR;
}

View File

@@ -29,6 +29,15 @@ public:
return FS_OK;
}
void create(bool quick, const std::string& volumeName)
{
if (!quick)
eraseEverythingOnDisk();
hfs_format(
(const char*)this, 0, HFS_MODE_ANY, volumeName.c_str(), 0, nullptr);
}
std::vector<std::unique_ptr<Dirent>> list(const Path& path)
{
HfsMount m(this);

View File

@@ -33,7 +33,7 @@ std::string Path::to_str(const std::string sep) const
return join(*this, sep);
}
void Filesystem::create()
void Filesystem::create(bool quick, const std::string& volumeName)
{
throw UnimplementedFilesystemException();
}
@@ -215,3 +215,9 @@ unsigned Filesystem::getLogicalSectorSize(unsigned track, unsigned side)
auto trackdata = Layout::getLayoutOfTrack(track, side);
return trackdata.sector_size();
}
void Filesystem::eraseEverythingOnDisk()
{
for (int i = 0; i < getLogicalSectorCount(); i++)
putLogicalSector(i, Bytes(1));
}

View File

@@ -101,7 +101,7 @@ public:
class Filesystem
{
public:
virtual void create();
virtual void create(bool quick, const std::string& name);
virtual FilesystemStatus check();
virtual std::vector<std::unique_ptr<Dirent>> list(const Path& path);
virtual Bytes getFile(const Path& path);
@@ -125,6 +125,8 @@ protected:
unsigned getLogicalSectorCount();
unsigned getLogicalSectorSize(unsigned track = 0, unsigned side = 0);
void eraseEverythingOnDisk();
private:
typedef std::tuple<unsigned, unsigned, unsigned> location_t;
std::vector<location_t> _locations;

View File

@@ -3,6 +3,7 @@ include src/formats/build.mk
FLUXENGINE_SRCS = \
src/fe-analysedriveresponse.cc \
src/fe-analyselayout.cc \
src/fe-format.cc \
src/fe-getfile.cc \
src/fe-getfileinfo.cc \
src/fe-inspect.cc \

43
src/fe-format.cc Normal file
View File

@@ -0,0 +1,43 @@
#include "globals.h"
#include "flags.h"
#include "fluxmap.h"
#include "sector.h"
#include "proto.h"
#include "readerwriter.h"
#include "imagereader/imagereader.h"
#include "imagewriter/imagewriter.h"
#include "lib/fluxsource/fluxsource.h"
#include "lib/decoders/decoders.h"
#include "fmt/format.h"
#include "fluxengine.h"
#include "lib/vfs/sectorinterface.h"
#include "lib/vfs/vfs.h"
#include "src/fileutils.h"
#include <google/protobuf/text_format.h>
#include <fstream>
static FlagGroup flags({&fileFlags});
static StringFlag volumeName({"-n", "--name"}, "volume name", "FluxEngine");
static SettableFlag quick({"-q", "--quick"},
"perform quick format (requires the disk to be previously formatted)");
int mainFormat(int argc, const char* argv[])
{
if (argc == 1)
showProfiles("format", formats);
flags.parseFlagsWithConfigFiles(argc, argv, formats);
try
{
auto filesystem = createFilesystemFromConfig();
filesystem->create(quick, volumeName);
filesystem->flush();
}
catch (const FilesystemException& e)
{
Error() << e.message;
}
return 0;
}

View File

@@ -6,6 +6,7 @@ typedef int command_cb(int agrc, const char* argv[]);
extern command_cb mainAnalyseDriveResponse;
extern command_cb mainAnalyseLayout;
extern command_cb mainFormat;
extern command_cb mainGetFile;
extern command_cb mainGetFileInfo;
extern command_cb mainInspect;
@@ -36,6 +37,7 @@ static std::vector<Command> commands =
{ "analyse", mainAnalyse, "Disk and drive analysis tools." },
{ "read", mainRead, "Reads a disk, producing a sector image.", },
{ "write", mainWrite, "Writes a sector image to a disk.", },
{ "format", mainFormat, "Format a disk and make a file system on it.", },
{ "rawread", mainRawRead, "Reads raw flux from a disk. Warning: you can't use this to copy disks.", },
{ "rawwrite", mainRawWrite, "Writes a flux file to a disk. Warning: you can't use this to copy disks.", },
{ "ls", mainLs, "Show files on disk (or image).", },