Memory management update, SonarCloud fixes, fix for issue #841 (#842)

- Memory management updates, more fixed Sonar issues
* Replaced macros, fixed other sonar issues
* Added const, replaced enum with a single value by constant
* Updated object initializations
* Fixed potential strncpy overflow reported by gcc 8.3
This commit is contained in:
Uwe Seimet 2022-09-15 23:01:10 +02:00 committed by GitHub
parent e64c2f7254
commit 241e739d3a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 533 additions and 712 deletions

View File

@ -13,6 +13,7 @@
#include "phase_handler.h"
#include <unordered_map>
#include <memory>
using namespace std;
@ -57,7 +58,7 @@ public:
unordered_map<int, PrimaryDevice *> luns;
};
AbstractController(BUS *bus, int target_id) : bus(bus), target_id(target_id) {}
AbstractController(shared_ptr<BUS> bus, int target_id) : bus(bus), target_id(target_id) {}
~AbstractController() override = default;
AbstractController(AbstractController&) = delete;
AbstractController& operator=(const AbstractController&) = delete;
@ -91,7 +92,7 @@ public:
protected:
BUS *bus;
shared_ptr<BUS> bus;
ctrl_t ctrl = {};

View File

@ -15,31 +15,24 @@
using namespace std;
unordered_map<int, AbstractController *> ControllerManager::controllers;
ControllerManager::~ControllerManager()
{
DeleteAllControllersAndDevices();
}
ControllerManager& ControllerManager::instance()
{
static ControllerManager instance;
return instance;
}
bool ControllerManager::CreateScsiController(BUS *bus, PrimaryDevice *device)
bool ControllerManager::CreateScsiController(shared_ptr<BUS> bus, PrimaryDevice *device) const
{
AbstractController *controller = FindController(device->GetId());
shared_ptr<AbstractController> controller = FindController(device->GetId());
if (controller == nullptr) {
controller = make_unique<ScsiController>(bus, device->GetId()).release();
controller = make_shared<ScsiController>(bus, device->GetId());
controllers[device->GetId()] = controller;
}
return controller->AddDevice(device);
}
AbstractController *ControllerManager::IdentifyController(int data) const
shared_ptr<AbstractController> ControllerManager::IdentifyController(int data) const
{
for (const auto& [id, controller] : controllers) {
if (data & (1 << controller->GetTargetId())) {
@ -50,26 +43,18 @@ AbstractController *ControllerManager::IdentifyController(int data) const
return nullptr;
}
AbstractController *ControllerManager::FindController(int target_id) const
shared_ptr<AbstractController> ControllerManager::FindController(int target_id) const
{
const auto& it = controllers.find(target_id);
return it == controllers.end() ? nullptr : it->second;
}
void ControllerManager::DeleteAllControllersAndDevices()
void ControllerManager::DeleteAllControllers() const
{
for (const auto& [id, controller] : controllers) {
delete controller;
}
controllers.clear();
DeviceFactory::instance().DeleteAllDevices();
FileSupport::UnreserveAll();
}
void ControllerManager::ResetAllControllers()
void ControllerManager::ResetAllControllers() const
{
for (const auto& [id, controller] : controllers) {
controller->Reset();

View File

@ -12,6 +12,9 @@
#pragma once
#include <unordered_map>
#include <memory>
using namespace std;
class BUS;
class AbstractController;
@ -20,7 +23,7 @@ class PrimaryDevice;
class ControllerManager
{
ControllerManager() = default;
~ControllerManager();
~ControllerManager() = default;
ControllerManager(ControllerManager&) = delete;
ControllerManager& operator=(const ControllerManager&) = delete;
@ -30,12 +33,12 @@ public:
static ControllerManager& instance();
bool CreateScsiController(BUS *, PrimaryDevice *);
AbstractController *IdentifyController(int) const;
AbstractController *FindController(int) const;
void DeleteAllControllersAndDevices();
void ResetAllControllers();
bool CreateScsiController(shared_ptr<BUS>, PrimaryDevice *) const;
shared_ptr<AbstractController> IdentifyController(int) const;
shared_ptr<AbstractController> FindController(int) const;
void DeleteAllControllers() const;
void ResetAllControllers() const;
PrimaryDevice *GetDeviceByIdAndLun(int, int) const;
static std::unordered_map<int, AbstractController *> controllers;
inline static unordered_map<int, shared_ptr<AbstractController>> controllers;
};

View File

@ -24,7 +24,7 @@
using namespace scsi_defs;
ScsiController::ScsiController(BUS *bus, int target_id) : AbstractController(bus, target_id)
ScsiController::ScsiController(shared_ptr<BUS> bus, int target_id) : AbstractController(bus, target_id)
{
// The initial buffer size will default to either the default buffer size OR
// the size of an Ethernet message, whichever is larger.
@ -57,7 +57,7 @@ void ScsiController::Reset()
bytes_to_transfer = 0;
// Reset all LUNs
for (auto& [lun, device] : ctrl.luns) {
for (const auto& [lun, device] : ctrl.luns) {
device->Reset();
}
}
@ -564,12 +564,10 @@ void ScsiController::Send()
bool result = true;
// Processing after data collection (read/data-in only)
if (ctrl.phase == BUS::datain) {
if (ctrl.blocks != 0) {
// set next buffer (set offset, length)
result = XferIn(ctrl.buffer);
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str())
}
if (ctrl.phase == BUS::datain && ctrl.blocks != 0) {
// set next buffer (set offset, length)
result = XferIn(ctrl.buffer);
LOGTRACE("%s%s", __PRETTY_FUNCTION__, (" Processing after data collection. Blocks: " + to_string(ctrl.blocks)).c_str())
}
// If result FALSE, move to status phase

View File

@ -69,7 +69,7 @@ class ScsiController : public AbstractController
public:
ScsiController(BUS *, int);
ScsiController(shared_ptr<BUS>, int);
~ScsiController() override;
ScsiController(ScsiController&) = delete;
ScsiController& operator=(const ScsiController&) = delete;

View File

@ -202,17 +202,6 @@ void Human68k::namests_t::GetCopyFilename(BYTE* szFilename) const
//
//===========================================================================
CHostDrv::CHostDrv()
{
m_bWriteProtect = FALSE;
m_bEnable = FALSE;
m_capCache.sectors = 0;
m_bVolumeCache = FALSE;
m_szVolumeCache[0] = _T('\0');
m_szBase[0] = _T('\0');
m_nRing = 0;
}
CHostDrv::~CHostDrv()
{
CHostPath* p;
@ -248,6 +237,8 @@ void CHostDrv::Init(const TCHAR* szBase, DWORD nFlag)
ASSERT(m_cRing.Prev() == &m_cRing);
ASSERT(m_nRing == 0);
m_capCache.sectors = 0;
// Receive parameters
if (nFlag & FSFLAG_WRITE_PROTECT)
m_bWriteProtect = TRUE;
@ -726,7 +717,7 @@ BOOL CHostDrv::Find(CHostFiles* pFiles)
ASSERT(pFiles);
// Get path name and build cache
CHostPath* pPath = CopyCache(pFiles);
const CHostPath* pPath = CopyCache(pFiles);
if (pPath == nullptr) {
pPath = MakeCache(pFiles);
if (pPath == nullptr) {
@ -764,13 +755,6 @@ BOOL CHostDrv::Find(CHostFiles* pFiles)
//
//===========================================================================
CHostFilename::CHostFilename()
{
m_bCorrect = FALSE;
m_pszHumanExt = FALSE;
m_pszHumanLast = FALSE;
}
//---------------------------------------------------------------------------
//
/// Set host side name
@ -861,8 +845,8 @@ void CHostFilename::ConvertHuman(int nCount)
// Char conversion
BYTE szHuman[FILEPATH_MAX];
const BYTE* pFirst = szHuman;
const BYTE* pLast;
const BYTE* pExt = nullptr;
BYTE* pLast;
BYTE* pExt = nullptr;
{
strcpy(szHost, m_szHost);
@ -934,15 +918,14 @@ void CHostFilename::ConvertHuman(int nCount)
// Delete spaces at the end
while (pExt < pLast - 1 && *(pLast - 1) == ' ') {
pLast--;
auto p = (BYTE*)pLast;
auto p = pLast;
*p = '\0';
}
// Delete if the file name disappeared after conversion
if (pExt + 1 >= pLast) {
pLast = pExt;
auto p = (BYTE*)pLast;
*p = '\0'; // Just in case
*pLast = '\0'; // Just in case
}
} else {
pExt = pLast;
@ -1065,7 +1048,7 @@ void CHostFilename::CopyHuman(const BYTE* szHuman)
void CHostFilename::SetEntryName()
{
// Set file name
BYTE* p = m_szHuman;
const BYTE* p = m_szHuman;
size_t i;
for (i = 0; i < 8; i++) {
if (p < m_pszHumanExt)
@ -1098,7 +1081,7 @@ void CHostFilename::SetEntryName()
//---------------------------------------------------------------------------
BOOL CHostFilename::isReduce() const
{
return strcmp((char *)m_szHost, (char*)m_szHuman) != 0;
return strcmp((const char *)m_szHost, (const char*)m_szHuman) != 0;
}
//---------------------------------------------------------------------------
@ -1150,18 +1133,6 @@ const BYTE* CHostFilename::SeparateExt(const BYTE* szHuman) // static
DWORD CHostPath::g_nId; ///< Identifier creation counter
CHostPath::CHostPath()
{
m_bRefresh = TRUE;
m_nId = 0;
m_tBackup = FALSE;
#ifdef _DEBUG
// Initialization is not required because this value always gets updated (used for debugging or initialization operation)
m_nId = 0;
#endif // _DEBUG
}
CHostPath::~CHostPath()
{
Clean();
@ -1739,22 +1710,13 @@ void CHostPath::Release()
//
//===========================================================================
CHostEntry::CHostEntry()
{
for (size_t n = 0; n < DriveMax; n++) {
m_pDrv[n] = nullptr;
}
m_nTimeout = 0;
}
CHostEntry::~CHostEntry()
{
Clean();
#ifdef _DEBUG
// Confirm object
for (size_t n = 0; n < DriveMax; n++) {
for (size_t n = 0; n < DRIVE_MAX; n++) {
ASSERT(m_pDrv[n] == nullptr);
}
#endif // _DEBUG
@ -1765,15 +1727,15 @@ CHostEntry::~CHostEntry()
/// Initialize (when the driver is installed)
//
//---------------------------------------------------------------------------
void CHostEntry::Init()
void CHostEntry::Init() const
{
#ifdef _DEBUG
// Confirm object
for (size_t n = 0; n < DriveMax; n++) {
for (size_t n = 0; n < DRIVE_MAX; n++) {
ASSERT(m_pDrv[n] == nullptr);
}
#endif // _DEBUG
#endif
}
//---------------------------------------------------------------------------
@ -1785,7 +1747,7 @@ void CHostEntry::Clean()
{
// Delete object
for (size_t n = 0; n < DriveMax; n++) {
for (size_t n = 0; n < DRIVE_MAX; n++) {
delete m_pDrv[n];
m_pDrv[n] = nullptr;
}
@ -1796,10 +1758,10 @@ void CHostEntry::Clean()
/// Update all cache
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCache()
void CHostEntry::CleanCache() const
{
for (size_t i = 0; i < DriveMax; i++) {
for (size_t i = 0; i < DRIVE_MAX; i++) {
if (m_pDrv[i])
m_pDrv[i]->CleanCache();
}
@ -1812,9 +1774,9 @@ void CHostEntry::CleanCache()
/// Update the cache for the specified unit
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCache(DWORD nUnit)
void CHostEntry::CleanCache(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->CleanCache();
@ -1825,10 +1787,10 @@ void CHostEntry::CleanCache(DWORD nUnit)
/// Update the cache for the specified path
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCache(DWORD nUnit, const BYTE* szHumanPath)
void CHostEntry::CleanCache(DWORD nUnit, const BYTE* szHumanPath) const
{
ASSERT(szHumanPath);
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->CleanCache(szHumanPath);
@ -1839,10 +1801,10 @@ void CHostEntry::CleanCache(DWORD nUnit, const BYTE* szHumanPath)
/// Update all cache for the specified path and below
//
//---------------------------------------------------------------------------
void CHostEntry::CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath)
void CHostEntry::CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath) const
{
ASSERT(szHumanPath);
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->CleanCacheChild(szHumanPath);
@ -1853,10 +1815,10 @@ void CHostEntry::CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath)
/// Delete cache for the specified path
//
//---------------------------------------------------------------------------
void CHostEntry::DeleteCache(DWORD nUnit, const BYTE* szHumanPath)
void CHostEntry::DeleteCache(DWORD nUnit, const BYTE* szHumanPath) const
{
ASSERT(szHumanPath);
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->DeleteCache(szHumanPath);
@ -1870,7 +1832,7 @@ void CHostEntry::DeleteCache(DWORD nUnit, const BYTE* szHumanPath)
BOOL CHostEntry::Find(DWORD nUnit, CHostFiles* pFiles) const
{
ASSERT(pFiles);
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->Find(pFiles);
@ -1883,7 +1845,7 @@ BOOL CHostEntry::Find(DWORD nUnit, CHostFiles* pFiles) const
//---------------------------------------------------------------------------
void CHostEntry::SetDrv(DWORD nUnit, CHostDrv* pDrv)
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit] == nullptr);
m_pDrv[nUnit] = pDrv;
@ -1896,7 +1858,7 @@ void CHostEntry::SetDrv(DWORD nUnit, CHostDrv* pDrv)
//---------------------------------------------------------------------------
BOOL CHostEntry::isWriteProtect(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->isWriteProtect();
@ -1909,7 +1871,7 @@ BOOL CHostEntry::isWriteProtect(DWORD nUnit) const
//---------------------------------------------------------------------------
BOOL CHostEntry::isEnable(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->isEnable();
@ -1922,7 +1884,7 @@ BOOL CHostEntry::isEnable(DWORD nUnit) const
//---------------------------------------------------------------------------
BOOL CHostEntry::isMediaOffline(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->isMediaOffline();
@ -1935,7 +1897,7 @@ BOOL CHostEntry::isMediaOffline(DWORD nUnit) const
//---------------------------------------------------------------------------
BYTE CHostEntry::GetMediaByte(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->GetMediaByte();
@ -1948,7 +1910,7 @@ BYTE CHostEntry::GetMediaByte(DWORD nUnit) const
//---------------------------------------------------------------------------
DWORD CHostEntry::GetStatus(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->GetStatus();
@ -1961,7 +1923,7 @@ DWORD CHostEntry::GetStatus(DWORD nUnit) const
//---------------------------------------------------------------------------
BOOL CHostEntry::CheckMedia(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->CheckMedia();
@ -1972,9 +1934,9 @@ BOOL CHostEntry::CheckMedia(DWORD nUnit) const
/// Eject
//
//---------------------------------------------------------------------------
void CHostEntry::Eject(DWORD nUnit)
void CHostEntry::Eject(DWORD nUnit) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->Eject();
@ -1985,9 +1947,9 @@ void CHostEntry::Eject(DWORD nUnit)
/// Get volume label
//
//---------------------------------------------------------------------------
void CHostEntry::GetVolume(DWORD nUnit, TCHAR* szLabel)
void CHostEntry::GetVolume(DWORD nUnit, TCHAR* szLabel) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
m_pDrv[nUnit]->GetVolume(szLabel);
@ -2000,7 +1962,7 @@ void CHostEntry::GetVolume(DWORD nUnit, TCHAR* szLabel)
//---------------------------------------------------------------------------
BOOL CHostEntry::GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->GetVolumeCache(szLabel);
@ -2013,7 +1975,7 @@ BOOL CHostEntry::GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const
//---------------------------------------------------------------------------
DWORD CHostEntry::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->GetCapacity(pCapacity);
@ -2026,7 +1988,7 @@ DWORD CHostEntry::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) cons
//---------------------------------------------------------------------------
BOOL CHostEntry::GetCapacityCache(DWORD nUnit, Human68k::capacity_t* pCapacity) const
{
ASSERT(nUnit < DriveMax);
ASSERT(nUnit < DRIVE_MAX);
ASSERT(m_pDrv[nUnit]);
return m_pDrv[nUnit]->GetCapacityCache(pCapacity);
@ -2108,7 +2070,7 @@ void CHostFiles::SetPath(const Human68k::namests_t* pNamests)
/// Find file on the Human68k side and create data on the host side
//
//---------------------------------------------------------------------------
BOOL CHostFiles::Find(DWORD nUnit, CHostEntry* pEntry)
BOOL CHostFiles::Find(DWORD nUnit, const CHostEntry* pEntry)
{
ASSERT(pEntry);
@ -2120,7 +2082,7 @@ BOOL CHostFiles::Find(DWORD nUnit, CHostEntry* pEntry)
/// Find file name
//
//---------------------------------------------------------------------------
const CHostFilename* CHostFiles::Find(CHostPath* pPath)
const CHostFilename* CHostFiles::Find(const CHostPath* pPath)
{
ASSERT(pPath);
@ -2282,12 +2244,6 @@ void CHostFilesManager::Free(CHostFiles* pFiles)
//
//===========================================================================
void CHostFcb::Init()
{
m_bUpdate = FALSE;
m_pFile = nullptr;
}
//---------------------------------------------------------------------------
//
/// Set file open mode
@ -2557,7 +2513,6 @@ CHostFcbManager::~CHostFcbManager()
//---------------------------------------------------------------------------
void CHostFcbManager::Init()
{
// Confirm that the entity does not exist (just in case)
ASSERT(m_cRing.Next() == &m_cRing);
ASSERT(m_cRing.Prev() == &m_cRing);
@ -2575,9 +2530,8 @@ void CHostFcbManager::Init()
// Clean (at startup/reset)
//
//---------------------------------------------------------------------------
void CHostFcbManager::Clean()
void CHostFcbManager::Clean() const
{
// Fast task killer
CRing* p;
while ((p = m_cRing.Next()) != &m_cRing) {
@ -2646,31 +2600,6 @@ void CHostFcbManager::Free(CHostFcb* pFcb)
DWORD CFileSys::g_nOption; // File name conversion flag
CFileSys::CFileSys()
{
m_nHostSectorCount = 0;
// Config data initialization
m_nDrives = 0;
for (size_t n = 0; n < DriveMax; n++) {
m_nFlag[n] = 0;
m_szBase[n][0] = _T('\0');
}
// Initialize TwentyOne option monitoring
m_nKernel = 0;
m_nKernelSearch = 0;
// Initialize operational flags
m_nOptionDefault = 0;
m_nOption = 0;
ASSERT(g_nOption == 0);
// Number of registered drives are 0
m_nUnits = 0;
}
//---------------------------------------------------------------------------
//
/// Reset (close all)
@ -2678,7 +2607,6 @@ CFileSys::CFileSys()
//---------------------------------------------------------------------------
void CFileSys::Reset()
{
// Initialize virtual sectors
m_nHostSectorCount = 0;
memset(m_nHostSectorBuffer, 0, sizeof(m_nHostSectorBuffer));
@ -2707,7 +2635,6 @@ void CFileSys::Reset()
//---------------------------------------------------------------------------
void CFileSys::Init()
{
// Initialize file search memory (device startup and load)
m_cFiles.Init();
@ -2755,7 +2682,6 @@ void CFileSys::Init()
//---------------------------------------------------------------------------
DWORD CFileSys::InitDevice(const Human68k::argument_t* pArgument)
{
InitOption(pArgument);
// File system initialization
@ -2769,12 +2695,12 @@ DWORD CFileSys::InitDevice(const Human68k::argument_t* pArgument)
/// $41 - Directory check
//
//---------------------------------------------------------------------------
int CFileSys::CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests)
int CFileSys::CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_INVALIDFUNC; // Avoid triggering a fatal error in mint when resuming with an invalid drive
@ -2796,12 +2722,12 @@ int CFileSys::CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests)
/// $42 - Create directory
//
//---------------------------------------------------------------------------
int CFileSys::MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests)
int CFileSys::MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -2838,12 +2764,12 @@ int CFileSys::MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests)
/// $43 - Delete directory
//
//---------------------------------------------------------------------------
int CFileSys::RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests)
int CFileSys::RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -2888,12 +2814,12 @@ int CFileSys::RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests)
/// $44 - Change file name
//
//---------------------------------------------------------------------------
int CFileSys::Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Human68k::namests_t* pNamestsNew)
int CFileSys::Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Human68k::namests_t* pNamestsNew) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -2946,12 +2872,12 @@ int CFileSys::Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Hum
/// $45 - Delete file
//
//---------------------------------------------------------------------------
int CFileSys::Delete(DWORD nUnit, const Human68k::namests_t* pNamests)
int CFileSys::Delete(DWORD nUnit, const Human68k::namests_t* pNamests) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -2986,12 +2912,12 @@ int CFileSys::Delete(DWORD nUnit, const Human68k::namests_t* pNamests)
/// $46 - Get/set file attribute
//
//---------------------------------------------------------------------------
int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD nHumanAttribute)
int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD nHumanAttribute) const
{
ASSERT(pNamests);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3020,9 +2946,8 @@ int CFileSys::Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD
return FS_FATAL_WRITEPROTECT;
// Generate attribute
DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) |
(f.GetAttribute() & ~Human68k::AT_READONLY);
if (f.GetAttribute() != nAttribute) {
if (DWORD nAttribute = (nHumanAttribute & Human68k::AT_READONLY) | (f.GetAttribute() & ~Human68k::AT_READONLY);
f.GetAttribute() != nAttribute) {
struct stat sb; //NOSONAR Cannot be declared in a separate statement because struct keyword is required
if (stat(S2U(f.GetPath()), &sb))
return FS_FILENOTFND;
@ -3065,7 +2990,7 @@ int CFileSys::Files(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests
}
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3150,7 +3075,7 @@ int CFileSys::NFiles(DWORD nUnit, DWORD nKey, Human68k::files_t* pFiles)
ASSERT(pFiles);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3195,7 +3120,7 @@ int CFileSys::Create(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamest
ASSERT(pFcb);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -3263,7 +3188,7 @@ int CFileSys::Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests,
ASSERT(pFcb);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3327,12 +3252,12 @@ int CFileSys::Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests,
/// $4B - File close
//
//---------------------------------------------------------------------------
int CFileSys::Close(DWORD nUnit, DWORD nKey, Human68k::fcb_t* /* pFcb */)
int CFileSys::Close(DWORD nUnit, DWORD nKey, const Human68k::fcb_t* /* pFcb */)
{
ASSERT(nKey);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3508,7 +3433,7 @@ DWORD CFileSys::TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD
return ((DWORD)pFcb->date << 16) | pFcb->time;
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -3551,7 +3476,7 @@ int CFileSys::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const
ASSERT(pCapacity);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -3570,12 +3495,12 @@ int CFileSys::GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const
/// $51 - Inspect/control drive status
//
//---------------------------------------------------------------------------
int CFileSys::CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive)
int CFileSys::CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive) const
{
ASSERT(pCtrlDrive);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_INVALIDFUNC; // Avoid triggering a fatal error in mint when resuming with an invalid drive
@ -3618,7 +3543,7 @@ int CFileSys::GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb) const
ASSERT(pDpb);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
Human68k::capacity_t cap;
@ -3698,7 +3623,7 @@ int CFileSys::DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize)
ASSERT(pBuffer);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_FATAL_MEDIAOFFLINE; // This occurs when resuming with an invalid drive
@ -3778,7 +3703,7 @@ int CFileSys::DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize)
int CFileSys::DiskWrite(DWORD nUnit) const
{
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -3806,7 +3731,7 @@ int CFileSys::Ioctrl(DWORD nUnit, DWORD nFunction, Human68k::ioctrl_t* pIoctrl)
ASSERT(pIoctrl);
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_INVALIDFUNC; // Avoid triggering a fatal error in mint when resuming with an invalid drive
@ -3870,7 +3795,7 @@ int CFileSys::Flush(DWORD nUnit) const
{
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_INVALIDFUNC; // Avoid triggering a fatal error returning from a mint command when resuming with an invalid drive
@ -3888,7 +3813,7 @@ int CFileSys::CheckMedia(DWORD nUnit) const
{
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
if (nUnit >= m_nUnits)
return FS_INVALIDFUNC; // Avoid triggering a fatal error in mint when resuming with an invalid drive
@ -3911,7 +3836,7 @@ int CFileSys::Lock(DWORD nUnit) const
{
// Unit check
if (nUnit >= DriveMax)
if (nUnit >= CHostEntry::DRIVE_MAX)
return FS_FATAL_INVALIDUNIT;
ASSERT(nUnit < m_nUnits);
if (nUnit >= m_nUnits)
@ -3971,7 +3896,7 @@ void CFileSys::InitOption(const Human68k::argument_t* pArgument)
nMode = 0;
} else if (c == '/') {
// Specify default base path
if (m_nDrives < DriveMax) {
if (m_nDrives < CHostEntry::DRIVE_MAX) {
p--;
strcpy(m_szBase[m_nDrives], (const char *)p);
m_nDrives++;
@ -4032,7 +3957,7 @@ void CFileSys::InitOption(const Human68k::argument_t* pArgument)
/// Get volume label
//
//---------------------------------------------------------------------------
BOOL CFileSys::FilesVolume(DWORD nUnit, Human68k::files_t* pFiles)
BOOL CFileSys::FilesVolume(DWORD nUnit, Human68k::files_t* pFiles) const
{
ASSERT(pFiles);

View File

@ -18,47 +18,47 @@
// Status code definitions
//
//---------------------------------------------------------------------------
#define FS_INVALIDFUNC 0xFFFFFFFF ///< Executed an invalid function
#define FS_FILENOTFND 0xFFFFFFFE ///< The selected file can not be found
#define FS_DIRNOTFND 0xFFFFFFFD ///< The selected directory can not be found
#define FS_OVEROPENED 0xFFFFFFFC ///< There are too many files open
#define FS_CANTACCESS 0xFFFFFFFB ///< Can not access the direcory or volume
#define FS_NOTOPENED 0xFFFFFFFA ///< The selected handle is not opened
#define FS_INVALIDMEM 0xFFFFFFF9 ///< Memory management has been destroyed
#define FS_OUTOFMEM 0xFFFFFFF8 ///< Insufficient memory for execution
#define FS_INVALIDPTR 0xFFFFFFF7 ///< Selected an invalid memory management pointer
#define FS_INVALIDENV 0xFFFFFFF6 ///< Selected an invalid environment
#define FS_ILLEGALFMT 0xFFFFFFF5 ///< The exeucted file is in an invalid format
#define FS_ILLEGALMOD 0xFFFFFFF4 ///< Invalid open access mode
#define FS_INVALIDPATH 0xFFFFFFF3 ///< Mistake in selected file name
#define FS_INVALIDPRM 0xFFFFFFF2 ///< Called with an invalid parameter
#define FS_INVALIDDRV 0xFFFFFFF1 ///< Mistake in selected drive
#define FS_DELCURDIR 0xFFFFFFF0 ///< Unable to delete the current directory
#define FS_NOTIOCTRL 0xFFFFFFEF ///< Unable to use IOCTRL with the device
#define FS_LASTFILE 0xFFFFFFEE ///< Can not find any more files
#define FS_CANTWRITE 0xFFFFFFED ///< Selected file can not be written
#define FS_DIRALREADY 0xFFFFFFEC ///< Selected directory is already registered
#define FS_CANTDELETE 0xFFFFFFEB ///< Can not delete because of a file
#define FS_CANTRENAME 0xFFFFFFEA ///< Can not rename because of a file
#define FS_DISKFULL 0xFFFFFFE9 ///< Can not create a file because the disk is full
#define FS_DIRFULL 0xFFFFFFE8 ///< Can not create a file because the directory is full
#define FS_CANTSEEK 0xFFFFFFE7 ///< Can not seek in the selected location
#define FS_SUPERVISOR 0xFFFFFFE6 ///< Selected supervisor in supervisor mode
#define FS_THREADNAME 0xFFFFFFE5 ///< A thread with this name already exists
#define FS_BUFWRITE 0xFFFFFFE4 ///< Writing to inter-process communication buffers is disallowed
#define FS_BACKGROUND 0xFFFFFFE3 ///< Unable to start a background process
#define FS_OUTOFLOCK 0xFFFFFFE0 ///< Insufficient lock space
#define FS_LOCKED 0xFFFFFFDF ///< Can not access because it is locked
#define FS_DRIVEOPENED 0xFFFFFFDE ///< Selected drive has an open handler
#define FS_LINKOVER 0xFFFFFFDD ///< The symbolic link is nested over 16 times
#define FS_FILEEXIST 0xFFFFFFB0 ///< The file exists
static const int FS_INVALIDFUNC = 0xFFFFFFFF; ///< Executed an invalid function
static const int FS_FILENOTFND = 0xFFFFFFFE; ///< The selected file can not be found
static const int FS_DIRNOTFND = 0xFFFFFFFD; ///< The selected directory can not be found
static const int FS_OVEROPENED = 0xFFFFFFFC; ///< There are too many files open
static const int FS_CANTACCESS = 0xFFFFFFFB; ///< Can not access the direcory or volume
static const int FS_NOTOPENED = 0xFFFFFFFA; ///< The selected handle is not opened
static const int FS_INVALIDMEM = 0xFFFFFFF9; ///< Memory management has been destroyed
static const int FS_OUTOFMEM = 0xFFFFFFF8; ///< Insufficient memory for execution
static const int FS_INVALIDPTR = 0xFFFFFFF7; ///< Selected an invalid memory management pointer
static const int FS_INVALIDENV = 0xFFFFFFF6; ///< Selected an invalid environment
static const int FS_ILLEGALFMT = 0xFFFFFFF5; ///< The exeucted file is in an invalid format
static const int FS_ILLEGALMOD = 0xFFFFFFF4; ///< Invalid open access mode
static const int FS_INVALIDPATH = 0xFFFFFFF3; ///< Mistake in selected file name
static const int FS_INVALIDPRM = 0xFFFFFFF2; ///< Called with an invalid parameter
static const int FS_INVALIDDRV = 0xFFFFFFF1; ///< Mistake in selected drive
static const int FS_DELCURDIR = 0xFFFFFFF0; ///< Unable to delete the current directory
static const int FS_NOTIOCTRL = 0xFFFFFFEF; ///< Unable to use IOCTRL with the device
static const int FS_LASTFILE = 0xFFFFFFEE; ///< Can not find any more files
static const int FS_CANTWRITE = 0xFFFFFFED; ///< Selected file can not be written
static const int FS_DIRALREADY = 0xFFFFFFEC; ///< Selected directory is already registered
static const int FS_CANTDELETE = 0xFFFFFFEB; ///< Can not delete because of a file
static const int FS_CANTRENAME = 0xFFFFFFEA; ///< Can not rename because of a file
static const int FS_DISKFULL = 0xFFFFFFE9; ///< Can not create a file because the disk is full
static const int FS_DIRFULL = 0xFFFFFFE8; ///< Can not create a file because the directory is full
static const int FS_CANTSEEK = 0xFFFFFFE7; ///< Can not seek in the selected location
static const int FS_SUPERVISOR = 0xFFFFFFE6; ///< Selected supervisor in supervisor mode
static const int FS_THREADNAME = 0xFFFFFFE5; ///< A thread with this name already exists
static const int FS_BUFWRITE = 0xFFFFFFE4; ///< Writing to inter-process communication buffers is disallowed
static const int FS_BACKGROUND = 0xFFFFFFE3; ///< Unable to start a background process
static const int FS_OUTOFLOCK = 0xFFFFFFE0; ///< Insufficient lock space
static const int FS_LOCKED = 0xFFFFFFDF; ///< Can not access because it is locked
static const int FS_DRIVEOPENED = 0xFFFFFFDE; ///< Selected drive has an open handler
static const int FS_LINKOVER = 0xFFFFFFDD; ///< The symbolic link is nested over 16 times
static const int FS_FILEEXIST = 0xFFFFFFB0; ///< The file exists
#define FS_FATAL_MEDIAOFFLINE 0xFFFFFFA3 ///< No media inserted
#define FS_FATAL_WRITEPROTECT 0xFFFFFFA2 ///< Write protected
#define FS_FATAL_INVALIDCOMMAND 0xFFFFFFA1 ///< Invalid command number
#define FS_FATAL_INVALIDUNIT 0xFFFFFFA0 ///< Invalid unit number
static const int FS_FATAL_MEDIAOFFLINE = 0xFFFFFFA3; ///< No media inserted
static const int FS_FATAL_WRITEPROTECT = 0xFFFFFFA2; ///< Write protected
static const int FS_FATAL_INVALIDCOMMAND = 0xFFFFFFA1; ///< Invalid command number
static const int FS_FATAL_INVALIDUNIT = 0xFFFFFFA0; ///< Invalid unit number
#define HUMAN68K_PATH_MAX 96 ///< Longest path allowed in Human68k
static const int HUMAN68K_PATH_MAX = 96; ///< Longest path allowed in Human68k
//===========================================================================
//
@ -236,7 +236,7 @@ deeply in the system, which is why this value is set this high.
Default is 20 buffers.
*/
#define XM6_HOST_FILES_MAX 20
static const int XM6_HOST_FILES_MAX = 20;
/// Number of FCB buffers
/**
@ -244,7 +244,7 @@ This decides how many files can be opened at the same time.
Default is 100 files.
*/
#define XM6_HOST_FCB_MAX 100
static const int XM6_HOST_FCB_MAX = 100;
/// Max number of virtual clusters and sectors
/**
@ -253,7 +253,7 @@ Allocating a generous amount to exceed the number of threads lzdsys uses for acc
Default is 10 sectors.
*/
#define XM6_HOST_PSEUDO_CLUSTER_MAX 10
static const int XM6_HOST_PSEUDO_CLUSTER_MAX = 10;
/// Number of caches for directory entries
/**
@ -264,7 +264,7 @@ and the host OS gets under a heavy load, so be careful.
Default is 16.
*/
#define XM6_HOST_DIRENTRY_CACHE_MAX 16
static const int XM6_HOST_DIRENTRY_CACHE_MAX = 16;
/// Max number of entries that can be stored per directory
/**
@ -276,7 +276,7 @@ file manager, the upper limit is 2560 files. This is one good example to use as
Default is around 60000 entries. (Upper limit of the FAT root directory)
*/
#define XM6_HOST_DIRENTRY_FILE_MAX 65535
static const int XM6_HOST_DIRENTRY_FILE_MAX = 65535;
/// Max number of patterns for file name deduplication
/**
@ -295,7 +295,7 @@ only the first entry will ever be accessed.
Default is 36 patterns.
*/
#define XM6_HOST_FILENAME_PATTERN_MAX 36
static const int XM6_HOST_FILENAME_PATTERN_MAX = 36;
/// Duplicate file identification mark
/**
@ -304,7 +304,7 @@ Do not use a command shell escape character, or similar protected symbol.
Default is '@'.
*/
#define XM6_HOST_FILENAME_MARK '@'
static const char XM6_HOST_FILENAME_MARK = '@';
/// WINDRV operational flags
/**
@ -440,47 +440,51 @@ private:
//===========================================================================
class CHostFilename {
public:
CHostFilename();
static size_t Offset() { return offsetof(CHostFilename, m_szHost); } ///< Get offset location
CHostFilename() = default;
~CHostFilename() = default;
CHostFilename(CHostFilename&) = delete;
CHostFilename& operator=(const CHostFilename&) = delete;
void SetHost(const TCHAR* szHost); ///< Set the name of the host
const TCHAR* GetHost() const { return m_szHost; } ///< Get the name of the host
void ConvertHuman(int nCount = -1); ///< Convert the Human68k name
void CopyHuman(const BYTE* szHuman); ///< Copy the Human68k name
BOOL isReduce() const; ///< Inspect if the Human68k name is generated
BOOL isCorrect() const { return m_bCorrect; } ///< Inspect if the Human68k file name adhers to naming rules
const BYTE* GetHuman() const { return m_szHuman; } ///< Get Human68k file name
const BYTE* GetHumanLast() const
static size_t Offset() { return offsetof(CHostFilename, m_szHost); } ///< Get offset location
void SetHost(const TCHAR* szHost); ///< Set the name of the host
const TCHAR* GetHost() const { return m_szHost; } ///< Get the name of the host
void ConvertHuman(int nCount = -1); ///< Convert the Human68k name
void CopyHuman(const BYTE* szHuman); ///< Copy the Human68k name
BOOL isReduce() const; ///< Inspect if the Human68k name is generated
BOOL isCorrect() const { return m_bCorrect; } ///< Inspect if the Human68k file name adhers to naming rules
const BYTE* GetHuman() const { return m_szHuman; } ///< Get Human68k file name
const BYTE* GetHumanLast() const
{ return m_pszHumanLast; } ///< Get Human68k file name
const BYTE* GetHumanExt() const { return m_pszHumanExt; }///< Get Human68k file name
void SetEntryName(); ///< Set Human68k directory entry
void SetEntryAttribute(BYTE nHumanAttribute)
const BYTE* GetHumanExt() const { return m_pszHumanExt; }///< Get Human68k file name
void SetEntryName(); ///< Set Human68k directory entry
void SetEntryAttribute(BYTE nHumanAttribute)
{ m_dirHuman.attr = nHumanAttribute; } ///< Set Human68k directory entry
void SetEntrySize(DWORD nHumanSize)
{ m_dirHuman.size = nHumanSize; } ///< Set Human68k directory entry
void SetEntryDate(WORD nHumanDate)
void SetEntryDate(WORD nHumanDate)
{ m_dirHuman.date = nHumanDate; } ///< Set Human68k directory entry
void SetEntryTime(WORD nHumanTime)
void SetEntryTime(WORD nHumanTime)
{ m_dirHuman.time = nHumanTime; } ///< Set Human68k directory entry
void SetEntryCluster(WORD nHumanCluster)
void SetEntryCluster(WORD nHumanCluster)
{ m_dirHuman.cluster = nHumanCluster; } ///< Set Human68k directory entry
const Human68k::dirent_t* GetEntry() const
{ return &m_dirHuman; } ///< Get Human68k directory entry
BOOL CheckAttribute(DWORD nHumanAttribute) const; ///< Determine Human68k directory entry attributes
BOOL isSameEntry(const Human68k::dirent_t* pdirHuman) const
BOOL CheckAttribute(DWORD nHumanAttribute) const; ///< Determine Human68k directory entry attributes
BOOL isSameEntry(const Human68k::dirent_t* pdirHuman) const
{ ASSERT(pdirHuman); return memcmp(&m_dirHuman, pdirHuman, sizeof(m_dirHuman)) == 0; }
///< Determine Human68k directory entry match
// Path name operations
static const BYTE* SeparateExt(const BYTE* szHuman); ///< Extract extension from Human68k file name
static const BYTE* SeparateExt(const BYTE* szHuman); ///< Extract extension from Human68k file name
private:
static BYTE* CopyName(BYTE* pWrite, const BYTE* pFirst, const BYTE* pLast);
static BYTE* CopyName(BYTE* pWrite, const BYTE* pFirst, const BYTE* pLast);
///< Copy Human68k file name elements
const BYTE* m_pszHumanLast; ///< Last position of the Human68k internal name of the relevant entry
const BYTE* m_pszHumanExt; ///< Position of the extension of the Human68k internal name of the relevant entry
BOOL m_bCorrect; ///< TRUE if the relevant entry of the Human68k internal name is correct
const BYTE* m_pszHumanLast = nullptr; ///< Last position of the Human68k internal name of the relevant entry
const BYTE* m_pszHumanExt = nullptr; ///< Position of the extension of the Human68k internal name of the relevant entry
BOOL m_bCorrect = FALSE; ///< TRUE if the relevant entry of the Human68k internal name is correct
BYTE m_szHuman[24]; ///< Human68k internal name of the relevant entry
Human68k::dirent_t m_dirHuman; ///< All information for the Human68k relevant entry
TCHAR m_szHost[FILEPATH_MAX]; ///< The host name of the relevant entry (variable length)
@ -526,7 +530,7 @@ public:
void Clear() { count = 0; } ///< Initialize
};
CHostPath();
CHostPath() = default;
~CHostPath();
CHostPath(CHostPath&) = delete;
CHostPath& operator=(const CHostPath&) = delete;
@ -558,9 +562,9 @@ private:
///< Compare string (with support for wildcards)
CRing m_cRing; ///< For CHostFilename linking
time_t m_tBackup; ///< For time stamp restoration
BOOL m_bRefresh; ///< Refresh flag
DWORD m_nId; ///< Unique ID (When the value has changed, it means an update has been made)
time_t m_tBackup = FALSE; ///< For time stamp restoration
BOOL m_bRefresh = TRUE; ///< Refresh flag
DWORD m_nId = 0; ///< Unique ID (When the value has changed, it means an update has been made)
BYTE m_szHuman[HUMAN68K_PATH_MAX]; ///< The internal Human68k name for the relevant entry
TCHAR m_szHost[FILEPATH_MAX]; ///< The host side name for the relevant entry
@ -590,47 +594,50 @@ private:
//===========================================================================
class CHostFiles {
public:
CHostFiles() { SetKey(0); }
void Init();
CHostFiles() = default;
~CHostFiles() = default;
CHostFiles(CHostFiles&) = delete;
CHostFiles& operator=(const CHostFiles&) = delete;
void SetKey(DWORD nKey) { m_nKey = nKey; } ///< Set search key
BOOL isSameKey(DWORD nKey) const { return m_nKey == nKey; } ///< Compare search key
void SetPath(const Human68k::namests_t* pNamests); ///< Create path and file name internally
BOOL isRootPath() const { return m_szHumanPath[1] == '\0'; } ///< Check if root directory
void SetPathWildcard() { m_nHumanWildcard = 1; } ///< Enable file search using wildcards
void SetPathOnly() { m_nHumanWildcard = 0xFF; } ///< Enable only path names
BOOL isPathOnly() const { return m_nHumanWildcard == 0xFF; } ///< Check if set to only path names
void SetAttribute(DWORD nHumanAttribute) { m_nHumanAttribute = nHumanAttribute; } ///< Set search attribute
BOOL Find(DWORD nUnit, class CHostEntry* pEntry) ; ///< Find files on the Human68k side, generating data on the host side
const CHostFilename* Find(CHostPath* pPath); ///< Find file name
void SetEntry(const CHostFilename* pFilename); ///< Store search results on the Human68k side
void SetResult(const TCHAR* szPath); ///< Set names on the host side
void AddResult(const TCHAR* szPath); ///< Add file name to the name on the host side
void AddFilename(); ///< Add the new Human68k file name to the name on the host side
void Init();
const TCHAR* GetPath() const { return m_szHostResult; } ///< Get the name on the host side
void SetKey(DWORD nKey) { m_nKey = nKey; } ///< Set search key
BOOL isSameKey(DWORD nKey) const { return m_nKey == nKey; } ///< Compare search key
void SetPath(const Human68k::namests_t* pNamests); ///< Create path and file name internally
BOOL isRootPath() const { return m_szHumanPath[1] == '\0'; } ///< Check if root directory
void SetPathWildcard() { m_nHumanWildcard = 1; } ///< Enable file search using wildcards
void SetPathOnly() { m_nHumanWildcard = 0xFF; } ///< Enable only path names
BOOL isPathOnly() const { return m_nHumanWildcard == 0xFF; } ///< Check if set to only path names
void SetAttribute(DWORD nHumanAttribute) { m_nHumanAttribute = nHumanAttribute; } ///< Set search attribute
BOOL Find(DWORD nUnit, const class CHostEntry* pEntry); ///< Find files on the Human68k side, generating data on the host side
const CHostFilename* Find(const CHostPath* pPath); ///< Find file name
void SetEntry(const CHostFilename* pFilename); ///< Store search results on the Human68k side
void SetResult(const TCHAR* szPath); ///< Set names on the host side
void AddResult(const TCHAR* szPath); ///< Add file name to the name on the host side
void AddFilename(); ///< Add the new Human68k file name to the name on the host side
const Human68k::dirent_t* GetEntry() const { return &m_dirHuman; }///< Get Human68k directory entry
const TCHAR* GetPath() const { return m_szHostResult; } ///< Get the name on the host side
DWORD GetAttribute() const { return m_dirHuman.attr; } ///< Get Human68k attribute
WORD GetDate() const { return m_dirHuman.date; } ///< Get Human68k date
WORD GetTime() const { return m_dirHuman.time; } ///< Get Human68k time
DWORD GetSize() const { return m_dirHuman.size; } ///< Get Human68k file size
const BYTE* GetHumanFilename() const { return m_szHumanFilename; }///< Get Human68k file name
const BYTE* GetHumanResult() const { return m_szHumanResult; } ///< Get Human68k file name search results
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
const Human68k::dirent_t* GetEntry() const { return &m_dirHuman; }///< Get Human68k directory entry
DWORD GetAttribute() const { return m_dirHuman.attr; } ///< Get Human68k attribute
WORD GetDate() const { return m_dirHuman.date; } ///< Get Human68k date
WORD GetTime() const { return m_dirHuman.time; } ///< Get Human68k time
DWORD GetSize() const { return m_dirHuman.size; } ///< Get Human68k file size
const BYTE* GetHumanFilename() const { return m_szHumanFilename; }///< Get Human68k file name
const BYTE* GetHumanResult() const { return m_szHumanResult; } ///< Get Human68k file name search results
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
private:
DWORD m_nKey; ///< FILES buffer address for Human68k; 0 is unused
DWORD m_nHumanWildcard; ///< Human68k wildcard data
DWORD m_nHumanAttribute; ///< Human68k search attribute
CHostPath::find_t m_findNext; ///< Next search location data
Human68k::dirent_t m_dirHuman; ///< Search results: Human68k file data
BYTE m_szHumanFilename[24]; ///< Human68k file name
BYTE m_szHumanResult[24]; ///< Search results: Human68k file name
BYTE m_szHumanPath[HUMAN68K_PATH_MAX];
///< Human68k path name
TCHAR m_szHostResult[FILEPATH_MAX]; ///< Search results: host's full path name
DWORD m_nKey = 0; ///< FILES buffer address for Human68k; 0 is unused
DWORD m_nHumanWildcard = 0; ///< Human68k wildcard data
DWORD m_nHumanAttribute = 0; ///< Human68k search attribute
CHostPath::find_t m_findNext = {}; ///< Next search location data
Human68k::dirent_t m_dirHuman = {}; ///< Search results: Human68k file data
BYTE m_szHumanFilename[24] = {}; ///< Human68k file name
BYTE m_szHumanResult[24] = {}; ///< Search results: Human68k file name
BYTE m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
TCHAR m_szHostResult[FILEPATH_MAX] = {}; ///< Search results: host's full path name
};
//===========================================================================
@ -666,41 +673,40 @@ private:
//===========================================================================
class CHostFcb {
public:
CHostFcb() { SetKey(0); Init(); }
CHostFcb() = default;
~CHostFcb() { Close(); }
CHostFcb(CHostFcb&) = delete;
CHostFcb& operator=(const CHostFcb&) = delete;
void Init();
void Init();
void SetKey(DWORD nKey) { m_nKey = nKey; } ///< Set search key
BOOL isSameKey(DWORD nKey) const { return m_nKey == nKey; } ///< Compare search key
void SetUpdate() { m_bUpdate = TRUE; } ///< Update
BOOL isUpdate() const { return m_bUpdate; } ///< Get update state
BOOL SetMode(DWORD nHumanMode); ///< Set file open mode
void SetFilename(const TCHAR* szFilename); ///< Set file name
void SetHumanPath(const BYTE* szHumanPath); ///< Set Human68k path name
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
void SetKey(DWORD nKey) { m_nKey = nKey; } ///< Set search key
BOOL isSameKey(DWORD nKey) const { return m_nKey == nKey; } ///< Compare search key
void SetUpdate() { m_bUpdate = TRUE; } ///< Update
BOOL isUpdate() const { return m_bUpdate; } ///< Get update state
BOOL SetMode(DWORD nHumanMode); ///< Set file open mode
void SetFilename(const TCHAR* szFilename); ///< Set file name
void SetHumanPath(const BYTE* szHumanPath); ///< Set Human68k path name
const BYTE* GetHumanPath() const { return m_szHumanPath; } ///< Get Human68k path name
BOOL Create(DWORD nHumanAttribute, BOOL bForce); ///< Create file
BOOL Open(); ///< Open file
BOOL Rewind(DWORD nOffset) const; ///< Seek file
DWORD Read(BYTE* pBuffer, DWORD nSize); ///< Read file
DWORD Write(const BYTE* pBuffer, DWORD nSize); ///< Write file
BOOL Truncate() const; ///< Truncate file
DWORD Seek(DWORD nOffset, DWORD nHumanSeek); ///< Seek file
BOOL TimeStamp(DWORD nHumanTime) const; ///< Set file time stamp
BOOL Close(); ///< Close file
BOOL Create(DWORD nHumanAttribute, BOOL bForce); ///< Create file
BOOL Open(); ///< Open file
BOOL Rewind(DWORD nOffset) const; ///< Seek file
DWORD Read(BYTE* pBuffer, DWORD nSize); ///< Read file
DWORD Write(const BYTE* pBuffer, DWORD nSize); ///< Write file
BOOL Truncate() const; ///< Truncate file
DWORD Seek(DWORD nOffset, DWORD nHumanSeek); ///< Seek file
BOOL TimeStamp(DWORD nHumanTime) const; ///< Set file time stamp
BOOL Close(); ///< Close file
private:
DWORD m_nKey; ///< Human68k FCB buffer address (0 if unused)
BOOL m_bUpdate; ///< Update flag
FILE* m_pFile; ///< Host side file object
const char* m_pszMode; ///< Host side file open mode
bool m_bFlag; ///< Host side file open flag
BYTE m_szHumanPath[HUMAN68K_PATH_MAX];
///< Human68k path name
TCHAR m_szFilename[FILEPATH_MAX]; ///< Host side file name
DWORD m_nKey = 0; ///< Human68k FCB buffer address (0 if unused)
BOOL m_bUpdate = FALSE; ///< Update flag
FILE* m_pFile = nullptr; ///< Host side file object
const char* m_pszMode = nullptr; ///< Host side file open mode
bool m_bFlag = false; ///< Host side file open flag
BYTE m_szHumanPath[HUMAN68K_PATH_MAX] = {}; ///< Human68k path name
TCHAR m_szFilename[FILEPATH_MAX] = {}; ///< Host side file name
};
//===========================================================================
@ -714,7 +720,7 @@ public:
~CHostFcbManager();
#endif // _DEBUG
void Init(); ///< Initialization (when the driver is installed)
void Clean(); ///< Release (when starting up or resetting)
void Clean() const; ///< Release (when starting up or resetting)
CHostFcb* Alloc(DWORD nKey);
CHostFcb* Search(DWORD nKey);
@ -740,36 +746,36 @@ private:
class CHostDrv
{
public:
CHostDrv();
CHostDrv() = default;
~CHostDrv();
CHostDrv(CHostDrv&) = delete;
CHostDrv& operator=(const CHostDrv&) = delete;
void Init(const TCHAR* szBase, DWORD nFlag); ///< Initialization (device startup and load)
void Init(const TCHAR* szBase, DWORD nFlag); ///< Initialization (device startup and load)
BOOL isWriteProtect() const { return m_bWriteProtect; }
BOOL isEnable() const { return m_bEnable; } ///< Is it accessible?
BOOL isMediaOffline() const;
BYTE GetMediaByte() const;
DWORD GetStatus() const;
void SetEnable(BOOL bEnable); ///< Set media status
BOOL isWriteProtect() const { return m_bWriteProtect; }
BOOL isEnable() const { return m_bEnable; } ///< Is it accessible?
BOOL isMediaOffline() const;
BYTE GetMediaByte() const;
DWORD GetStatus() const;
void SetEnable(BOOL bEnable); ///< Set media status
BOOL CheckMedia(); ///< Check if media was changed
void Update(); ///< Update media status
void Eject();
void GetVolume(TCHAR* szLabel); ///< Get volume label
BOOL GetVolumeCache(TCHAR* szLabel) const; ///< Get volume label from cache
DWORD GetCapacity(Human68k::capacity_t* pCapacity);
BOOL GetCapacityCache(Human68k::capacity_t* pCapacity) const; ///< Get capacity from cache
void GetVolume(TCHAR* szLabel); ///< Get volume label
BOOL GetVolumeCache(TCHAR* szLabel) const; ///< Get volume label from cache
DWORD GetCapacity(Human68k::capacity_t* pCapacity);
BOOL GetCapacityCache(Human68k::capacity_t* pCapacity) const; ///< Get capacity from cache
// Cache operations
void CleanCache() const; ///< Update all cache
void CleanCache(const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(const BYTE* szHumanPath) const; ///< Update all cache below the specified path
void DeleteCache(const BYTE* szHumanPath); ///< Delete the cache for the specified path
CHostPath* FindCache(const BYTE* szHuman); ///< Inspect if the specified path is cached
CHostPath* CopyCache(CHostFiles* pFiles); ///< Acquire the host side name on the basis of cache information
CHostPath* MakeCache(CHostFiles* pFiles); ///< Get all required data to construct a host side name
BOOL Find(CHostFiles* pFiles); ///< Find host side name (path + file name (can be abbreviated) + attribute)
void CleanCache() const; ///< Update all cache
void CleanCache(const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(const BYTE* szHumanPath) const; ///< Update all cache below the specified path
void DeleteCache(const BYTE* szHumanPath); ///< Delete the cache for the specified path
CHostPath* FindCache(const BYTE* szHuman); ///< Inspect if the specified path is cached
CHostPath* CopyCache(CHostFiles* pFiles); ///< Acquire the host side name on the basis of cache information
CHostPath* MakeCache(CHostFiles* pFiles); ///< Get all required data to construct a host side name
BOOL Find(CHostFiles* pFiles); ///< Find host side name (path + file name (can be abbreviated) + attribute)
private:
// Path name operations
@ -782,14 +788,14 @@ private:
CHostPath f;
};
BOOL m_bWriteProtect; ///< TRUE if write-protected
BOOL m_bEnable; ///< TRUE if media is usable
DWORD m_nRing; ///< Number of stored path names
BOOL m_bWriteProtect = FALSE; ///< TRUE if write-protected
BOOL m_bEnable = FALSE; ///< TRUE if media is usable
DWORD m_nRing = 0; ///< Number of stored path names
CRing m_cRing; ///< For attaching to CHostPath
Human68k::capacity_t m_capCache; ///< Sector data cache: if "sectors == 0" then not cached
BOOL m_bVolumeCache; ///< TRUE if the volume label has been read
TCHAR m_szVolumeCache[24]; ///< Volume label cache
TCHAR m_szBase[FILEPATH_MAX]; ///< Base path
BOOL m_bVolumeCache = FALSE; ///< TRUE if the volume label has been read
TCHAR m_szVolumeCache[24] = {}; ///< Volume label cache
TCHAR m_szBase[FILEPATH_MAX] = {}; ///< Base path
};
//===========================================================================
@ -798,46 +804,47 @@ private:
//
//===========================================================================
class CHostEntry {
public:
CHostEntry();
/// Max number of drive candidates
static const int DRIVE_MAX = 10;
CHostEntry() = default;
~CHostEntry();
CHostEntry(CHostEntry&) = delete;
CHostEntry& operator=(const CHostEntry&) = delete;
void Init(); ///< Initialization (when the driver is installed)
void Clean(); ///< Release (when starting up or resetting)
void Init() const; ///< Initialization (when the driver is installed)
void Clean(); ///< Release (when starting up or resetting)
// Cache operations
void CleanCache(); ///< Update all cache
void CleanCache(DWORD nUnit); ///< Update cache for the specified unit
void CleanCache(DWORD nUnit, const BYTE* szHumanPath); ///< Update cache for the specified path
void CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath); ///< Update cache below the specified path
void DeleteCache(DWORD nUnit, const BYTE* szHumanPath); ///< Delete cache for the specified path
BOOL Find(DWORD nUnit, CHostFiles* pFiles) const; ///< Find host side name (path + file name (can be abbreviated) + attribute)
void ShellNotify(DWORD nEvent, const TCHAR* szPath); ///< Notify status change in the host side file system
void CleanCache() const; ///< Update all cache
void CleanCache(DWORD nUnit) const; ///< Update cache for the specified unit
void CleanCache(DWORD nUnit, const BYTE* szHumanPath) const; ///< Update cache for the specified path
void CleanCacheChild(DWORD nUnit, const BYTE* szHumanPath) const; ///< Update cache below the specified path
void DeleteCache(DWORD nUnit, const BYTE* szHumanPath) const; ///< Delete cache for the specified path
BOOL Find(DWORD nUnit, CHostFiles* pFiles) const; ///< Find host side name (path + file name (can be abbreviated) + attribute)
void ShellNotify(DWORD nEvent, const TCHAR* szPath); ///< Notify status change in the host side file system
// Drive object operations
void SetDrv(DWORD nUnit, CHostDrv* pDrv);
BOOL isWriteProtect(DWORD nUnit) const;
BOOL isEnable(DWORD nUnit) const; ///< Is it accessible?
BOOL isMediaOffline(DWORD nUnit) const;
BYTE GetMediaByte(DWORD nUnit) const;
DWORD GetStatus(DWORD nUnit) const; ///< Get drive status
void SetDrv(DWORD nUnit, CHostDrv* pDrv);
BOOL isWriteProtect(DWORD nUnit) const;
BOOL isEnable(DWORD nUnit) const; ///< Is it accessible?
BOOL isMediaOffline(DWORD nUnit) const;
BYTE GetMediaByte(DWORD nUnit) const;
DWORD GetStatus(DWORD nUnit) const; ///< Get drive status
BOOL CheckMedia(DWORD nUnit) const; ///< Media change check
void Eject(DWORD nUnit);
void GetVolume(DWORD nUnit, TCHAR* szLabel); ///< Get volume label
BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; ///< Get volume label from cache
DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const;
BOOL GetCapacityCache(DWORD nUnit, Human68k::capacity_t* pCapacity) const;
///< Get cluster size from cache
enum {
DriveMax = 10 ///< Max number of drive candidates
};
void Eject(DWORD nUnit) const;
void GetVolume(DWORD nUnit, TCHAR* szLabel) const; ///< Get volume label
BOOL GetVolumeCache(DWORD nUnit, TCHAR* szLabel) const; ///< Get volume label from cache
DWORD GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const;
BOOL GetCapacityCache(DWORD nUnit, Human68k::capacity_t* pCapacity) const; ///< Get cluster size from cache
private:
CHostDrv* m_pDrv[DriveMax]; ///< Host side drive object
DWORD m_nTimeout; ///< Last time a timeout check was carried out
CHostDrv* m_pDrv[DRIVE_MAX] = {}; ///< Host side drive object
DWORD m_nTimeout = 0; ///< Last time a timeout check was carried out
};
//===========================================================================
@ -874,7 +881,7 @@ The easy solution is to put the content of 'class CFileSys' into 'class CWindrv'
class CFileSys
{
public:
CFileSys();
CFileSys() = default;
virtual ~CFileSys() = default;
void Reset(); ///< Reset (close all)
@ -882,13 +889,13 @@ public:
// Command handlers
DWORD InitDevice(const Human68k::argument_t* pArgument); ///< $40 - Device startup
int CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $41 - Directory check
int MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $42 - Create directory
int RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $43 - Delete directory
int Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Human68k::namests_t* pNamestsNew);
int CheckDir(DWORD nUnit, const Human68k::namests_t* pNamests) const; ///< $41 - Directory check
int MakeDir(DWORD nUnit, const Human68k::namests_t* pNamests) const; ///< $42 - Create directory
int RemoveDir(DWORD nUnit, const Human68k::namests_t* pNamests) const; ///< $43 - Delete directory
int Rename(DWORD nUnit, const Human68k::namests_t* pNamests, const Human68k::namests_t* pNamestsNew) const;
///< $44 - Change file name
int Delete(DWORD nUnit, const Human68k::namests_t* pNamests); ///< $45 - Delete file
int Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD nHumanAttribute);
int Delete(DWORD nUnit, const Human68k::namests_t* pNamests) const; ///< $45 - Delete file
int Attribute(DWORD nUnit, const Human68k::namests_t* pNamests, DWORD nHumanAttribute) const;
///< $46 - Get / set file attribute
int Files(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests, Human68k::files_t* pFiles);
///< $47 - Find file
@ -897,7 +904,7 @@ public:
///< $49 - Create file
int Open(DWORD nUnit, DWORD nKey, const Human68k::namests_t* pNamests, Human68k::fcb_t* pFcb);
///< $4A - Open file
int Close(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb); ///< $4B - Close file
int Close(DWORD nUnit, DWORD nKey, const Human68k::fcb_t* pFcb); ///< $4B - Close file
int Read(DWORD nKey, Human68k::fcb_t* pFcb, BYTE* pAddress, DWORD nSize);
///< $4C - Read file
int Write(DWORD nKey, Human68k::fcb_t* pFcb, const BYTE* pAddress, DWORD nSize);
@ -906,7 +913,7 @@ public:
DWORD TimeStamp(DWORD nUnit, DWORD nKey, Human68k::fcb_t* pFcb, DWORD nHumanTime);
///< $4F - Get / set file timestamp
int GetCapacity(DWORD nUnit, Human68k::capacity_t* pCapacity) const; ///< $50 - Get capacity
int CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive); ///< $51 - Inspect / control drive status
int CtrlDrive(DWORD nUnit, Human68k::ctrldrive_t* pCtrlDrive) const; ///< $51 - Inspect / control drive status
int GetDPB(DWORD nUnit, Human68k::dpb_t* pDpb) const; ///< $52 - Get DPB
int DiskRead(DWORD nUnit, BYTE* pBuffer, DWORD nSector, DWORD nSize); ///< $53 - Read sectors
int DiskWrite(DWORD nUnit) const; ///< $54 - Write sectors
@ -921,24 +928,24 @@ public:
static DWORD GetFileOption() { return g_nOption; } ///< Get file name change option
enum {
DriveMax = CHostEntry::DriveMax ///< Max number of drive candidates
DriveMax = CHostEntry::DRIVE_MAX ///< Max number of drive candidates
};
private:
void InitOption(const Human68k::argument_t* pArgument);
BOOL FilesVolume(DWORD nUnit, Human68k::files_t* pFiles); ///< Get volume label
BOOL FilesVolume(DWORD nUnit, Human68k::files_t* pFiles) const; ///< Get volume label
DWORD m_nUnits; ///< Number of current drive objects (Changes for every resume)
DWORD m_nUnits = 0; ///< Number of current drive objects (Changes for every resume)
DWORD m_nOption; ///< Current runtime flag
DWORD m_nOptionDefault; ///< Runtime flag at reset
DWORD m_nOption = 0; ///< Current runtime flag
DWORD m_nOptionDefault = 0; ///< Runtime flag at reset
DWORD m_nDrives; ///< Number of candidates for base path status restoration (scan every time if 0)
DWORD m_nDrives = 0; ///< Number of candidates for base path status restoration (scan every time if 0)
DWORD m_nKernel; ///< Counter for kernel check
DWORD m_nKernelSearch; ///< Initial address for NUL device
DWORD m_nKernel = 0; ///< Counter for kernel check
DWORD m_nKernelSearch = 0; ///< Initial address for NUL device
DWORD m_nHostSectorCount; ///< Virtual sector identifier
DWORD m_nHostSectorCount = 0; ///< Virtual sector identifier
CHostFilesManager m_cFiles; ///< File search memory
CHostFcbManager m_cFcb; ///< FCB operation memory
@ -947,7 +954,7 @@ private:
DWORD m_nHostSectorBuffer[XM6_HOST_PSEUDO_CLUSTER_MAX];
///< Entity that the virtual sector points to
DWORD m_nFlag[DriveMax]; ///< Candidate runtime flag for base path restoration
TCHAR m_szBase[DriveMax][FILEPATH_MAX]; ///< Candidate for base path restoration
DWORD m_nFlag[DriveMax] = {}; ///< Candidate runtime flag for base path restoration
TCHAR m_szBase[DriveMax][FILEPATH_MAX] = {}; ///< Candidate for base path restoration
static DWORD g_nOption; ///< File name change flag
};

View File

@ -25,7 +25,7 @@
#include "rascsi_exceptions.h"
#include <sstream>
#define BRIDGE_NAME "rascsi_bridge"
static const char *BRIDGE_NAME = "rascsi_bridge";
using namespace std;
using namespace ras_util;
@ -42,7 +42,7 @@ static bool br_setif(int br_socket_fd, const char* bridgename, const char* ifnam
LOGERROR("Can't if_nametoindex: %s", strerror(errno))
return false;
}
strncpy(ifr.ifr_name, bridgename, IFNAMSIZ);
strncpy(ifr.ifr_name, bridgename, IFNAMSIZ - 1);
if (ioctl(br_socket_fd, add ? SIOCBRADDIF : SIOCBRDELIF, &ifr) < 0) {
LOGERROR("Can't ioctl %s: %s", add ? "SIOCBRADDIF" : "SIOCBRDELIF", strerror(errno))
return false;
@ -70,7 +70,7 @@ static bool ip_link(int fd, const char* ifname, bool up) {
return true;
}
static bool is_interface_up(const string& interface) {
static bool is_interface_up(string_view interface) {
string file = "/sys/class/net/";
file += interface;
file += "/carrier";
@ -381,7 +381,8 @@ void CTapDriver::Cleanup()
}
}
bool CTapDriver::Enable(){
bool CTapDriver::Enable() const
{
int fd = socket(PF_INET, SOCK_DGRAM, 0);
LOGDEBUG("%s: ip link set ras0 up", __PRETTY_FUNCTION__)
bool result = ip_link(fd, "ras0", true);
@ -389,7 +390,8 @@ bool CTapDriver::Enable(){
return result;
}
bool CTapDriver::Disable(){
bool CTapDriver::Disable() const
{
int fd = socket(PF_INET, SOCK_DGRAM, 0);
LOGDEBUG("%s: ip link set ras0 down", __PRETTY_FUNCTION__)
bool result = ip_link(fd, "ras0", false);
@ -397,14 +399,15 @@ bool CTapDriver::Disable(){
return result;
}
void CTapDriver::Flush(){
void CTapDriver::Flush()
{
LOGTRACE("%s", __PRETTY_FUNCTION__)
while(PendingPackets()){
(void)Rx(m_garbage_buffer);
}
}
void CTapDriver::GetMacAddr(BYTE *mac)
void CTapDriver::GetMacAddr(BYTE *mac) const
{
ASSERT(mac);
@ -416,7 +419,7 @@ void CTapDriver::GetMacAddr(BYTE *mac)
// Receive
//
//---------------------------------------------------------------------------
bool CTapDriver::PendingPackets()
bool CTapDriver::PendingPackets() const
{
pollfd fds;
@ -436,7 +439,7 @@ bool CTapDriver::PendingPackets()
}
// See https://stackoverflow.com/questions/21001659/crc32-algorithm-implementation-in-c-without-a-look-up-table-and-with-a-public-li
uint32_t crc32(BYTE *buf, int length) {
uint32_t crc32(const BYTE *buf, int length) {
uint32_t crc = 0xffffffff;
for (int i = 0; i < length; i++) {
crc ^= buf[i];

View File

@ -49,12 +49,12 @@ public:
void OpenDump(const Filepath& path);
// Capture packets
void Cleanup(); // Cleanup
void GetMacAddr(BYTE *mac); // Get Mac Address
int Rx(BYTE *buf); // Receive
int Tx(const BYTE *buf, int len); // Send
bool PendingPackets(); // Check if there are IP packets available
bool Enable(); // Enable the ras0 interface
bool Disable(); // Disable the ras0 interface
void GetMacAddr(BYTE *mac) const; // Get Mac Address
int Rx(BYTE *buf); // Receive
int Tx(const BYTE *buf, int len); // Send
bool PendingPackets() const; // Check if there are IP packets available
bool Enable() const; // Enable the ras0 interface
bool Disable() const; // Disable the ras0 interface
void Flush(); // Purge all of the packets that are waiting to be processed
private:

View File

@ -14,14 +14,10 @@
#include "rascsi_exceptions.h"
#include "device.h"
unordered_set<Device *> Device::devices;
Device::Device(const string& t) : type(t)
{
assert(type.length() == 4);
devices.insert(this);
char rev[5];
sprintf(rev, "%02d%02d", rascsi_major_version, rascsi_minor_version);
revision = rev;

View File

@ -10,7 +10,6 @@
#pragma once
#include "scsi.h"
#include <unordered_set>
#include <unordered_map>
#include <string>
@ -87,8 +86,6 @@ protected:
string GetParam(const string&) const;
void SetParams(const unordered_map<string, string>&);
static unordered_set<Device *> devices;
explicit Device(const string&);
public:

View File

@ -22,7 +22,7 @@
using namespace std;
using namespace rascsi_interface;
multimap<int, Device *> DeviceFactory::devices;
multimap<int, unique_ptr<PrimaryDevice>> DeviceFactory::devices;
DeviceFactory::DeviceFactory()
{
@ -66,25 +66,19 @@ DeviceFactory::DeviceFactory()
extension_mapping["iso"] = SCCD;
}
DeviceFactory::~DeviceFactory()
{
DeleteAllDevices();
}
DeviceFactory& DeviceFactory::instance()
{
static DeviceFactory instance;
return instance;
}
void DeviceFactory::DeleteDevice(const Device *device) const
void DeviceFactory::DeleteDevice(const PrimaryDevice *device) const
{
auto iterpair = devices.equal_range(device->GetId());
for (auto it = iterpair.first; it != iterpair.second; ++it) {
if (it->second->GetLun() == device->GetLun()) {
devices.erase(it);
delete device;
break;
}
@ -93,30 +87,26 @@ void DeviceFactory::DeleteDevice(const Device *device) const
void DeviceFactory::DeleteAllDevices() const
{
for (const auto& [id, device] : devices) {
delete device;
}
devices.clear();
}
const Device * DeviceFactory::GetDeviceByIdAndLun(int i, int lun) const
const PrimaryDevice *DeviceFactory::GetDeviceByIdAndLun(int i, int lun) const
{
for (const auto& [id, device] : devices) {
if (device->GetId() == i && device->GetLun() == lun) {
return device;
return device.get();
}
}
return nullptr;
}
list<Device *> DeviceFactory::GetAllDevices() const
list<PrimaryDevice *> DeviceFactory::GetAllDevices() const
{
list<Device *> result;
list<PrimaryDevice *> result;
for (const auto& [id, device] : devices) {
result.push_back(device);
result.push_back(device.get());
}
return result;
@ -155,7 +145,7 @@ PbDeviceType DeviceFactory::GetTypeForFile(const string& filename) const
}
// ID -1 is used by rascsi to create a temporary device
Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, int id)
PrimaryDevice *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, int id)
{
// If no type was specified try to derive the device type from the filename
if (type == UNDEFINED) {
@ -165,7 +155,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
}
}
unique_ptr<Device> device;
unique_ptr<PrimaryDevice> device;
switch (type) {
case SCHD: {
if (string ext = GetExtension(filename); ext == "hdn" || ext == "hdi" || ext == "nhd") {
@ -248,7 +238,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename, i
assert(device != nullptr);
Device *d = device.release();
PrimaryDevice *d = device.release();
if (d != nullptr) {
d->SetId(id);

View File

@ -23,14 +23,12 @@ using namespace rascsi_interface;
using Geometry = pair<uint32_t, uint32_t>;
class Device;
class PrimaryDevice;
class DeviceFactory
{
friend class ControllerManager;
DeviceFactory();
~DeviceFactory();
~DeviceFactory() = default;
DeviceFactory(DeviceFactory&) = delete;
DeviceFactory& operator=(const DeviceFactory&) = delete;
@ -38,10 +36,11 @@ public:
static DeviceFactory& instance();
Device *CreateDevice(PbDeviceType, const string&, int);
void DeleteDevice(const Device *) const;
const Device *GetDeviceByIdAndLun(int, int) const;
list<Device *> GetAllDevices() const;
PrimaryDevice *CreateDevice(PbDeviceType, const string&, int);
void DeleteDevice(const PrimaryDevice *) const;
void DeleteAllDevices() const;
const PrimaryDevice *GetDeviceByIdAndLun(int, int) const;
list<PrimaryDevice *> GetAllDevices() const;
PbDeviceType GetTypeForFile(const string&) const;
const unordered_set<uint32_t>& GetSectorSizes(PbDeviceType type) { return sector_sizes[type]; }
const unordered_set<uint32_t>& GetSectorSizes(const string&) const;
@ -51,8 +50,6 @@ public:
private:
void DeleteAllDevices() const;
unordered_map<PbDeviceType, unordered_set<uint32_t>> sector_sizes;
// Optional mapping of drive capacities to drive geometries
@ -64,5 +61,5 @@ private:
string GetExtension(const string&) const;
static std::multimap<int, Device *> devices;
static std::multimap<int, unique_ptr<PrimaryDevice>> devices;
};

View File

@ -57,10 +57,9 @@ Disk::Disk(const string& id) : ModePageDevice(id), ScsiBlockCommands()
Disk::~Disk()
{
// Save disk cache
if (IsReady()) {
// Only if ready...
FlushCache();
// Save disk cache, only if ready
if (IsReady() && disk.dcache) {
disk.dcache->Save();
}
delete disk.dcache;
@ -122,9 +121,7 @@ void Disk::FlushCache()
void Disk::Rezero()
{
CheckReady();
EnterStatusPhase();
Seek();
}
void Disk::FormatUnit()
@ -136,9 +133,7 @@ void Disk::FormatUnit()
void Disk::ReassignBlocks()
{
CheckReady();
EnterStatusPhase();
Seek();
}
void Disk::Read(access_mode mode)

View File

@ -27,32 +27,14 @@
//
//===========================================================================
DiskTrack::DiskTrack()
{
// Initialization of internal information
dt.track = 0;
dt.size = 0;
dt.sectors = 0;
dt.raw = FALSE;
dt.init = FALSE;
dt.changed = FALSE;
dt.length = 0;
dt.buffer = nullptr;
dt.maplen = 0;
dt.changemap = nullptr;
dt.imgoffset = 0;
}
DiskTrack::~DiskTrack()
{
// Release memory, but do not save automatically
if (dt.buffer) {
free(dt.buffer);
dt.buffer = nullptr;
}
if (dt.changemap) {
free(dt.changemap);
dt.changemap = nullptr;
}
}

View File

@ -37,10 +37,10 @@ private:
BOOL *changemap; // Changed map
BOOL raw; // RAW mode flag
off_t imgoffset; // Offset to actual data
} dt;
} dt = {};
public:
DiskTrack();
DiskTrack() = default;
~DiskTrack();
DiskTrack(DiskTrack&) = delete;
DiskTrack& operator=(const DiskTrack&) = delete;

View File

@ -24,12 +24,7 @@ class Dispatcher
public:
Dispatcher() = default;
~Dispatcher()
{
for (auto const& [name, command] : commands) {
delete command;
}
}
~Dispatcher() = default;
Dispatcher(Dispatcher&) = delete;
Dispatcher& operator=(const Dispatcher&) = delete;
@ -40,11 +35,11 @@ public:
_command_t(const char* _name, operation _execute) : name(_name), execute(_execute) { };
};
unordered_map<scsi_command, command_t*> commands;
unordered_map<scsi_command, unique_ptr<command_t>> commands;
void AddCommand(scsi_command opcode, const char* name, operation execute)
{
commands[opcode] = new command_t(name, execute);
commands[opcode] = make_unique<command_t>(name, execute);
}
bool Dispatch(T *instance, DWORD cmd)

View File

@ -18,7 +18,7 @@ void FileSupport::ReserveFile(const Filepath& path, int id, int lun) const
reserved_files[path.GetPath()] = make_pair(id, lun);
}
void FileSupport::UnreserveFile()
void FileSupport::UnreserveFile() const
{
reserved_files.erase(diskpath.GetPath());
}

View File

@ -21,15 +21,11 @@ using id_set = pair<int, int>;
class FileSupport
{
friend class ControllerManager;
Filepath diskpath;
// The list of image files in use and the IDs and LUNs using these files
static unordered_map<string, id_set> reserved_files;
static void UnreserveAll();
public:
FileSupport() = default;
@ -41,7 +37,8 @@ public:
void SetPath(const Filepath& path) { diskpath = path; }
void ReserveFile(const Filepath&, int, int) const;
void UnreserveFile();
void UnreserveFile() const;
static void UnreserveAll();
static unordered_map<string, id_set> GetReservedFiles() { return reserved_files; }
static void SetReservedFiles(const unordered_map<string, id_set>& files_in_use)

View File

@ -35,6 +35,7 @@
#include "rascsi_exceptions.h"
#include "device.h"
#include "device_factory.h"
#include "host_services.h"
using namespace scsi_defs;
@ -69,7 +70,7 @@ void HostServices::StartStopUnit()
if (!start) {
// Flush any caches
for (Device *device : devices) {
for (Device *device : DeviceFactory::instance().GetAllDevices()) {
device->FlushCache();
}
@ -175,14 +176,15 @@ void HostServices::AddRealtimeClockPage(map<int, vector<BYTE>>& pages, bool chan
buf[3] = 0x00;
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);
buf[4] = (BYTE)tm.tm_year;
buf[5] = (BYTE)tm.tm_mon;
buf[6] = (BYTE)tm.tm_mday;
buf[7] = (BYTE)tm.tm_hour;
buf[8] = (BYTE)tm.tm_min;
tm localtime;
localtime_r(&t, &localtime);
buf[4] = (BYTE)localtime.tm_year;
buf[5] = (BYTE)localtime.tm_mon;
buf[6] = (BYTE)localtime.tm_mday;
buf[7] = (BYTE)localtime.tm_hour;
buf[8] = (BYTE)localtime.tm_min;
// Ignore leap second for simplicity
buf[9] = (BYTE)(tm.tm_sec < 60 ? tm.tm_sec : 59);
buf[9] = (BYTE)(localtime.tm_sec < 60 ? localtime.tm_sec : 59);
pages[32] = buf;
}

View File

@ -11,14 +11,13 @@
#pragma once
#include "scsi_primary_commands.h"
class ScsiBlockCommands : virtual public ScsiPrimaryCommands
class ScsiBlockCommands
{
public:
ScsiBlockCommands() = default;
~ScsiBlockCommands() override = default;
virtual ~ScsiBlockCommands() = default;
// Mandatory commands
virtual void FormatUnit() = 0;

View File

@ -11,14 +11,13 @@
#pragma once
#include "scsi_primary_commands.h"
class ScsiMmcCommands : virtual public ScsiPrimaryCommands
class ScsiMmcCommands
{
public:
ScsiMmcCommands() = default;
~ScsiMmcCommands() override = default;
virtual ~ScsiMmcCommands() = default;
virtual void ReadToc() = 0;
virtual void GetEventStatusNotification() = 0;

View File

@ -13,6 +13,7 @@
class ScsiPrimaryCommands
{
public:
ScsiPrimaryCommands() = default;

View File

@ -11,14 +11,13 @@
#pragma once
#include "scsi_primary_commands.h"
class ScsiPrinterCommands : virtual public ScsiPrimaryCommands
class ScsiPrinterCommands
{
public:
ScsiPrinterCommands() = default;
~ScsiPrinterCommands() override = default;
virtual ~ScsiPrinterCommands() = default;
// Mandatory commands
virtual void Print() = 0;

View File

@ -123,7 +123,7 @@ void ModePageDevice::ModeSelect10()
EnterDataOutPhase();
}
int ModePageDevice::ModeSelectCheck(int length)
int ModePageDevice::ModeSelectCheck(int length) const
{
// Error if save parameters are set for other types than of SCHD, SCRM or SCMO
// TODO The assumption above is not correct, and this code should be located elsewhere
@ -134,13 +134,13 @@ int ModePageDevice::ModeSelectCheck(int length)
return length;
}
int ModePageDevice::ModeSelectCheck6()
int ModePageDevice::ModeSelectCheck6() const
{
// Receive the data specified by the parameter length
return ModeSelectCheck(ctrl->cmd[4]);
}
int ModePageDevice::ModeSelectCheck10()
int ModePageDevice::ModeSelectCheck10() const
{
// Receive the data specified by the parameter length
int length = ctrl->cmd[7];

View File

@ -50,7 +50,7 @@ private:
void ModeSelect6();
void ModeSelect10();
int ModeSelectCheck(int);
int ModeSelectCheck6();
int ModeSelectCheck10();
int ModeSelectCheck(int) const;
int ModeSelectCheck6() const;
int ModeSelectCheck10() const;
};

View File

@ -182,7 +182,7 @@ vector<BYTE> PrimaryDevice::HandleInquiry(device_type type, scsi_level level, bo
return buf;
}
vector<BYTE> PrimaryDevice::HandleRequestSense()
vector<BYTE> PrimaryDevice::HandleRequestSense() const
{
// Return not ready only if there are no errors
if (!GetStatusCode() && !IsReady()) {

View File

@ -19,8 +19,9 @@
using namespace std;
class PrimaryDevice: public Device, virtual public ScsiPrimaryCommands
class PrimaryDevice: public ScsiPrimaryCommands, public Device
{
public:
explicit PrimaryDevice(const string&);
@ -54,7 +55,7 @@ private:
void ReportLuns() override;
void Inquiry() override;
vector<BYTE> HandleRequestSense();
vector<BYTE> HandleRequestSense() const;
Dispatcher<PrimaryDevice> dispatcher;
};

View File

@ -314,7 +314,7 @@ int SCSIDaynaPort::WriteCheck(uint64_t)
// XX XX ... is the actual packet
//
//---------------------------------------------------------------------------
bool SCSIDaynaPort::WriteBytes(const DWORD *cdb, BYTE *buf, uint64_t)
bool SCSIDaynaPort::WriteBytes(const DWORD *cdb, const BYTE *buf, uint64_t)
{
auto data_format = (BYTE)cdb[5];
WORD data_length = (WORD)cdb[4] + ((WORD)cdb[3] << 8);

View File

@ -53,7 +53,7 @@ public:
// Commands
vector<BYTE> InquiryInternal() const override;
int Read(const DWORD *cdb, BYTE *, uint64_t) override;
bool WriteBytes(const DWORD *, BYTE *, uint64_t);
bool WriteBytes(const DWORD *, const BYTE *, uint64_t);
int WriteCheck(uint64_t block) override;
int RetrieveStats(const DWORD *cdb, BYTE *buffer) const;

View File

@ -304,8 +304,8 @@ void SCSIBR::SendMessage10()
// Reallocate buffer (because it is not transfer for each block)
if (ctrl->bufsize < 0x1000000) {
delete[] ctrl->buffer;
ctrl->buffer = new BYTE[ctrl->bufsize];
ctrl->bufsize = 0x1000000;
ctrl->buffer = new BYTE[ctrl->bufsize];
}
// Set transfer amount
@ -352,11 +352,9 @@ void SCSIBR::ReceivePacket()
packet_len = tap->Rx(packet_buf);
// Check if received packet
if (memcmp(packet_buf, mac_addr, 6) != 0) {
if (memcmp(packet_buf, bcast_addr, 6) != 0) {
packet_len = 0;
return;
}
if (memcmp(packet_buf, mac_addr, 6) != 0 && memcmp(packet_buf, bcast_addr, 6) != 0) {
packet_len = 0;
return;
}
// Discard if it exceeds the buffer size
@ -388,7 +386,7 @@ void SCSIBR::GetPacketBuf(BYTE *buf)
packet_enable = false;
}
void SCSIBR::SendPacket(BYTE *buf, int len)
void SCSIBR::SendPacket(const BYTE *buf, int len)
{
assert(tap);
@ -1144,7 +1142,7 @@ void SCSIBR::WriteFs(int func, BYTE *buf)
// File system write (input option data)
//
//---------------------------------------------------------------------------
void SCSIBR::WriteFsOpt(BYTE *buf, int num)
void SCSIBR::WriteFsOpt(const BYTE *buf, int num)
{
memcpy(fsopt, buf, num);
}

View File

@ -60,7 +60,7 @@ private:
void SetMacAddr(const BYTE *buf); // Set MAC address
void ReceivePacket(); // Receive a packet
void GetPacketBuf(BYTE *buf); // Get a packet
void SendPacket(BYTE *buf, int len); // Send a packet
void SendPacket(const BYTE *buf, int len); // Send a packet
CTapDriver *tap = nullptr; // TAP driver
bool m_bTapEnable = false; // TAP valid flag
@ -73,7 +73,7 @@ private:
int ReadFsOut(BYTE *buf) const; // Read filesystem (return data)
int ReadFsOpt(BYTE *buf) const; // Read file system (optional data)
void WriteFs(int func, BYTE *buf); // File system write (execute)
void WriteFsOpt(BYTE *buf, int len); // File system write (optional data)
void WriteFsOpt(const BYTE *buf, int len); // File system write (optional data)
// Command handlers
void FS_InitDevice(BYTE *buf); // $40 - boot

View File

@ -212,11 +212,8 @@ void SCSIPrinter::SendDiagnostic()
void SCSIPrinter::StopPrint()
{
CheckReservation();
// Nothing to do, printing has not yet been started
EnterStatusPhase();
// Both command implemntations are identical
TestUnitReady();
}
bool SCSIPrinter::WriteByteSequence(BYTE *buf, uint32_t length)
@ -234,7 +231,7 @@ bool SCSIPrinter::WriteByteSequence(BYTE *buf, uint32_t length)
LOGTRACE("Appending %d byte(s) to printer output file", length)
uint32_t num_written = (uint32_t)write(fd, buf, length);
auto num_written = (uint32_t)write(fd, buf, length);
return num_written == length;
}

View File

@ -17,7 +17,7 @@
using namespace std;
class SCSIPrinter: public PrimaryDevice, public ScsiPrinterCommands
class SCSIPrinter: public PrimaryDevice, public ScsiPrinterCommands //NOSONAR Custom destructor cannot be removed
{
static constexpr const char *TMP_FILE_PATTERN = "/tmp/rascsi_sclp-XXXXXX";
static constexpr const int TMP_FILENAME_LENGTH = strlen(TMP_FILE_PATTERN);

View File

@ -299,11 +299,11 @@ void SCSICD::OpenIso(const Filepath& path)
}
// Create only one data track
assert(!track[0]);
track[0] = new CDTrack();
track[0]->Init(1, 0, GetBlockCount() - 1);
track[0]->SetPath(false, path);
tracks = 1;
assert(!tracks.size());
auto track = make_unique<CDTrack>();
track->Init(1, 0, GetBlockCount() - 1);
track->SetPath(false, path);
tracks.push_back(move(track));
dataindex = 0;
}
@ -332,11 +332,11 @@ void SCSICD::OpenPhysical(const Filepath& path)
SetBlockCount((DWORD)(size >> GetSectorSizeShiftCount()));
// Create only one data track
ASSERT(!track[0]);
track[0] = new CDTrack();
track[0]->Init(1, 0, GetBlockCount() - 1);
track[0]->SetPath(false, path);
tracks = 1;
ASSERT(!tracks.size());
auto track = make_unique<CDTrack>();
track->Init(1, 0, GetBlockCount() - 1);
track->SetPath(false, path);
tracks.push_back(move(track));
dataindex = 0;
}
@ -440,7 +440,7 @@ int SCSICD::Read(const DWORD *cdb, BYTE *buf, uint64_t block)
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::LBA_OUT_OF_RANGE);
}
assert(track[index]);
assert(tracks[index]);
// If different from the current data track
if (dataindex != index) {
@ -449,12 +449,12 @@ int SCSICD::Read(const DWORD *cdb, BYTE *buf, uint64_t block)
disk.dcache = nullptr;
// Reset the number of blocks
SetBlockCount(track[index]->GetBlocks());
SetBlockCount(tracks[index]->GetBlocks());
ASSERT(GetBlockCount() > 0);
// Recreate the disk cache
Filepath path;
track[index]->GetPath(path);
tracks[index]->GetPath(path);
disk.dcache = new DiskCache(path, GetSectorSizeShiftCount(), GetBlockCount());
disk.dcache->SetRawMode(rawfile);
@ -475,8 +475,8 @@ int SCSICD::ReadToc(const DWORD *cdb, BYTE *buf)
CheckReady();
// If ready, there is at least one track
assert(tracks > 0);
assert(track[0]);
assert(tracks.size() > 0);
assert(tracks[0]);
// Get allocation length, clear buffer
int length = cdb[7] << 8;
@ -487,35 +487,33 @@ int SCSICD::ReadToc(const DWORD *cdb, BYTE *buf)
bool msf = cdb[1] & 0x02;
// Get and check the last track number
int last = track[tracks - 1]->GetTrackNo();
if ((int)cdb[6] > last) {
// Except for AA
if (cdb[6] != 0xaa) {
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
int last = tracks[tracks.size() - 1]->GetTrackNo();
// Except for AA
if ((int)cdb[6] > last && cdb[6] != 0xaa) {
throw scsi_error_exception(sense_key::ILLEGAL_REQUEST, asc::INVALID_FIELD_IN_CDB);
}
// Check start index
int index = 0;
if (cdb[6] != 0x00) {
// Advance the track until the track numbers match
while (track[index]) {
if ((int)cdb[6] == track[index]->GetTrackNo()) {
while (tracks[index]) {
if ((int)cdb[6] == tracks[index]->GetTrackNo()) {
break;
}
index++;
}
// AA if not found or internal error
if (!track[index]) {
if (!tracks[index]) {
if (cdb[6] == 0xaa) {
// Returns the final LBA+1 because it is AA
buf[0] = 0x00;
buf[1] = 0x0a;
buf[2] = (BYTE)track[0]->GetTrackNo();
buf[2] = (BYTE)tracks[0]->GetTrackNo();
buf[3] = (BYTE)last;
buf[6] = 0xaa;
DWORD lba = track[tracks - 1]->GetLast() + 1;
DWORD lba = tracks[tracks.size() - 1]->GetLast() + 1;
if (msf) {
LBAtoMSF(lba, &buf[8]);
} else {
@ -531,20 +529,20 @@ int SCSICD::ReadToc(const DWORD *cdb, BYTE *buf)
}
// Number of track descriptors returned this time (number of loops)
int loop = last - track[index]->GetTrackNo() + 1;
int loop = last - tracks[index]->GetTrackNo() + 1;
assert(loop >= 1);
// Create header
buf[0] = (BYTE)(((loop << 3) + 2) >> 8);
buf[1] = (BYTE)((loop << 3) + 2);
buf[2] = (BYTE)track[0]->GetTrackNo();
buf[2] = (BYTE)tracks[0]->GetTrackNo();
buf[3] = (BYTE)last;
buf += 4;
// Loop....
for (int i = 0; i < loop; i++) {
// ADR and Control
if (track[index]->IsAudio()) {
if (tracks[index]->IsAudio()) {
// audio track
buf[1] = 0x10;
} else {
@ -553,14 +551,14 @@ int SCSICD::ReadToc(const DWORD *cdb, BYTE *buf)
}
// track number
buf[2] = (BYTE)track[index]->GetTrackNo();
buf[2] = (BYTE)tracks[index]->GetTrackNo();
// track address
if (msf) {
LBAtoMSF(track[index]->GetFirst(), &buf[4]);
LBAtoMSF(tracks[index]->GetFirst(), &buf[4]);
} else {
buf[6] = (BYTE)(track[index]->GetFirst() >> 8);
buf[7] = (BYTE)(track[index]->GetFirst());
buf[6] = (BYTE)(tracks[index]->GetFirst() >> 8);
buf[7] = (BYTE)(tracks[index]->GetFirst());
}
// Advance buffer pointer and index
@ -615,14 +613,7 @@ void SCSICD::LBAtoMSF(DWORD lba, BYTE *msf) const
void SCSICD::ClearTrack()
{
// delete the track object
for (auto t: track) {
delete t;
t = nullptr;
}
// Number of tracks is 0
tracks = 0;
tracks.clear();
// No settings for data and audio
dataindex = -1;
@ -638,10 +629,10 @@ void SCSICD::ClearTrack()
int SCSICD::SearchTrack(DWORD lba) const
{
// Track loop
for (int i = 0; i < tracks; i++) {
for (size_t i = 0; i < tracks.size(); i++) {
// Listen to the track
assert(track[i]);
if (track[i]->IsValid(lba)) {
assert(tracks[i]);
if (tracks[i]->IsValid(lba)) {
return i;
}
}

View File

@ -28,15 +28,13 @@
//===========================================================================
class CDTrack
{
private:
friend class SCSICD;
public:
CDTrack() = default;
virtual ~CDTrack() final = default;
CDTrack(CDTrack&) = delete;
public:
CDTrack& operator=(const CDTrack&) = delete;
void Init(int track, DWORD first, DWORD last);
@ -66,8 +64,6 @@ private:
//===========================================================================
class SCSICD : public Disk, public ScsiMmcCommands, public FileSupport
{
// Maximum number of tracks
static const int TRACK_MAX = 96;
public:
@ -114,8 +110,7 @@ private:
// Track management
void ClearTrack(); // Clear the track
int SearchTrack(DWORD lba) const; // Track search
CDTrack* track[TRACK_MAX] = {}; // Track opbject references
int tracks = 0; // Effective number of track objects
vector<unique_ptr<CDTrack>> tracks; // Track opbject references
int dataindex = -1; // Current data track
int audioindex = -1; // Current audio track
};

View File

@ -161,7 +161,6 @@ bool protobuf_util::ReturnLocalizedError(const CommandContext& context, const Lo
const PbErrorCode error_code, const string& arg1, const string& arg2, const string& arg3)
{
// For the logfile always use English
// TODO This line forces rasctl to depend on the localizer. This should be fixed.
LOGERROR("%s", localizer.Localize(key, "en", arg1, arg2, arg3).c_str())
return ReturnStatus(context, false, localizer.Localize(key, context.locale, arg1, arg2, arg3), error_code, false);

View File

@ -57,7 +57,7 @@ static const char COMPONENT_SEPARATOR = ':';
//---------------------------------------------------------------------------
static volatile bool running; // Running flag
static volatile bool active; // Processing flag
unique_ptr<GPIOBUS> bus; // GPIO Bus
shared_ptr<GPIOBUS> bus; // GPIO Bus
int monsocket; // Monitor Socket
pthread_t monthread; // Monitor Thread
pthread_mutex_t ctrl_mutex; // Semaphore for the ctrl array
@ -177,7 +177,7 @@ bool InitService(int port)
bool InitBus()
{
// GPIOBUS creation
bus = make_unique<GPIOBUS>();
bus = make_shared<GPIOBUS>();
// GPIO Initialization
if (!bus->Init()) {
@ -262,7 +262,7 @@ string ValidateLunSetup(const PbCommand& command)
}
// Collect LUN bit vectors of existing devices
for (const Device *device : device_factory.GetAllDevices()) {
for (const auto device : device_factory.GetAllDevices()) {
luns[device->GetId()] |= 1 << device->GetLun();
}
@ -369,7 +369,9 @@ string SetReservedIds(string_view ids)
void DetachAll()
{
controller_manager.DeleteAllControllersAndDevices();
controller_manager.DeleteAllControllers();
DeviceFactory::instance().DeleteAllDevices();
FileSupport::UnreserveAll();
LOGINFO("Detached all devices")
}
@ -391,7 +393,7 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
string filename = GetParam(pb_device, "file");
Device *device = device_factory.CreateDevice(type, filename, id);
PrimaryDevice *device = device_factory.CreateDevice(type, filename, id);
if (device == nullptr) {
if (type == UNDEFINED) {
return ReturnLocalizedError(context, ERROR_MISSING_DEVICE_TYPE, filename);
@ -451,7 +453,7 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
}
Filepath filepath;
if (file_support && !filename.empty()) {
if (file_support != nullptr && !filename.empty()) {
filepath.SetPath(filename.c_str());
string initial_filename = filepath.GetPath();
@ -513,11 +515,9 @@ bool Attach(const CommandContext& context, const PbDeviceDefinition& pb_device,
", unit " +to_string(unit) + " failed");
}
// Replace with the newly created unit
pthread_mutex_lock(&ctrl_mutex);
if (auto primary_device = static_cast<PrimaryDevice *>(device);
!controller_manager.CreateScsiController(bus.get(), primary_device)) {
if (!controller_manager.CreateScsiController(bus, device)) {
pthread_mutex_unlock(&ctrl_mutex);
return ReturnStatus(context, false, "Couldn't create SCSI controller instance");
@ -1511,7 +1511,7 @@ int main(int argc, char* argv[])
pthread_mutex_lock(&ctrl_mutex);
// Identify the responsible controller
AbstractController *controller = controller_manager.IdentifyController(id_data);
shared_ptr<AbstractController> controller = controller_manager.IdentifyController(id_data);
if (controller != nullptr) {
initiator_id = controller->ExtractInitiatorId(id_data);

View File

@ -124,7 +124,7 @@ bool RascsiImage::IsValidDstFilename(const string& filename) const
return stat(filename.c_str(), &st);
}
bool RascsiImage::CreateImage(const CommandContext& context, const PbCommand& command)
bool RascsiImage::CreateImage(const CommandContext& context, const PbCommand& command) const
{
string filename = GetParam(command, "file");
if (filename.empty()) {
@ -189,7 +189,7 @@ bool RascsiImage::CreateImage(const CommandContext& context, const PbCommand& co
return ReturnStatus(context);
}
bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& command)
bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& command) const
{
string filename = GetParam(command, "file");
if (filename.empty()) {
@ -237,7 +237,7 @@ bool RascsiImage::DeleteImage(const CommandContext& context, const PbCommand& co
return ReturnStatus(context);
}
bool RascsiImage::RenameImage(const CommandContext& context, const PbCommand& command)
bool RascsiImage::RenameImage(const CommandContext& context, const PbCommand& command) const
{
string from = GetParam(command, "from");
if (from.empty()) {
@ -280,7 +280,7 @@ bool RascsiImage::RenameImage(const CommandContext& context, const PbCommand& co
return ReturnStatus(context);
}
bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& command)
bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& command) const
{
string from = GetParam(command, "from");
if (from.empty()) {
@ -364,7 +364,7 @@ bool RascsiImage::CopyImage(const CommandContext& context, const PbCommand& comm
return ReturnStatus(context);
}
bool RascsiImage::SetImagePermissions(const CommandContext& context, const PbCommand& command)
bool RascsiImage::SetImagePermissions(const CommandContext& context, const PbCommand& command) const
{
string filename = GetParam(command, "file");
if (filename.empty()) {

View File

@ -22,6 +22,8 @@ public:
RascsiImage();
~RascsiImage() = default;
RascsiImage(RascsiImage&) = delete;
RascsiImage& operator=(const RascsiImage&) = delete;
void SetDepth(int d) { depth = d; }
int GetDepth() const { return depth; }
@ -31,11 +33,11 @@ public:
string SetDefaultImageFolder(const string&);
bool IsValidSrcFilename(const string&) const;
bool IsValidDstFilename(const string&) const;
bool CreateImage(const CommandContext&, const PbCommand&);
bool DeleteImage(const CommandContext&, const PbCommand&);
bool RenameImage(const CommandContext&, const PbCommand&);
bool CopyImage(const CommandContext&, const PbCommand&);
bool SetImagePermissions(const CommandContext&, const PbCommand&);
bool CreateImage(const CommandContext&, const PbCommand&) const;
bool DeleteImage(const CommandContext&, const PbCommand&) const;
bool RenameImage(const CommandContext&, const PbCommand&) const;
bool CopyImage(const CommandContext&, const PbCommand&) const;
bool SetImagePermissions(const CommandContext&, const PbCommand&) const;
private:

View File

@ -32,7 +32,7 @@ PbDeviceProperties *RascsiResponse::GetDeviceProperties(const Device *device)
properties->set_stoppable(device->IsStoppable());
properties->set_removable(device->IsRemovable());
properties->set_lockable(device->IsLockable());
properties->set_supports_file(dynamic_cast<const FileSupport *>(device));
properties->set_supports_file(dynamic_cast<const FileSupport *>(device) != nullptr);
properties->set_supports_params(device->SupportsParams());
PbDeviceType t = UNDEFINED;
@ -56,9 +56,9 @@ void RascsiResponse::GetDeviceTypeProperties(PbDeviceTypesInfo& device_types_inf
{
PbDeviceTypeProperties *type_properties = device_types_info.add_properties();
type_properties->set_type(type);
const Device *device = device_factory->CreateDevice(type, "", -1);
const PrimaryDevice *device = device_factory->CreateDevice(type, "", -1);
type_properties->set_allocated_properties(GetDeviceProperties(device));
device_factory->DeleteDevice(device);
device_factory->DeleteDevice(device); //NOSONAR The alloced memory is managed by protobuf
}
void RascsiResponse::GetAllDeviceTypeProperties(PbDeviceTypesInfo& device_types_info)
@ -94,7 +94,7 @@ void RascsiResponse::GetDevice(const Device *device, PbDevice *pb_device)
status->set_removed(device->IsRemoved());
status->set_locked(device->IsLocked());
if (device->SupportsParams()) {
if (device->SupportsParams()) { //NOSONAR The alloced memory is managed by protobuf
for (const auto& [key, value] : device->GetParams()) {
AddParam(*pb_device, key, value);
}
@ -113,9 +113,9 @@ void RascsiResponse::GetDevice(const Device *device, PbDevice *pb_device)
GetImageFile(image_file, device->IsRemovable() && !device->IsReady() ? "" : filepath.GetPath());
pb_device->set_allocated_file(image_file);
}
}
} //NOSONAR The alloced memory is managed by protobuf
bool RascsiResponse::GetImageFile(PbImageFile *image_file, const string& filename)
bool RascsiResponse::GetImageFile(PbImageFile *image_file, const string& filename) const
{
if (!filename.empty()) {
image_file->set_name(filename);
@ -209,7 +209,7 @@ void RascsiResponse::GetAvailableImages(PbResult& result, PbServerInfo& server_i
image_files_info->set_default_image_folder(rascsi_image->GetDefaultImageFolder());
server_info.set_allocated_image_files_info(image_files_info);
result.set_status(true);
result.set_status(true); //NOSONAR The alloced memory is managed by protobuf
}
PbReservedIdsInfo *RascsiResponse::GetReservedIds(PbResult& result, const unordered_set<int>& ids)
@ -280,14 +280,14 @@ PbServerInfo *RascsiResponse::GetServerInfo(PbResult& result, const unordered_se
auto server_info = make_unique<PbServerInfo>().release();
server_info->set_allocated_version_info(GetVersionInfo(result));
server_info->set_allocated_log_level_info(GetLogLevelInfo(result, current_log_level));
GetAllDeviceTypeProperties(*server_info->mutable_device_types_info());
server_info->set_allocated_log_level_info(GetLogLevelInfo(result, current_log_level)); //NOSONAR The alloced memory is managed by protobuf
GetAllDeviceTypeProperties(*server_info->mutable_device_types_info()); //NOSONAR The alloced memory is managed by protobuf
GetAvailableImages(result, *server_info, folder_pattern, file_pattern, scan_depth);
server_info->set_allocated_network_interfaces_info(GetNetworkInterfacesInfo(result));
server_info->set_allocated_mapping_info(GetMappingInfo(result));
GetDevices(*server_info);
server_info->set_allocated_mapping_info(GetMappingInfo(result)); //NOSONAR The alloced memory is managed by protobuf
GetDevices(*server_info); //NOSONAR The alloced memory is managed by protobuf
server_info->set_allocated_reserved_ids_info(GetReservedIds(result, reserved_ids));
server_info->set_allocated_operation_info(GetOperationInfo(result, scan_depth));
server_info->set_allocated_operation_info(GetOperationInfo(result, scan_depth)); //NOSONAR The alloced memory is managed by protobuf
result.set_status(true);
@ -492,7 +492,7 @@ PbOperationInfo *RascsiResponse::GetOperationInfo(PbResult& result, int depth)
}
void RascsiResponse::CreateOperation(PbOperationInfo *operation_info, PbOperationMetaData *meta_data,
const PbOperation& operation, const string& description)
const PbOperation& operation, const string& description) const
{
meta_data->set_server_side_name(PbOperation_Name(operation));
meta_data->set_description(description);

View File

@ -28,8 +28,10 @@ public:
RascsiResponse(DeviceFactory *device_factory, const RascsiImage *rascsi_image)
: device_factory(device_factory), rascsi_image(rascsi_image) {}
~RascsiResponse() = default;
RascsiResponse(RascsiResponse&) = delete;
RascsiResponse& operator=(const RascsiResponse&) = delete;
bool GetImageFile(PbImageFile *, const string&);
bool GetImageFile(PbImageFile *, const string&) const;
PbImageFilesInfo *GetAvailableImages(PbResult&, const string&, const string&, int);
PbReservedIdsInfo *GetReservedIds(PbResult&, const unordered_set<int>&);
void GetDevices(PbServerInfo&);
@ -55,7 +57,7 @@ private:
void GetDeviceTypeProperties(PbDeviceTypesInfo&, PbDeviceType);
void GetAvailableImages(PbImageFilesInfo&, string_view, const string&, const string&, const string&, int);
void GetAvailableImages(PbResult& result, PbServerInfo&, const string&, const string&, int);
void CreateOperation(PbOperationInfo *, PbOperationMetaData *, const PbOperation&, const string&);
void CreateOperation(PbOperationInfo *, PbOperationMetaData *, const PbOperation&, const string&) const;
PbOperationParameter *AddOperationParameter(PbOperationMetaData *, const string&, const string&,
const string& = "", bool = false);
};

View File

@ -22,6 +22,8 @@ public:
RasctlCommands(const PbCommand&, const string&, int, const string&, const string&);
~RasctlCommands() = default;
RasctlCommands(RasctlCommands&) = delete;
RasctlCommands& operator=(const RasctlCommands&) = delete;
void SendCommand();
void CommandDevicesInfo();

View File

@ -19,6 +19,8 @@ public:
RasctlDisplay() = default;
~RasctlDisplay() = default;
RasctlDisplay(RasctlDisplay&) = delete;
RasctlDisplay& operator=(const RasctlDisplay&) = delete;
void DisplayDevices(const PbDevicesInfo&) const;
void DisplayDeviceInfo(const PbDevice&) const;

View File

@ -37,7 +37,7 @@ bool ras_util::GetAsInt(const string& value, int& result)
string ras_util::ListDevices(const list<PbDevice>& pb_devices)
{
if (pb_devices.empty()) {
return "No images currently attached.";
return "No devices currently attached.";
}
ostringstream s;

View File

@ -30,7 +30,7 @@ using namespace std;
//
//---------------------------------------------------------------------------
static volatile bool running; // Running flag
GPIOBUS *bus; // GPIO Bus
unique_ptr<GPIOBUS> bus; // GPIO Bus
DWORD buff_size = 1000000;
data_capture *data_buffer;
@ -183,7 +183,7 @@ bool Init()
}
// GPIO Initialization
bus = new GPIOBUS();
bus = make_unique<GPIOBUS>();
if (!bus->Init())
{
LOGERROR("Unable to intiailize the GPIO bus. Exiting....")
@ -217,7 +217,6 @@ void Cleanup()
{
// Cleanup the Bus
bus->Cleanup();
delete bus;
}
}

View File

@ -15,7 +15,7 @@ TEST(ControllerManagerTest, ControllerManager)
const int ID = 4;
const int LUN = 6;
auto device = static_cast<PrimaryDevice *>(device_factory.CreateDevice(UNDEFINED, "services", ID));
auto device = device_factory.CreateDevice(UNDEFINED, "services", ID);
device->SetId(ID);
device->SetLun(LUN);
@ -27,7 +27,8 @@ TEST(ControllerManagerTest, ControllerManager)
EXPECT_EQ(device, controller_manager.GetDeviceByIdAndLun(ID, LUN));
EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(0, 0));
controller_manager.DeleteAllControllersAndDevices();
controller_manager.DeleteAllControllers();
device_factory.DeleteAllDevices();
EXPECT_EQ(nullptr, controller_manager.FindController(ID));
EXPECT_EQ(nullptr, controller_manager.GetDeviceByIdAndLun(ID, LUN));
}

View File

@ -36,11 +36,11 @@ TEST(DeviceFactoryTest, GetTypeForFile)
TEST(DeviceFactoryTest, LifeCycle)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "services", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "services", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCHS", device->GetType());
list<Device *> devices = device_factory.GetAllDevices();
list<PrimaryDevice *> devices = device_factory.GetAllDevices();
EXPECT_EQ(1, devices.size());
EXPECT_EQ(device, devices.front());
@ -98,13 +98,13 @@ TEST(DeviceFactoryTest, GetSectorSizes)
TEST(DeviceFactoryTest, UnknownDeviceType)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "test", -1);
EXPECT_EQ(nullptr, device);
}
TEST(DeviceFactoryTest, SCHD_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.hda", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "test.hda", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCHD", device->GetType());
EXPECT_TRUE(device->SupportsFile());
@ -144,7 +144,7 @@ TEST(DeviceFactoryTest, SCHD_Device_Defaults)
TEST(DeviceFactoryTest, SCRM_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.hdr", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "test.hdr", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCRM", device->GetType());
EXPECT_TRUE(device->SupportsFile());
@ -169,7 +169,7 @@ TEST(DeviceFactoryTest, SCRM_Device_Defaults)
TEST(DeviceFactoryTest, SCMO_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.mos", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "test.mos", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCMO", device->GetType());
EXPECT_TRUE(device->SupportsFile());
@ -194,7 +194,7 @@ TEST(DeviceFactoryTest, SCMO_Device_Defaults)
TEST(DeviceFactoryTest, SCCD_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "test.iso", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "test.iso", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCCD", device->GetType());
EXPECT_TRUE(device->SupportsFile());
@ -219,7 +219,7 @@ TEST(DeviceFactoryTest, SCCD_Device_Defaults)
TEST(DeviceFactoryTest, SCBR_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "bridge", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "bridge", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCBR", device->GetType());
EXPECT_FALSE(device->SupportsFile());
@ -244,7 +244,7 @@ TEST(DeviceFactoryTest, SCBR_Device_Defaults)
TEST(DeviceFactoryTest, SCDP_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "daynaport", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "daynaport", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCDP", device->GetType());
EXPECT_FALSE(device->SupportsFile());
@ -268,7 +268,7 @@ TEST(DeviceFactoryTest, SCDP_Device_Defaults)
TEST(DeviceFactoryTest, SCHS_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "services", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "services", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCHS", device->GetType());
EXPECT_FALSE(device->SupportsFile());
@ -293,7 +293,7 @@ TEST(DeviceFactoryTest, SCHS_Device_Defaults)
TEST(DeviceFactoryTest, SCLP_Device_Defaults)
{
Device *device = device_factory.CreateDevice(UNDEFINED, "printer", -1);
PrimaryDevice *device = device_factory.CreateDevice(UNDEFINED, "printer", -1);
EXPECT_NE(nullptr, device);
EXPECT_EQ("SCLP", device->GetType());
EXPECT_FALSE(device->SupportsFile());

View File

@ -154,26 +154,27 @@ TEST(PrimaryDeviceTest, ReportLuns)
EXPECT_CALL(controller, DataIn()).Times(1);
EXPECT_TRUE(device1.Dispatch());
EXPECT_EQ(0x00, controller.ctrl.buffer[0]) << "Wrong data length";
EXPECT_EQ(0x00, controller.ctrl.buffer[1]) << "Wrong data length";
EXPECT_EQ(0x00, controller.ctrl.buffer[2]) << "Wrong data length";
EXPECT_EQ(0x10, controller.ctrl.buffer[3]) << "Wrong data length";
EXPECT_EQ(0x00, controller.ctrl.buffer[8]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[9]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[10]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[11]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[12]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[13]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[14]) << "Wrong LUN1 number";
EXPECT_EQ(LUN1, controller.ctrl.buffer[15]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[16]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[17]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[18]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[19]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[20]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[21]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, controller.ctrl.buffer[22]) << "Wrong LUN2 number";
EXPECT_EQ(LUN2, controller.ctrl.buffer[23]) << "Wrong LUN2 number";
const BYTE *buffer = controller.ctrl.buffer;
EXPECT_EQ(0x00, buffer[0]) << "Wrong data length";
EXPECT_EQ(0x00, buffer[1]) << "Wrong data length";
EXPECT_EQ(0x00, buffer[2]) << "Wrong data length";
EXPECT_EQ(0x10, buffer[3]) << "Wrong data length";
EXPECT_EQ(0x00, buffer[8]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[9]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[10]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[11]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[12]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[13]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[14]) << "Wrong LUN1 number";
EXPECT_EQ(LUN1, buffer[15]) << "Wrong LUN1 number";
EXPECT_EQ(0x00, buffer[16]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[17]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[18]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[19]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[20]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[21]) << "Wrong LUN2 number";
EXPECT_EQ(0x00, buffer[22]) << "Wrong LUN2 number";
EXPECT_EQ(LUN2, buffer[23]) << "Wrong LUN2 number";
controller.ctrl.cmd[2] = 0x01;
EXPECT_THROW(device1.Dispatch(), scsi_error_exception) << "Only SELECT REPORT mode 0 is supported";

View File

@ -12,8 +12,7 @@
TEST(ScsiControllerTest, ScsiController)
{
MockBus bus;
MockScsiController controller(&bus, 0);
MockScsiController controller(nullptr, 0);
EXPECT_EQ(32, controller.GetMaxLuns());

View File

@ -25,45 +25,6 @@
extern DeviceFactory& device_factory;
extern ControllerManager& controller_manager;
class MockBus : public BUS
{
public:
MOCK_METHOD(bool, Init, (mode_e), (override));
MOCK_METHOD(void, Reset, (), (override));
MOCK_METHOD(void, Cleanup, (), (override));
MOCK_METHOD(bool, GetBSY, (), (const override));
MOCK_METHOD(void, SetBSY, (bool), (override));
MOCK_METHOD(bool, GetSEL, (), (const override));
MOCK_METHOD(void, SetSEL, (bool), (override));
MOCK_METHOD(bool, GetATN, (), (const override));
MOCK_METHOD(void, SetATN, (bool), (override));
MOCK_METHOD(bool, GetACK, (), (const override));
MOCK_METHOD(void, SetACK, (bool), (override));
MOCK_METHOD(bool, GetRST, (), (const override));
MOCK_METHOD(void, SetRST, (bool), (override));
MOCK_METHOD(bool, GetMSG, (), (const override));
MOCK_METHOD(void, SetMSG, (bool), (override));
MOCK_METHOD(bool, GetCD, (), (const override));
MOCK_METHOD(void, SetCD, (bool), (override));
MOCK_METHOD(bool, GetIO, (), (override));
MOCK_METHOD(void, SetIO, (bool), (override));
MOCK_METHOD(bool, GetREQ, (), (const override));
MOCK_METHOD(void, SetREQ, (bool), (override));
MOCK_METHOD(BYTE, GetDAT, (), (override));
MOCK_METHOD(void, SetDAT, (BYTE), (override));
MOCK_METHOD(bool, GetDP, (), (const, override));
MOCK_METHOD(DWORD, Acquire,(), (override));
MOCK_METHOD(int, CommandHandShake, (BYTE *), (override));
MOCK_METHOD(int, ReceiveHandShake, (BYTE *, int), (override));
MOCK_METHOD(int, SendHandShake, (BYTE *, int, int), (override));
MOCK_METHOD(bool, GetSignal, (int), (const, override));
MOCK_METHOD(void, SetSignal, (int, bool), (override));
MockBus() = default;
~MockBus() final = default;
};
class MockAbstractController : public AbstractController
{
public:
@ -180,7 +141,7 @@ public:
// Make protected methods visible for testing
// TODO Why does FRIEND_TEST not work for this method?
int AddModePages(const DWORD *cdb, BYTE *buf, int max_length) {
int AddModePages(const DWORD *cdb, BYTE *buf, int max_length) const {
return ModePageDevice::AddModePages(cdb, buf, max_length);
}
};