Use existing ioexception for Disk::Open() error handling (#175)

* Use ioexception for file open error handling

* Use standard string comparison functions

* Error message update

* Improved CD-ROM handling error messages
This commit is contained in:
Uwe Seimet 2021-08-10 01:56:13 +02:00 committed by GitHub
parent 0a5298b8ac
commit 157172b566
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 99 additions and 110 deletions

View File

@ -24,7 +24,7 @@
#include "xm6.h"
#include "ctapdriver.h"
#include "log.h"
#include "exceptions.h"
//---------------------------------------------------------------------------
//
@ -247,7 +247,7 @@ BOOL CTapDriver::Init()
}
#endif // __NetBSD__
const char *CTapDriver::OpenDump(const Filepath& path) {
void CTapDriver::OpenDump(const Filepath& path) {
if (m_pcap == NULL) {
m_pcap = pcap_open_dead(DLT_EN10MB, 65535);
}
@ -257,10 +257,10 @@ const char *CTapDriver::OpenDump(const Filepath& path) {
m_pcap_dumper = pcap_dump_open(m_pcap, path.GetPath());
if (m_pcap_dumper == NULL) {
LOGERROR("Error: can't open pcap file: %s", pcap_geterr(m_pcap));
return "Can't open pcap file";
throw ioexception("Can't open pcap file");
}
LOGTRACE("%s Opened %s for dumping", __PRETTY_FUNCTION__, path.GetPath());
return NULL;
}
//---------------------------------------------------------------------------

View File

@ -34,7 +34,7 @@ public:
// Basic Functionality
CTapDriver(); // Constructor
BOOL Init(); // Initilization
const char *OpenDump(const Filepath& path);
void OpenDump(const Filepath& path);
// Capture packets
void Cleanup(); // Cleanup
void GetMacAddr(BYTE *mac); // Get Mac Address

View File

@ -843,10 +843,9 @@ bool Disk::IsNuvolink() const
//
// Open
// * Call as a post-process after successful opening in a derived class
// TODO Use exceptions for error handling instead of returning a string
//
//---------------------------------------------------------------------------
const char *Disk::Open(const Filepath& path, BOOL /*attn*/)
void Disk::Open(const Filepath& path, BOOL /*attn*/)
{
ASSERT((disk.size >= 8) && (disk.size <= 11));
ASSERT(disk.blocks > 0);
@ -877,9 +876,6 @@ const char *Disk::Open(const Filepath& path, BOOL /*attn*/)
// Save path
diskpath = path;
// Success
return NULL;
}
//---------------------------------------------------------------------------

View File

@ -203,7 +203,7 @@ public:
bool IsNuvolink() const;
// Media Operations
virtual const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
virtual void Open(const Filepath& path, BOOL attn = TRUE); // Open
void GetPath(Filepath& path) const; // Get the path
bool Eject(bool); // Eject
bool IsReady() const { return disk.ready; } // Ready check

View File

@ -16,7 +16,7 @@
#include "sasihd.h"
#include "xm6.h"
#include "fileio.h"
#include "exceptions.h"
//===========================================================================
//
@ -55,14 +55,14 @@ void SASIHD::Reset()
// Open
//
//---------------------------------------------------------------------------
const char *SASIHD::Open(const Filepath& path, BOOL /*attn*/)
void SASIHD::Open(const Filepath& path, BOOL /*attn*/)
{
ASSERT(!disk.ready);
// Open as read-only
Fileio fio;
if (!fio.Open(path, Fileio::ReadOnly)) {
return "Can't open hard disk file read-only";
throw ioexception("Can't open hard disk file read-only");
}
// Get file size
@ -78,24 +78,24 @@ const char *SASIHD::Open(const Filepath& path, BOOL /*attn*/)
disk.blocks = (DWORD)(size >> 10);
// Call the base class
return Disk::Open(path);
Disk::Open(path);
}
#endif // USE_MZ1F23_1024_SUPPORT
#if defined(REMOVE_FIXED_SASIHD_SIZE)
// Must be in 256-byte units
if (size & 0xff) {
return "File size must be a multiple of 512";
throw ioexception("File size must be a multiple of 512 bytes");
}
// 10MB or more
if (size < 0x9f5400) {
return FALSE;
throw ioexception("File size must be at least 10 MB");
}
// Limit to about 512MB
if (size > 512 * 1024 * 1024) {
return "File size must not exceed 512 MB";
throw ioexception("File size must not exceed 512 MB");
}
#else
// 10MB, 20MB, 40MBのみ
@ -114,7 +114,7 @@ const char *SASIHD::Open(const Filepath& path, BOOL /*attn*/)
// Other (Not supported )
default:
return "Unsupported file size";
throw ioexception("Unsupported file size");
}
#endif // REMOVE_FIXED_SASIHD_SIZE
@ -123,7 +123,7 @@ const char *SASIHD::Open(const Filepath& path, BOOL /*attn*/)
disk.blocks = (DWORD)(size >> 8);
// Call the base class
return Disk::Open(path);
Disk::Open(path);
}
//---------------------------------------------------------------------------

