From dfce234cfb2e664b2ba0907cf164873c48517cd5 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Mon, 6 May 2019 08:37:53 +0000 Subject: [PATCH] Fix unitialized access to some isoDrive fields. Pause audio before switching. Use right subunit with multiple CDs on one driveletter. (krcroft, jmarsh and qbix) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4223 --- src/dos/cdrom_image.cpp | 6 +++++- src/dos/dos_mscdex.cpp | 11 +++++++++-- src/dos/drive_iso.cpp | 22 ++++++++++++++++------ src/dos/drive_local.cpp | 5 ++++- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/dos/cdrom_image.cpp b/src/dos/cdrom_image.cpp index 25a7783a..68d1806d 100644 --- a/src/dos/cdrom_image.cpp +++ b/src/dos/cdrom_image.cpp @@ -52,6 +52,7 @@ CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error) CDROM_Interface_Image::BinaryFile::~BinaryFile() { delete file; + file = NULL; } bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count) @@ -128,12 +129,13 @@ int CDROM_Interface_Image::AudioFile::getLength() // initialize static members int CDROM_Interface_Image::refCount = 0; -CDROM_Interface_Image* CDROM_Interface_Image::images[26]; +CDROM_Interface_Image* CDROM_Interface_Image::images[26] = {}; CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = { NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} }; CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit) + :subUnit(subUnit) { images[subUnit] = this; if (refCount == 0) { @@ -375,6 +377,7 @@ bool CDROM_Interface_Image::LoadIsoFile(char* filename) track.file = new BinaryFile(filename, error); if (error) { delete track.file; + track.file = NULL; return false; } track.number = 1; @@ -544,6 +547,7 @@ bool CDROM_Interface_Image::LoadCueSheet(char *cuefile) #endif if (error) { delete track.file; + track.file = NULL; success = false; } } diff --git a/src/dos/dos_mscdex.cpp b/src/dos/dos_mscdex.cpp index 23e60b31..c211bcc6 100644 --- a/src/dos/dos_mscdex.cpp +++ b/src/dos/dos_mscdex.cpp @@ -407,9 +407,11 @@ bool CMscdex::HasDrive(Bit16u drive) { } void CMscdex::ReplaceDrive(CDROM_Interface* newCdrom, Bit8u subUnit) { - delete cdrom[subUnit]; + if (cdrom[subUnit] != NULL) { + StopAudio(subUnit); + delete cdrom[subUnit]; + } cdrom[subUnit] = newCdrom; - StopAudio(subUnit); } PhysPt CMscdex::GetDefaultBuffer(void) { @@ -1298,6 +1300,11 @@ void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit) mscdex->ReplaceDrive(cdrom, subUnit); } +Bit8u MSCDEX_GetSubUnit(char driveLetter) +{ + return mscdex->GetSubUnit(driveLetter-'A'); +} + bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name) { return mscdex->GetVolumeName(subUnit,name); diff --git a/src/dos/drive_iso.cpp b/src/dos/drive_iso.cpp index 937a8a3a..9b3333d9 100644 --- a/src/dos/drive_iso.cpp +++ b/src/dos/drive_iso.cpp @@ -133,13 +133,22 @@ Bit16u isoFile::GetInformation(void) { return 0x40; // read-only drive } -int MSCDEX_RemoveDrive(char driveLetter); -int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); -void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); -bool MSCDEX_HasDrive(char driveLetter); -bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); +int MSCDEX_RemoveDrive(char driveLetter); +int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit); +void MSCDEX_ReplaceDrive(CDROM_Interface* cdrom, Bit8u subUnit); +bool MSCDEX_HasDrive(char driveLetter); +bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); +Bit8u MSCDEX_GetSubUnit(char driveLetter); -isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) { +isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error) + :iso(false), + dataCD(false), + mediaid(0), + fileName{'\0'}, + subUnit(0), + driveLetter('\0'), + discLabel{'\0'} + { nextFreeDirIterator = 0; memset(dirIterators, 0, sizeof(dirIterators)); memset(sectorHashEntries, 0, sizeof(sectorHashEntries)); @@ -174,6 +183,7 @@ isoDrive::~isoDrive() { } int isoDrive::UpdateMscdex(char driveLetter, const char* path, Bit8u& subUnit) { if (MSCDEX_HasDrive(driveLetter)) { + subUnit = MSCDEX_GetSubUnit(driveLetter); CDROM_Interface_Image* oldCdrom = CDROM_Interface_Image::images[subUnit]; CDROM_Interface* cdrom = new CDROM_Interface_Image(subUnit); char pathCopy[CROSS_LEN]; diff --git a/src/dos/drive_local.cpp b/src/dos/drive_local.cpp index d2ba17d1..da8d6e59 100644 --- a/src/dos/drive_local.cpp +++ b/src/dos/drive_local.cpp @@ -559,7 +559,10 @@ bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name); cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error) - :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid) { + :localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid), + subUnit(0), + driveLetter('\0') +{ // Init mscdex error = MSCDEX_AddDrive(driveLetter,startdir,subUnit); strcpy(info, "CDRom ");