1
0
Fork 0

Add rewriten form of patch "[ 1498334 ] CD Images unmounting" created by Kronutz

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2658
This commit is contained in:
Peter Veenstra 2006-06-22 13:15:07 +00:00
parent 35201631c9
commit 3ea5a913a9
9 changed files with 239 additions and 89 deletions

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_system.h,v 1.35 2006-04-23 14:20:57 c2woody Exp $ */
/* $Id: dos_system.h,v 1.36 2006-06-22 13:15:07 qbix79 Exp $ */
#ifndef DOSBOX_DOS_SYSTEM_H
#define DOSBOX_DOS_SYSTEM_H
@ -229,6 +229,8 @@ public:
virtual void EmptyCache(void) { dirCache.EmptyCache(); };
virtual bool isRemote(void)=0;
virtual bool isRemovable(void)=0;
virtual Bits UnMount(void)=0;
char * GetInfo(void);
char curdir[DOS_PATHLENGTH];
char info[256];

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_files.cpp,v 1.74 2006-05-28 09:40:42 qbix79 Exp $ */
/* $Id: dos_files.cpp,v 1.75 2006-06-22 13:15:07 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
@ -535,7 +535,7 @@ bool DOS_SetFileAttr(char * name,Bit16u attr)
Bit16u attrTemp;
char fullname[DOS_PATHLENGTH];Bit8u drive;
if (!DOS_MakeName(name,fullname,&drive)) return false;
if (strcmp(Drives[drive]->GetInfo(),"CDRom.")==0 || strcmp(Drives[drive]->GetInfo(),"isoDrive")==0) {
if (strncmp(Drives[drive]->GetInfo(),"CDRom ",6)==0 || strncmp(Drives[drive]->GetInfo(),"isoDrive ",9)==0) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_mscdex.cpp,v 1.42 2006-04-21 08:35:31 qbix79 Exp $ */
/* $Id: dos_mscdex.cpp,v 1.43 2006-06-22 13:15:07 qbix79 Exp $ */
#include <string.h>
#include <ctype.h>
@ -107,6 +107,7 @@ public:
bool GetSubChannelData (Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs);
int RemoveDrive (Bit16u _drive);
int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit);
void GetDrives (PhysPt data);
void GetDriverInfo (PhysPt data);
@ -197,10 +198,113 @@ Bit8u CMscdex::GetSubUnit(Bit16u _drive)
return 0xff;
};
int CMscdex::RemoveDrive(Bit16u _drive)
{
Bit16u idx = MSCDEX_MAX_DRIVES;
for (Bit16u i=0; i<GetNumDrives(); i++) {
if (dinfo[i].drive == _drive) {
idx = i;
break;
}
}
if (idx == MSCDEX_MAX_DRIVES || (idx!=0 && idx!=GetNumDrives()-1)) return 0;
delete (cdrom)[idx];
if (idx==0) {
for (Bit16u i=0; i<GetNumDrives(); i++) {
if (i == MSCDEX_MAX_DRIVES-1) {
cdrom[i] = 0;
memset(&dinfo[i],0,sizeof(TDriveInfo));
} else {
dinfo[i] = dinfo[i+1];
cdrom[i] = cdrom[i+1];
}
}
} else {
cdrom[idx] = 0;
memset(&dinfo[idx],0,sizeof(TDriveInfo));
}
numDrives--;
if (GetNumDrives() == 0) {
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader);
devHeader.SetStrategy(off+4); // point to the RETF (To deactivate MSCDEX)
devHeader.SetInterrupt(off+4); // point to the RETF (To deactivate MSCDEX)
devHeader.SetDriveLetter(0);
} else if (idx==0) {
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
devHeader.SetDriveLetter(GetFirstDrive()+1);
}
return 1;
}
int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
{
subUnit = 0;
if (GetNumDrives()==0) {
if (GetNumDrives()+1>=MSCDEX_MAX_DRIVES) return 4;
if (GetNumDrives()) {
// Error check, driveletter have to be in a row
if (dinfo[0].drive-1!=_drive && dinfo[numDrives-1].drive+1!=_drive)
return 1;
}
// Set return type to ok
int result = 0;
// Get Mounttype and init needed cdrom interface
switch (CDROM_GetMountType(physicalPath,forceCD)) {
case 0x00: {
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting physical cdrom: %s" ,physicalPath);
#if defined (WIN32)
// Check OS
OSVERSIONINFO osi;
osi.dwOSVersionInfoSize = sizeof(osi);
GetVersionEx(&osi);
if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
// only WIN NT/200/XP
if (useCdromInterface==CDROM_USE_IOCTL) {
cdrom[numDrives] = new CDROM_Interface_Ioctl();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
break;
}
}
if (useCdromInterface==CDROM_USE_ASPI) {
// all Wins - ASPI
cdrom[numDrives] = new CDROM_Interface_Aspi();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface.");
break;
}
#endif
#if defined (LINUX) || defined(OS2)
// Always use IOCTL in Linux or OS/2
cdrom[numDrives] = new CDROM_Interface_Ioctl();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
#else
// Default case windows and other oses
cdrom[numDrives] = new CDROM_Interface_SDL();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface.");
#endif
} break;
case 0x01: // iso cdrom interface
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath);
cdrom[numDrives] = new CDROM_Interface_Image((Bit8u)numDrives);
break;
case 0x02: // fake cdrom interface (directories)
cdrom[numDrives] = new CDROM_Interface_Fake;
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath);
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !");
result = 5;
break;
default : // weird result
return 6;
};
if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) {
// delete cdrom[numDrives] ; mount seems to delete it
return 3;
}
if (rootDriverHeaderSeg==0) {
Bit16u driverSize = sizeof(DOS_DeviceHeader::sDeviceHeader) + 10; // 10 = Bytes for 3 callbacks
@ -246,75 +350,36 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
rootDriverHeaderSeg = seg;
} else {
// Error check, driveletter have to be in a row
if (dinfo[numDrives-1].drive+1!=_drive) return 1;
};
if (GetNumDrives()+1<MSCDEX_MAX_DRIVES) {
// Set return type to ok
int result = 0;
// Get Mounttype and init needed cdrom interface
switch (CDROM_GetMountType(physicalPath,forceCD)) {
case 0x00 : {
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting physical cdrom: %s" ,physicalPath);
#if defined (WIN32)
// Check OS
OSVERSIONINFO osi;
osi.dwOSVersionInfoSize = sizeof(osi);
GetVersionEx(&osi);
if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
// only WIN NT/200/XP
if (useCdromInterface==CDROM_USE_IOCTL) {
cdrom[numDrives] = new CDROM_Interface_Ioctl();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
break;
}
}
if (useCdromInterface==CDROM_USE_ASPI) {
// all Wins - ASPI
cdrom[numDrives] = new CDROM_Interface_Aspi();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: ASPI Interface.");
break;
}
#endif
#if defined (LINUX) || defined(OS2)
// Always use IOCTL in Linux or OS/2
// if (useCdromInterface==CDROM_USE_IOCTL) {
cdrom[numDrives] = new CDROM_Interface_Ioctl();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: IOCTL Interface.");
break;
// }
#endif
cdrom[numDrives] = new CDROM_Interface_SDL();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface.");
} break;
case 0x01 : // iso cdrom interface
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting iso file as cdrom: %s", physicalPath);
cdrom[numDrives] = new CDROM_Interface_Image((Bit8u)numDrives);
break;
case 0x02 : // fake cdrom interface (directories)
cdrom[numDrives] = new CDROM_Interface_Fake;
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: Mounting directory as cdrom: %s",physicalPath);
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: You wont have full MSCDEX support !");
result = 5;
break;
default : // weird result
return 6;
};
if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3;
subUnit = (Bit8u)numDrives;
// Set drive
} else if (GetNumDrives() == 0) {
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader);
devHeader.SetDriveLetter(_drive+1);
devHeader.SetStrategy(off);
devHeader.SetInterrupt(off+5);
}
subUnit = (Bit8u)numDrives;
// Set drive
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
if (dinfo[0].drive-1==_drive) {
CDROM_Interface *_cdrom = cdrom[numDrives];
for (Bit16u i=GetNumDrives(); i>0; i--) {
dinfo[i] = dinfo[i-1];
cdrom[i] = cdrom[i-1];
}
cdrom[0] = _cdrom;
dinfo[0].drive = (Bit8u)_drive;
dinfo[0].physDrive = toupper(physicalPath[0]);
} else {
dinfo[numDrives].drive = (Bit8u)_drive;
dinfo[numDrives].physDrive = toupper(physicalPath[0]);
numDrives++;
// stop audio
StopAudio(subUnit);
return result;
}
return 4;
numDrives++;
// stop audio
StopAudio(subUnit);
return result;
};
PhysPt CMscdex::GetDefaultBuffer(void)
@ -1134,6 +1199,12 @@ int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit)
return result;
};
int MSCDEX_RemoveDrive(char driveLetter)
{
if(!mscdex) return 0;
return mscdex->RemoveDrive(driveLetter-'A');
};
bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name)
{
return mscdex->GetVolumeName(subUnit,name);

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_programs.cpp,v 1.61 2006-06-01 06:44:22 qbix79 Exp $ */
/* $Id: dos_programs.cpp,v 1.62 2006-06-22 13:15:07 qbix79 Exp $ */
#include <stdlib.h>
#include <string.h>
@ -51,23 +51,26 @@ public:
DOS_Drive * newdrive;char drive;
std::string label;
std::string umount;
/* Check for unmounting */
if (cmd->FindString("-u",umount,false)) {
umount[0] = toupper(umount[0]);
int i_drive = umount[0]-'A';
if(i_drive < DOS_DRIVES && Drives[i_drive]) {
try { /* Check if virtualdrive */
if( dynamic_cast<localDrive*>(Drives[i_drive]) == 0 ) throw 0;
}
catch(...) {
switch (Drives[i_drive]->UnMount()) {
case 0:
Drives[i_drive] = 0;
if(i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]);
break;
case 1:
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL"));
return;
break;
case 2:
WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS"));
break;
}
if(i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
delete Drives[i_drive];
Drives[i_drive] = 0;
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]);
} else {
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]);
}
@ -229,6 +232,10 @@ public:
case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break;
default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break;
};
if (error && error!=5) {
delete newdrive;
return;
}
} else {
/* Give a warning when mount c:\ or the / */
#if defined (WIN32) || defined(OS2)
@ -657,6 +664,32 @@ public:
Bit32u imagesize;
char drive;
std::string label;
std::string umount;
/* Check for unmounting */
if (cmd->FindString("-u",umount,false)) {
umount[0] = toupper(umount[0]);
int i_drive = umount[0]-'A';
if (i_drive < DOS_DRIVES && Drives[i_drive]) {
switch (Drives[i_drive]->UnMount()) {
case 0:
Drives[i_drive] = 0;
if (i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCES"),umount[0]);
break;
case 1:
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NO_VIRTUAL"));
break;
case 2:
WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS"));
break;
}
} else {
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_NOT_MOUNTED"),umount[0]);
}
return;
}
std::string type="hdd";
std::string fstype="fat";
@ -777,7 +810,7 @@ public:
case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break;
default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break;
};
if (error) {
if (error && error!=5) {
delete newdrive;
return;
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_fat.cpp,v 1.15 2006-05-31 14:22:00 qbix79 Exp $ */
/* $Id: drive_fat.cpp,v 1.16 2006-06-22 13:15:07 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -704,6 +704,11 @@ Bit32u fatDrive::getFirstFreeClust(void) {
bool fatDrive::isRemote(void) { return false; }
bool fatDrive::isRemovable(void) { return false; }
Bits fatDrive::UnMount(void) {
delete this;
return 0;
}
Bit8u fatDrive::GetMediaByte(void) { return loadedDisk->GetBiosType(); }
bool fatDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes) {

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_iso.cpp,v 1.13 2006-04-23 14:20:58 c2woody Exp $ */
/* $Id: drive_iso.cpp,v 1.14 2006-06-22 13:15:07 qbix79 Exp $ */
#include <cctype>
#include <cstring>
@ -138,6 +138,7 @@ Bit16u isoFile::GetInformation(void)
return 0x40; // read-only drive
}
int MSCDEX_RemoveDrive(char driveLetter);
int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit);
bool MSCDEX_HasMediaChanged(Bit8u subUnit);
bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name);
@ -153,7 +154,9 @@ isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &e
if (!error) {
if (loadImage()) {
strcpy(info, "isoDrive");
strcpy(info, "isoDrive ");
strcat(info, fileName);
this->driveLetter = driveLetter;
this->mediaid = mediaid;
char buffer[32] = { 0 };
if (!MSCDEX_GetVolumeName(subUnit, buffer)) strcpy(buffer, "");
@ -373,6 +376,14 @@ bool isoDrive::isRemovable(void)
return true;
}
Bits isoDrive::UnMount(void) {
if(MSCDEX_RemoveDrive(driveLetter)) {
delete this;
return 0;
}
return 2;
}
int isoDrive::GetDirIterator(const isoDirEntry* de)
{
int dirIterator = nextFreeDirIterator;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_local.cpp,v 1.68 2006-05-14 19:57:24 qbix79 Exp $ */
/* $Id: drive_local.cpp,v 1.69 2006-06-22 13:15:07 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -411,6 +411,11 @@ bool localDrive::isRemovable(void) {
return false;
}
Bits localDrive::UnMount(void) {
delete this;
return 0;
}
localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) {
strcpy(basedir,startdir);
sprintf(info,"local directory %s",startdir);
@ -535,6 +540,7 @@ bool localFile::UpdateDateTimeFromHost(void) {
// CDROM DRIVE
// ********************************************
int MSCDEX_RemoveDrive(char driveLetter);
int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit);
bool MSCDEX_HasMediaChanged(Bit8u subUnit);
bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name);
@ -545,7 +551,9 @@ cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _byt
{
// Init mscdex
error = MSCDEX_AddDrive(driveLetter,startdir,subUnit);
strcpy(info,"CDRom.");
strcpy(info, "CDRom ");
strcat(info, startdir);
this->driveLetter = driveLetter;
// Get Volume Label
char name[32];
if (MSCDEX_GetVolumeName(subUnit,name)) dirCache.SetLabel(name);
@ -632,3 +640,11 @@ bool cdromDrive::isRemote(void) {
bool cdromDrive::isRemovable(void) {
return true;
}
Bits cdromDrive::UnMount(void) {
if(MSCDEX_RemoveDrive(driveLetter)) {
delete this;
return 0;
}
return 2;
}

View file

@ -176,7 +176,7 @@ bool Virtual_Drive::TestDir(char * dir) {
}
bool Virtual_Drive::FileStat(const char* name, FileStat_Block * const stat_block){
VFILE_Block * cur_file=first_file;
VFILE_Block * cur_file=first_file;
while (cur_file) {
if (strcasecmp(name,cur_file->name)==0) {
stat_block->attr=DOS_ATTR_ARCHIVE;
@ -267,3 +267,8 @@ bool Virtual_Drive::isRemote(void) {
bool Virtual_Drive::isRemovable(void) {
return false;
}
Bits Virtual_Drive::UnMount(void) {
return 1;
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drives.h,v 1.32 2006-04-17 10:45:32 qbix79 Exp $ */
/* $Id: drives.h,v 1.33 2006-06-22 13:15:07 qbix79 Exp $ */
#ifndef _DRIVES_H__
#define _DRIVES_H__
@ -50,6 +50,7 @@ public:
virtual Bit8u GetMediaByte(void);
virtual bool isRemote(void);
virtual bool isRemovable(void);
virtual Bits UnMount(void);
private:
char basedir[CROSS_LEN];
friend void DOS_Shell::CMD_SUBST(char* args);
@ -142,6 +143,7 @@ public:
virtual Bit8u GetMediaByte(void);
virtual bool isRemote(void);
virtual bool isRemovable(void);
virtual Bits UnMount(void);
public:
Bit32u getAbsoluteSectFromBytePos(Bit32u startClustNum, Bit32u bytePos);
Bit32u getSectorSize(void);
@ -204,8 +206,10 @@ public:
virtual void SetDir(const char* path);
virtual bool isRemote(void);
virtual bool isRemovable(void);
virtual Bits UnMount(void);
private:
Bit8u subUnit;
char driveLetter;
};
#ifdef _MSC_VER
@ -304,6 +308,7 @@ public:
virtual void EmptyCache(void){}
virtual bool isRemote(void);
virtual bool isRemovable(void);
virtual Bits UnMount(void);
bool readSector(Bit8u *buffer, Bit32u sector);
virtual char const* GetLabel(void) {return discLabel;};
private:
@ -335,6 +340,7 @@ private:
isoDirEntry rootEntry;
Bit8u mediaid;
Bit8u subUnit;
char driveLetter;
char discLabel[32];
};
@ -360,6 +366,7 @@ public:
void EmptyCache(void){}
bool isRemote(void);
virtual bool isRemovable(void);
virtual Bits UnMount(void);
private:
VFILE_Block * search_file;
};