View File

@ -30,7 +30,7 @@ public:
// Basic Functions
SASIHD(); // Constructor
void Reset(); // Reset
const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
void Open(const Filepath& path, BOOL attn = TRUE); // Open
// commands
int RequestSense(const DWORD *cdb, BYTE *buf); // REQUEST SENSE command

View File

@ -104,10 +104,10 @@ SCSIDaynaPort::~SCSIDaynaPort()
}
}
const char *SCSIDaynaPort::Open(const Filepath& path, BOOL attn)
void SCSIDaynaPort::Open(const Filepath& path, BOOL attn)
{
LOGTRACE("SCSIDaynaPort Open");
return m_tap->OpenDump(path);
m_tap->OpenDump(path);
}
//---------------------------------------------------------------------------

View File

@ -46,7 +46,7 @@ public:
// Constructor
virtual ~SCSIDaynaPort();
// Destructor
const char *Open(const Filepath& path, BOOL attn = TRUE);
void Open(const Filepath& path, BOOL attn = TRUE);
// Capture packets
// commands

View File

@ -17,6 +17,7 @@
#include "xm6.h"
#include "scsicd.h"
#include "fileio.h"
#include "exceptions.h"
//===========================================================================
//
@ -286,7 +287,7 @@ SCSICD::~SCSICD()
// Open
//
//---------------------------------------------------------------------------
const char *SCSICD::Open(const Filepath& path, BOOL attn)
void SCSICD::Open(const Filepath& path, BOOL attn)
{
Fileio fio;
off64_t size;
@ -301,7 +302,7 @@ const char *SCSICD::Open(const Filepath& path, BOOL attn)
// Open as read-only
if (!fio.Open(path, Fileio::ReadOnly)) {
return "Can't open CD-ROM file read-only";
throw ioexception("Can't open CD-ROM file read-only");
}
// Close and transfer for physical CD access
@ -310,15 +311,13 @@ const char *SCSICD::Open(const Filepath& path, BOOL attn)
fio.Close();
// Open physical CD
if (!OpenPhysical(path)) {
return "Can't open physical CD";
}
OpenPhysical(path);
} else {
// Get file size
size = fio.GetFileSize();
if (size <= 4) {
fio.Close();
return "Invalid file size";
throw ioexception("CD-ROM file size must be at least 4 bytes");
}
// Judge whether it is a CUE sheet or an ISO file
@ -327,16 +326,12 @@ const char *SCSICD::Open(const Filepath& path, BOOL attn)
fio.Close();
// If it starts with FILE, consider it as a CUE sheet
if (xstrncasecmp(file, _T("FILE"), 4) == 0) {
if (strncasecmp(file, _T("FILE"), 4) == 0) {
// Open as CUE
if (!OpenCue(path)) {
return "Can't open as CUE";
}
OpenCue(path);
} else {
// Open as ISO
if (!OpenIso(path)) {
return "Can't open as ISO";
}
OpenIso(path);
}
}
@ -358,8 +353,6 @@ const char *SCSICD::Open(const Filepath& path, BOOL attn)
if (disk.ready && attn) {
disk.attn = TRUE;
}
return NULL;
}
//---------------------------------------------------------------------------
@ -367,10 +360,9 @@ const char *SCSICD::Open(const Filepath& path, BOOL attn)
// Open (CUE)
//
//---------------------------------------------------------------------------
BOOL SCSICD::OpenCue(const Filepath& /*path*/)
void SCSICD::OpenCue(const Filepath& /*path*/)
{
// Always fail
return FALSE;
throw ioexception("Opening CUE CD-ROM files is not supported");
}
//---------------------------------------------------------------------------
@ -378,7 +370,7 @@ BOOL SCSICD::OpenCue(const Filepath& /*path*/)
// Open (ISO)
//
//---------------------------------------------------------------------------
BOOL SCSICD::OpenIso(const Filepath& path)
void SCSICD::OpenIso(const Filepath& path)
{
BYTE header[12];
BYTE sync[12];
@ -386,20 +378,20 @@ BOOL SCSICD::OpenIso(const Filepath& path)
// Open as read-only
Fileio fio;
if (!fio.Open(path, Fileio::ReadOnly)) {
return FALSE;
throw ioexception("Can't open ISO CD-ROM file read-only");
}
// Get file size
off64_t size = fio.GetFileSize();
if (size < 0x800) {
fio.Close();
return FALSE;
throw ioexception("ISO CD-ROM file size must be at least 2048 bytes");
}
// Read the first 12 bytes and close
if (!fio.Read(header, sizeof(header))) {
fio.Close();
return FALSE;
throw ioexception("Can't read header of ISO CD-ROM file");
}
// Check if it is RAW format
@ -411,14 +403,14 @@ BOOL SCSICD::OpenIso(const Filepath& path)
// 00,FFx10,00, so it is presumed to be RAW format
if (!fio.Read(header, 4)) {
fio.Close();
return FALSE;
throw ioexception("Can't read header of raw ISO CD-ROM file");
}
// Supports MODE1/2048 or MODE1/2352 only
if (header[3] != 0x01) {
// Different mode
fio.Close();
return FALSE;
throw ioexception("Illegal raw ISO CD-ROM file header");
}
// Set to RAW file
@ -429,10 +421,10 @@ BOOL SCSICD::OpenIso(const Filepath& path)
if (rawfile) {
// Size must be a multiple of 2536 and less than 700MB
if (size % 0x930) {
return FALSE;
throw ioexception("Raw ISO CD-ROM file size must be a multiple of 2536 bytes");
}
if (size > 912579600) {
return FALSE;
throw ioexception("Raw ISO CD-ROM file size must not exceed 700 MB");
}
// Set the number of blocks
@ -440,10 +432,10 @@ BOOL SCSICD::OpenIso(const Filepath& path)
} else {
// Size must be a multiple of 2048 and less than 700MB
if (size & 0x7ff) {
return FALSE;
throw ioexception("ISO CD-ROM file size must be a multiple of 2048 bytes");
}
if (size > 0x2bed5000) {
return FALSE;
throw ioexception("ISO CD-ROM file size must not exceed 700 MB");
}
// Set the number of blocks
@ -457,9 +449,6 @@ BOOL SCSICD::OpenIso(const Filepath& path)
track[0]->SetPath(FALSE, path);
tracks = 1;
dataindex = 0;
// Successful opening
return TRUE;
}
//---------------------------------------------------------------------------
@ -467,19 +456,19 @@ BOOL SCSICD::OpenIso(const Filepath& path)
// Open (Physical)
//
//---------------------------------------------------------------------------
BOOL SCSICD::OpenPhysical(const Filepath& path)
void SCSICD::OpenPhysical(const Filepath& path)
{
// Open as read-only
Fileio fio;
if (!fio.Open(path, Fileio::ReadOnly)) {
return FALSE;
throw ioexception("Can't open CD-ROM file read-only");
}
// Get size
off64_t size = fio.GetFileSize();
if (size < 0x800) {
fio.Close();
return FALSE;
throw ioexception("CD-ROM file size must be at least 2048 bytes");
}
// Close
@ -487,10 +476,10 @@ BOOL SCSICD::OpenPhysical(const Filepath& path)
// Size must be a multiple of 2048 and less than 700MB
if (size & 0x7ff) {
return FALSE;
throw ioexception("CD-ROM file size must be a multiple of 2048 bytes");
}
if (size > 0x2bed5000) {
return FALSE;
throw ioexception("CD-ROM file size must not exceed 700 MB");
}
// Set the number of blocks
@ -503,9 +492,6 @@ BOOL SCSICD::OpenPhysical(const Filepath& path)
track[0]->SetPath(FALSE, path);
tracks = 1;
dataindex = 0;
// Successful opening
return TRUE;
}
//---------------------------------------------------------------------------

View File

@ -114,7 +114,7 @@ public:
// Basic Functions
SCSICD(); // Constructor
virtual ~SCSICD(); // Destructor
const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
void Open(const Filepath& path, BOOL attn = TRUE); // Open
// commands
int Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command
@ -134,9 +134,9 @@ public:
private:
// Open
BOOL OpenCue(const Filepath& path); // Open(CUE)
BOOL OpenIso(const Filepath& path); // Open(ISO)
BOOL OpenPhysical(const Filepath& path); // Open(Physical)
void OpenCue(const Filepath& path); // Open(CUE)
void OpenIso(const Filepath& path); // Open(ISO)
void OpenPhysical(const Filepath& path); // Open(Physical)
BOOL rawfile; // RAW flag
// Track management

View File

@ -16,6 +16,7 @@
#include "scsihd.h"
#include "xm6.h"
#include "fileio.h"
#include "exceptions.h"
//===========================================================================
//
@ -54,14 +55,14 @@ void SCSIHD::Reset()
// Open
//
//---------------------------------------------------------------------------
const char *SCSIHD::Open(const Filepath& path, BOOL /*attn*/)
void SCSIHD::Open(const Filepath& path, BOOL /*attn*/)
{
ASSERT(!disk.ready);
// read open required
Fileio fio;
if (!fio.Open(path, Fileio::ReadOnly)) {
return "Can't open hard disk file read-only";
throw ioexception("Can't open hard disk file read-only");
}
// Get file size
@ -70,14 +71,14 @@ const char *SCSIHD::Open(const Filepath& path, BOOL /*attn*/)
// Must be 512 bytes
if (size & 0x1ff) {
return "File size must be a multiple of 512 bytes";
throw ioexception("File size must be a multiple of 512 bytes");
}
// 2TB according to xm6i
// There is a similar one in wxw/wxw_cfg.cpp
// Bigger files/drives require READ/WRITE(16) to be implemented
if (size > 2LL * 1024 * 1024 * 1024 * 1024) {
return "File size must not exceed 2 TB";
throw ioexception("File size must not exceed 2 TB");
}
// sector size and number of blocks
@ -85,7 +86,7 @@ const char *SCSIHD::Open(const Filepath& path, BOOL /*attn*/)
disk.blocks = (DWORD)(size >> 9);
// Call base class
return Disk::Open(path);
Disk::Open(path);
}
//---------------------------------------------------------------------------

View File

@ -30,7 +30,7 @@ public:
// Basic Functions
SCSIHD(); // Constructor
void Reset(); // Reset
const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
void Open(const Filepath& path, BOOL attn = TRUE); // Open
// commands
int Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command

View File

@ -16,6 +16,7 @@
#include "scsihd_nec.h"
#include "fileio.h"
#include "exceptions.h"
//===========================================================================
//
@ -65,7 +66,7 @@ static inline DWORD getDwordLE(const BYTE *b)
// Open
//
//---------------------------------------------------------------------------
const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
void SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
{
Fileio fio;
off64_t size;
@ -76,7 +77,7 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
// Open as read-only
if (!fio.Open(path, Fileio::ReadOnly)) {
return "Can't open hard disk file read-only";
throw ioexception("Can't open hard disk file read-only");
}
// Get file size
@ -86,28 +87,24 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
if (size >= (off64_t)sizeof(hdr)) {
if (!fio.Read(hdr, sizeof(hdr))) {
fio.Close();
return "Can't read hard disk file header";
throw ioexception("Can't read hard disk file header");
}
}
fio.Close();
// Must be in 512 byte units
if (size & 0x1ff) {
return "File size must be a multiple of 512";
throw ioexception("File size must be a multiple of 512 bytes");
}
// 10MB or more
if (size < 0x9f5400) {
return FALSE;
}
// 2TB according to xm6i
if (size > 2LL * 1024 * 1024 * 1024 * 1024) {
return "File size must not exceed 2 TB";
throw ioexception("File size must not exceed 2 TB");
}
// Determine parameters by extension
ext = path.GetFileExt();
if (xstrcasecmp(ext, _T(".HDN")) == 0) {
if (strcasecmp(ext, _T(".HDN")) == 0) {
// Assuming sector size 512, number of sectors 25, number of heads 8 as default settings
imgoffset = 0;
imgsize = size;
@ -117,14 +114,14 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
cylinders = (int)(size >> 9);
cylinders >>= 3;
cylinders /= 25;
} else if (xstrcasecmp(ext, _T(".HDI")) == 0) { // Anex86 HD image?
} else if (strcasecmp(ext, _T(".HDI")) == 0) { // Anex86 HD image?
imgoffset = getDwordLE(&hdr[4 + 4]);
imgsize = getDwordLE(&hdr[4 + 4 + 4]);
sectorsize = getDwordLE(&hdr[4 + 4 + 4 + 4]);
sectors = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4]);
heads = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4]);
cylinders = getDwordLE(&hdr[4 + 4 + 4 + 4 + 4 + 4 + 4]);
} else if (xstrcasecmp(ext, _T(".NHD")) == 0 &&
} else if (strcasecmp(ext, _T(".NHD")) == 0 &&
memcmp(hdr, "T98HDDIMAGE.R0\0", 15) == 0) { // T98Next HD image?
imgoffset = getDwordLE(&hdr[0x10 + 0x100]);
cylinders = getDwordLE(&hdr[0x10 + 0x100 + 4]);
@ -136,12 +133,12 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
// Supports 256 or 512 sector sizes
if (sectorsize != 256 && sectorsize != 512) {
return "Sector size must be 256 or 512";
throw ioexception("Sector size must be 256 or 512 bytes");
}
// Image size consistency check
if (imgoffset + imgsize > size || (imgsize % sectorsize != 0)) {
return "Image size consistency check failed";
throw ioexception("Image size consistency check failed");
}
// Sector size
@ -150,7 +147,7 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
break;
}
if (disk.size <= 0 || disk.size > 16) {
return "Invalid disk size";
throw ioexception("Invalid disk size");
}
// Number of blocks
@ -158,7 +155,7 @@ const char *SCSIHD_NEC::Open(const Filepath& path, BOOL /*attn*/)
disk.imgoffset = imgoffset;
// Call the base class
return Disk::Open(path);
Disk::Open(path);
}
//---------------------------------------------------------------------------

View File

@ -27,7 +27,7 @@ class SCSIHD_NEC : public SCSIHD
public:
// Basic Functions
SCSIHD_NEC(); // Constructor
const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
void Open(const Filepath& path, BOOL attn = TRUE); // Open
// commands
int Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command

View File

@ -17,6 +17,7 @@
#include "scsimo.h"
#include "xm6.h"
#include "fileio.h"
#include "exceptions.h"
//===========================================================================
//
@ -41,14 +42,14 @@ SCSIMO::SCSIMO() : Disk("SCMO")
// Open
//
//---------------------------------------------------------------------------
const char *SCSIMO::Open(const Filepath& path, BOOL attn)
void SCSIMO::Open(const Filepath& path, BOOL attn)
{
ASSERT(!disk.ready);
// Open as read-only
Fileio fio;
if (!fio.Open(path, Fileio::ReadOnly)) {
return "Can't open MO file read-only";
throw ioexception("Can't open MO file read-only");
}
// Get file size
@ -82,7 +83,7 @@ const char *SCSIMO::Open(const Filepath& path, BOOL attn)
// Other (this is an error)
default:
return "Invalid MO size";
throw ioexception("Invalid MO file size");
}
// Call the base class
@ -92,8 +93,6 @@ const char *SCSIMO::Open(const Filepath& path, BOOL attn)
if (disk.ready && attn) {
disk.attn = TRUE;
}
return NULL;
}
//---------------------------------------------------------------------------

View File

@ -29,7 +29,7 @@ class SCSIMO : public Disk
public:
// Basic Functions
SCSIMO(); // Constructor
const char *Open(const Filepath& path, BOOL attn = TRUE); // Open
void Open(const Filepath& path, BOOL attn = TRUE); // Open
// commands
int Inquiry(const DWORD *cdb, BYTE *buf, DWORD major, DWORD minor); // INQUIRY command

View File

@ -130,7 +130,4 @@ typedef const char *LPCSTR;
#define off64_t off_t
#define xstrcasecmp strcasecmp
#define xstrncasecmp strncasecmp
#endif // os_h

View File

@ -525,7 +525,6 @@ bool ProcessCmd(int fd, const PbCommand &command)
Filepath filepath;
Disk *pUnit;
ostringstream error;
const char *result;
int id = command.id();
int un = command.un();
@ -629,16 +628,20 @@ bool ProcessCmd(int fd, const PbCommand &command)
filepath.SetPath(file.c_str());
// Open the file path
result = pUnit->Open(filepath);
if (result) {
try {
pUnit->Open(filepath);
}
catch(const ioexception& e) {
// If the file does not exist search for it in the default image folder
string default_file = default_image_folder + "/" + file;
filepath.SetPath(default_file.c_str());
result = pUnit->Open(filepath);
if (result) {
try {
pUnit->Open(filepath);
}
catch(const ioexception&) {
delete pUnit;
error << "Tried to open an invalid file '" << file << "': " << result;
error << "Tried to open an invalid file '" << file << "': " << e.getmsg();
LOGWARN("%s", error.str().c_str());
return ReturnStatus(fd, false, error);
}
@ -723,14 +726,18 @@ bool ProcessCmd(int fd, const PbCommand &command)
filepath.SetPath(params.c_str());
LOGINFO("Insert file '%s' requested into %s ID: %d UN: %d", params.c_str(), pUnit->GetID().c_str(), id, un);
result = pUnit->Open(filepath);
if (result) {
try {
pUnit->Open(filepath);
}
catch(const ioexception& e) {
// If the file does not exist search for it in the default image folder
string default_file = default_image_folder + "/" + params;
filepath.SetPath(default_file.c_str());
result = pUnit->Open(filepath);
if (result) {
error << "Tried to open an invalid file '" << params << "': " << result;
try {
pUnit->Open(filepath);
}
catch(const ioexception&) {
error << "Tried to open an invalid file '" << params << "': " << e.getmsg();
LOGWARN("%s", error.str().c_str());
return ReturnStatus(fd, false, error);
}

View File

@ -136,6 +136,9 @@ PbDeviceType MapIdToType(const string& id, bool is_sasi)
else if (id == "SCDP") {
return DAYNAPORT;
}
else if (id == "SCNL") {
return NUVOLINK;
}
else {
return UNDEFINED;
}
@ -160,6 +163,9 @@ string MapTypeToId(const PbDeviceType type)
case DAYNAPORT:
return "SCDP";
case NUVOLINK:
return "SCNL";
default:
return "????";
}