mirror of
https://github.com/kevinbentley/Descent3.git
synced 2025-01-23 12:08:56 +00:00
855 lines
23 KiB
C++
855 lines
23 KiB
C++
/*
|
|
* Descent 3
|
|
* Copyright (C) 2024 Parallax Software
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/*
|
|
* $Logfile: /DescentIII/Main/ddio_lnx/lnxcdrom.cpp $
|
|
* $Revision: 1.12 $
|
|
* $Date: 2004/12/05 04:00:20 $
|
|
* $Author: ryan $
|
|
*
|
|
* Linux cdrom routines (borrowed some code from SDL)
|
|
*
|
|
* $Log: lnxcdrom.cpp,v $
|
|
* Revision 1.12 2004/12/05 04:00:20 ryan
|
|
* MacOS X patches.
|
|
*
|
|
* Revision 1.11 2004/03/21 17:11:39 kevinb
|
|
* Fixes so linux will compile again. Tested with gcc-2.96
|
|
*
|
|
* Revision 1.10 2004/02/25 00:04:06 ryan
|
|
* Removed loki_utils dependency and ported to MacOS X (runs, but incomplete).
|
|
*
|
|
* Revision 1.9 2001/01/11 11:41:29 icculus
|
|
* Mounting fix.
|
|
*
|
|
* Revision 1.8 2000/07/07 01:45:32 icculus
|
|
* Reinit functionality.
|
|
*
|
|
* Revision 1.7 2000/07/06 22:15:49 icculus
|
|
* Changed to work with GetMultiCDPath()'s new behaviour.
|
|
*
|
|
* Revision 1.6 2000/06/29 08:57:34 icculus
|
|
* Took out the Mount() and Unmount() code, 'cause it was retarded. Do it
|
|
* outside the program.
|
|
*
|
|
* Revision 1.5 2000/06/29 06:41:23 icculus
|
|
* mad commits.
|
|
*
|
|
* Revision 1.4 2000/06/24 01:15:15 icculus
|
|
* patched to compile.
|
|
*
|
|
* Revision 1.3 2000/04/27 11:16:34 icculus
|
|
* Took out SDL_Init() call. It's handled in $/Main/lnxmain.cpp, now.
|
|
*
|
|
* Revision 1.2 2000/04/24 03:18:00 icculus
|
|
* SDLified and loki_utilified this code. Lots of paradigm fixes, too. It's
|
|
* VERY different now.
|
|
*
|
|
* Revision 1.1.1.1 2000/04/18 00:00:33 icculus
|
|
* initial checkin
|
|
*
|
|
*
|
|
* 5 12/01/99 3:30p Jeff
|
|
* ddio_GetCDDrive now returns NULL instead of ""
|
|
*
|
|
* 4 10/05/99 12:54p Jeff
|
|
* removed system() call
|
|
*
|
|
* 3 10/02/99 6:50p Jeff
|
|
* pretty solid cd-rom support now. Tested and seems to work. Need to
|
|
* figure out a better way of handlng /proc/mounts
|
|
*
|
|
* 2 10/02/99 3:00p Jeff
|
|
* slightly rewritten due to some early design flaws (namely multiple
|
|
* cd-rom drives, and the drive would be mounted when you try to switch
|
|
* CDs). This should be better (though only 1 cd-rom drive is supported
|
|
* now). May not compile yet.
|
|
*
|
|
* 1 10/01/99 7:44p Jeff
|
|
* initial checkin
|
|
*
|
|
* $NoKeywords: $
|
|
*/
|
|
|
|
#include <sys/mount.h>
|
|
#include <sys/types.h>
|
|
#include <stdlib.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include <SDL.h>
|
|
#include "mem.h"
|
|
#include "mono.h"
|
|
#include "ddio.h"
|
|
#include "debug.h"
|
|
#include "pserror.h"
|
|
#include "loki_utils.h"
|
|
|
|
#define VD_LSN 16 // first logical sector of volume descriptor table
|
|
#define CDROM_LSECSZ 2048 // initial logical sector size of a CDROM
|
|
#define CDROM_LBS CDROM_LSECSZ
|
|
|
|
class system_cdroms {
|
|
public:
|
|
system_cdroms();
|
|
~system_cdroms();
|
|
|
|
bool Mount(void);
|
|
bool UnMount(void);
|
|
|
|
// Given a device specified by the user, it will make it the
|
|
// default device for the system.
|
|
bool SetDefaultDevice(char *device);
|
|
|
|
// resets the device mountpoint. If the mountpoint was created, it will
|
|
// unmount the drive and remove the mountpoint directory
|
|
void ResetMountpoint(void);
|
|
|
|
// This function will check the default device to see if it
|
|
// has a CD in it with the given volume. If it doesn't
|
|
// then it will unmount the device (if it is mounted), in preparation
|
|
// for a CD switch. If it does have the correct CD in it, then
|
|
// it wil be mounted (if it isn't already) and the mount position
|
|
// will be given in mountpoint. If it can't mount it will return false;
|
|
bool PrepareForVolume(char *volume, char *mountpoint);
|
|
|
|
// Returns the device name of the default drive
|
|
const char *GetDeviceName(void);
|
|
|
|
// Returns the volume name of the default drive
|
|
const char *GetVolumeName(void);
|
|
|
|
// Returns true if a CD is in the default device drive
|
|
bool IsCdInDrive(void);
|
|
|
|
private:
|
|
bool IsCdInDrive(int drive);
|
|
const char *CDName(int drive);
|
|
const char *GetVolume(int drive);
|
|
int GetNumCDRoms(void);
|
|
|
|
// checks to see if the given cd-rom device is mounted
|
|
// if so, it returns true and fills in mountpoint with the
|
|
// directory it is mounted in
|
|
bool IsDeviceMounted(const char *device, char *mountpoint, int max_size);
|
|
// Check a drive to see if it is a CD-ROM
|
|
int CheckDrive(char *drive, struct stat *stbuf);
|
|
// Add a CD-ROM drive to our list of valid drives
|
|
void AddDrive(char *drive, struct stat *stbuf);
|
|
void Shutdown(void);
|
|
|
|
// Locks the CD-ROM
|
|
void LockDevice(void);
|
|
// UnLocks the CD-ROM
|
|
void UnLockDevice(void);
|
|
// This function will go through our list of devices
|
|
// when it comes across the first CD-ROM (which can only be
|
|
// detected when a CD is in the drive), it will make it the default
|
|
// device.
|
|
public:
|
|
void FindDefaultDevice(void);
|
|
void reinit(void);
|
|
|
|
private:
|
|
// Queries the settings for the default drive
|
|
// First it checks to see if the drive is already mounted
|
|
// If it is, it's mountpoint is saved and we continue
|
|
// If it isn't mounted, the it will create a mountpoint for the device
|
|
// and mount it there.
|
|
void QueryDefaultDevice(void);
|
|
|
|
bool m_CreatedMountPoint;
|
|
bool m_DefaultMounted;
|
|
|
|
public: // !!! hack. Make an accessor method.
|
|
char m_MountedDir[_MAX_PATH];
|
|
|
|
private:
|
|
char m_MountDirectory[_MAX_PATH];
|
|
int m_NumCDRoms;
|
|
int m_DeviceToUse;
|
|
};
|
|
|
|
system_cdroms CDROM_Devices;
|
|
|
|
// Given a device/drive, this marks it as the default CD-ROM drive
|
|
void ddio_MarkDefaultCDDrive(char *drive) {
|
|
bool ret = CDROM_Devices.SetDefaultDevice(drive);
|
|
/*
|
|
if(!ret)
|
|
{
|
|
Error("Unable to set %s as the default CD-ROM drive\n",drive);
|
|
}
|
|
*/
|
|
}
|
|
|
|
void ddio_ReinitCDSystem(void) { CDROM_Devices.reinit(); }
|
|
|
|
// Give a volume label to look for, and if it's found returns a path
|
|
// If it isn't found, return NULL
|
|
char *ddio_GetCDDrive(char *vol) {
|
|
static char drivepath[_MAX_PATH];
|
|
|
|
/*
|
|
if(*vol=='\0')
|
|
return NULL;
|
|
|
|
bool ret = CDROM_Devices.PrepareForVolume(vol,drivepath);
|
|
if(!ret)
|
|
{
|
|
// nope...not yet
|
|
return NULL;
|
|
}
|
|
*/
|
|
|
|
CDROM_Devices.FindDefaultDevice(); // returns if already set.
|
|
|
|
if (CDROM_Devices.Mount() == false)
|
|
return (NULL);
|
|
|
|
strcpy(drivepath, CDROM_Devices.m_MountedDir);
|
|
return drivepath;
|
|
}
|
|
|
|
void cdrom_system_shutdown(void) { CDROM_Devices.ResetMountpoint(); }
|
|
|
|
void cdrom_set_system_shutdown(void) {
|
|
static bool set = false;
|
|
if (set)
|
|
return;
|
|
set = true;
|
|
atexit(cdrom_system_shutdown);
|
|
}
|
|
|
|
system_cdroms::system_cdroms(void) { reinit(); }
|
|
|
|
void system_cdroms::reinit(void) {
|
|
SDL_QuitSubSystem(SDL_INIT_CDROM);
|
|
SDL_Init(SDL_INIT_CDROM);
|
|
m_CreatedMountPoint = false;
|
|
m_NumCDRoms = 0;
|
|
m_DeviceToUse = -1;
|
|
m_DefaultMounted = false;
|
|
|
|
m_NumCDRoms = GetNumCDRoms();
|
|
} // reinit
|
|
|
|
system_cdroms::~system_cdroms(void) {
|
|
// SDL_QuitSubSystem(SDL_INIT_CDROM);
|
|
}
|
|
|
|
int system_cdroms::GetNumCDRoms(void) { return (SDL_CDNumDrives()); }
|
|
|
|
// Returns the device name of the default drive
|
|
const char *system_cdroms::GetDeviceName(void) { return CDName(m_DeviceToUse); }
|
|
|
|
// Returns the volume name of the default drive
|
|
const char *system_cdroms::GetVolumeName(void) { return GetVolume(m_DeviceToUse); }
|
|
|
|
const char *system_cdroms::CDName(int drive) { return (SDL_CDName(drive)); }
|
|
|
|
const char *system_cdroms::GetVolume(int drive) {
|
|
#if 1 // MACOSX
|
|
assert(0);
|
|
#else
|
|
static char buffer[256];
|
|
|
|
if (drive < 0 || drive >= m_NumCDRoms)
|
|
return NULL;
|
|
|
|
struct iso_primary_descriptor *ipd;
|
|
int cdfd, cdromfmt = 0;
|
|
|
|
if (!IsCdInDrive(drive))
|
|
return NULL;
|
|
|
|
cdfd = open(CDName(drive), (O_RDONLY | O_EXCL | O_NONBLOCK), 0);
|
|
if (cdfd < 0)
|
|
return NULL;
|
|
|
|
// locate at the beginning of the descriptor table
|
|
lseek(cdfd, VD_LSN * CDROM_LSECSZ, SEEK_SET);
|
|
|
|
ipd = (struct iso_primary_descriptor *)buffer;
|
|
|
|
// walk descriptor table
|
|
for (;;) {
|
|
unsigned char type;
|
|
read(cdfd, buffer, sizeof(buffer));
|
|
|
|
// make sure it's ISO format
|
|
if (cdromfmt == 0) {
|
|
if (strncmp(ipd->id, ISO_STANDARD_ID, sizeof(ipd->id)) != 0) {
|
|
// not an ISO9660 cdrom
|
|
close(cdfd);
|
|
return NULL;
|
|
} else {
|
|
// ISO9660
|
|
cdromfmt = 1;
|
|
}
|
|
}
|
|
|
|
// type of descriptor
|
|
type = (unsigned char)ipd->type[0];
|
|
|
|
// terminating volume
|
|
if (type == ISO_VD_END) {
|
|
break;
|
|
}
|
|
|
|
// ISO 9660 filestructure
|
|
if (cdromfmt == 1 && type == ISO_VD_PRIMARY && !strncmp(ipd->id, ISO_STANDARD_ID, sizeof(ipd->id))) {
|
|
char *ptr;
|
|
int len = sizeof(ipd->volume_id);
|
|
bcopy(ipd->volume_id, buffer, len);
|
|
buffer[len] = '\0';
|
|
|
|
for (ptr = buffer + len - 1; ptr > buffer; ptr--) {
|
|
if (*ptr == ' ') {
|
|
*ptr = 0;
|
|
}
|
|
}
|
|
|
|
close(cdfd);
|
|
return buffer;
|
|
}
|
|
}
|
|
|
|
close(cdfd);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
// Returns true if a CD is in the default device drive
|
|
bool system_cdroms::IsCdInDrive(void) { return IsCdInDrive(m_DeviceToUse); }
|
|
|
|
bool system_cdroms::IsCdInDrive(int drive) {
|
|
// int cdfd,is_in=0;
|
|
// struct cdrom_subchnl info;
|
|
// struct stat stbuf;
|
|
CDstatus cdStat;
|
|
SDL_CD cdInfo;
|
|
bool retVal = true;
|
|
|
|
if (drive < 0 || drive >= m_NumCDRoms)
|
|
retVal = false;
|
|
else {
|
|
cdStat = SDL_CDStatus(&cdInfo);
|
|
if ((cdStat == CD_TRAYEMPTY) || (cdStat == CD_ERROR))
|
|
retVal = false;
|
|
} // else
|
|
return (retVal);
|
|
}
|
|
|
|
static int read_file_string(FILE *fd, char *buffer, int maxsize) {
|
|
int ret;
|
|
int size = 0;
|
|
|
|
ret = fgetc(fd);
|
|
while (ret != EOF && size < maxsize) {
|
|
if (ret == '\n') {
|
|
break;
|
|
} else {
|
|
// check for a number
|
|
if (ret == '\\') {
|
|
// we have a number coming
|
|
char val = 0;
|
|
char c[3];
|
|
c[0] = fgetc(fd);
|
|
c[1] = fgetc(fd);
|
|
c[2] = fgetc(fd);
|
|
val = ((c[0] - '0') * 64) + ((c[1] - '0') * 8) + (c[0] - '0');
|
|
*buffer = val;
|
|
buffer++;
|
|
} else {
|
|
*buffer = ret;
|
|
buffer++;
|
|
}
|
|
size++;
|
|
}
|
|
ret = fgetc(fd);
|
|
}
|
|
|
|
*buffer = '\0';
|
|
|
|
return size;
|
|
}
|
|
|
|
static bool cdrom_CopyFile(char *dst_path, const char *src_path) {
|
|
char *buf;
|
|
int buf_size;
|
|
int dest_desc;
|
|
int source_desc;
|
|
int n_read;
|
|
struct stat sb;
|
|
char *cp;
|
|
int *ip;
|
|
bool return_val = true;
|
|
off_t n_read_total = 0;
|
|
int last_write_made_hole = 0;
|
|
int make_holes = 0;
|
|
|
|
source_desc = open(src_path, O_RDONLY);
|
|
if (source_desc < 0) {
|
|
return false;
|
|
}
|
|
|
|
/* Create the new regular file with small permissions initially,
|
|
to not create a security hole. */
|
|
dest_desc = open(dst_path, O_WRONLY | O_CREAT | O_TRUNC, 0666);
|
|
if (dest_desc < 0) {
|
|
return_val = false;
|
|
goto ret2;
|
|
}
|
|
|
|
/* Find out the optimal buffer size. */
|
|
if (fstat(dest_desc, &sb)) {
|
|
return_val = false;
|
|
goto ret;
|
|
}
|
|
buf_size = sb.st_blksize;
|
|
|
|
/* Make a buffer with space for a sentinel at the end. */
|
|
buf = (char *)alloca(buf_size + sizeof(int));
|
|
|
|
for (;;) {
|
|
n_read = read(source_desc, buf, buf_size);
|
|
if (n_read < 0) {
|
|
return_val = false;
|
|
goto ret;
|
|
}
|
|
if (n_read == 0)
|
|
break;
|
|
|
|
n_read_total += n_read;
|
|
|
|
ip = 0;
|
|
|
|
if (write(dest_desc, buf, n_read) < 0) {
|
|
return_val = false;
|
|
goto ret;
|
|
}
|
|
}
|
|
|
|
ret:
|
|
if (close(dest_desc) < 0) {
|
|
return_val = false;
|
|
}
|
|
ret2:
|
|
if (close(source_desc) < 0) {
|
|
return_val = false;
|
|
}
|
|
|
|
return return_val;
|
|
}
|
|
|
|
static bool checkDevMount(const char *device, const char *mntfname, char *mountpoint) {
|
|
bool retVal = false;
|
|
#if 1 // MACOSX
|
|
assert(0);
|
|
#else
|
|
bool getOut = false;
|
|
struct mntent *mntEntry;
|
|
|
|
FILE *mountFile = setmntent(mntfname, "r");
|
|
if (mountFile == NULL) {
|
|
mprintf((0, "setmntent(\"%s\", \"r\"); failed! errno == (%d).", mntfname, errno));
|
|
Int3();
|
|
return (false);
|
|
} // if
|
|
|
|
do {
|
|
mntEntry = getmntent(mountFile);
|
|
if (mntEntry == NULL)
|
|
getOut = true;
|
|
else {
|
|
if (strcmp(device, mntEntry->mnt_fsname) == 0) // found device?
|
|
{
|
|
strcpy(mountpoint, mntEntry->mnt_dir); //!!! overflows?
|
|
getOut = retVal = true;
|
|
} // if
|
|
} // else
|
|
} while (getOut == false);
|
|
|
|
endmntent(mountFile);
|
|
#endif
|
|
return (retVal);
|
|
}
|
|
|
|
bool system_cdroms::IsDeviceMounted(const char *device, char *mountpoint, int max_size) {
|
|
#if 1 // MACOSX
|
|
int rc = loki_getmountpoint(device, mountpoint, max_size);
|
|
return (rc > 0);
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
bool system_cdroms::Mount(void) {
|
|
if (m_DeviceToUse == -1)
|
|
return false;
|
|
|
|
// make sure the atexit is set so we can properly clear all created tmp dirs
|
|
cdrom_set_system_shutdown();
|
|
|
|
// first check to see if it is mounted
|
|
const char *name = CDName(m_DeviceToUse);
|
|
char mountpoint[_MAX_PATH];
|
|
if (IsDeviceMounted(name, mountpoint, sizeof(mountpoint))) {
|
|
strcpy(m_MountedDir, mountpoint);
|
|
m_DefaultMounted = true;
|
|
return true;
|
|
}
|
|
|
|
/* don't do this.
|
|
// Not mounted? Do it ourselves.
|
|
// so we now have our directory, try to mount
|
|
unsigned long int rwflag = MS_MGC_VAL|MS_RDONLY;
|
|
int ret = mount(name,m_MountedDir,"iso9660",rwflag,NULL);
|
|
if(ret!=0)
|
|
{
|
|
switch(errno)
|
|
{
|
|
case EPERM:
|
|
fprintf(stdout,"Unable to mount %s, you are not superuser\n",name);
|
|
break;
|
|
case ENODEV:
|
|
fprintf(stdout,"iso9660 filesystem not supported by kernel\n");
|
|
break;
|
|
case ENOTBLK:
|
|
fprintf(stdout,"Device %s not a block device\n",name);
|
|
break;
|
|
case EBUSY:
|
|
fprintf(stdout,"Device %s already mounted\n",name);
|
|
Int3();
|
|
break;
|
|
case ENAMETOOLONG:
|
|
fprintf(stdout,"Attempting to mount %s to %s (but name too long)\n",name,m_MountedDir);
|
|
break;
|
|
case ENOTDIR:
|
|
fprintf(stdout,"%s not a directory\n",m_MountedDir);
|
|
break;
|
|
default:
|
|
//case EINVAL:
|
|
//case EFAULT:
|
|
//case ENOMEM:
|
|
//case EMXIO:
|
|
//case EMFILE:
|
|
//case ENOENT:
|
|
//case EACCES:
|
|
fprintf(stdout,"Unknown error %d trying to mount %s\n",errno,name);
|
|
break;
|
|
}
|
|
}else
|
|
{
|
|
// we mounted!
|
|
m_DefaultMounted = true;
|
|
LockDevice();//make sure it is locked
|
|
return true;
|
|
}
|
|
*/
|
|
return false;
|
|
}
|
|
|
|
bool system_cdroms::UnMount(void) {
|
|
if (m_DeviceToUse == -1)
|
|
return false;
|
|
/*
|
|
// find the drive that is mounted
|
|
char mountpoint[_MAX_PATH];
|
|
const char *name = CDName(m_DeviceToUse);
|
|
if (IsDeviceMounted(name,mountpoint,sizeof (mountpoint)) == false)
|
|
{
|
|
m_DefaultMounted = false;
|
|
UnLockDevice();//make sure it is unlocked
|
|
return true;//drive isn't mounted anywhere
|
|
}
|
|
|
|
UnLockDevice();//make sure it is unlocked
|
|
int ret = umount(name);
|
|
if(ret==0)
|
|
{
|
|
m_DefaultMounted = false;
|
|
return true;
|
|
}else
|
|
{
|
|
mprintf((0,"Error %d trying to unmount %s\n",errno,name));
|
|
//lock it again...something went wrong
|
|
LockDevice();
|
|
return false;
|
|
}
|
|
*/
|
|
return false;
|
|
}
|
|
|
|
// Given a device specified by the user, it will make it the
|
|
// default device for the system.
|
|
bool system_cdroms::SetDefaultDevice(char *device) {
|
|
/*
|
|
if(m_DeviceToUse!=-1)
|
|
{
|
|
Int3();
|
|
return false;
|
|
}
|
|
*/
|
|
// first find which id the device is
|
|
int i, dev_id = -1;
|
|
|
|
for (i = 0; i < m_NumCDRoms; i++) {
|
|
if (strcmp(device, CDName(i)) == 0) {
|
|
dev_id = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (dev_id == -1) {
|
|
// printf("CDROM: Default device (%s) not found\n",device);
|
|
return false;
|
|
}
|
|
|
|
m_DeviceToUse = dev_id;
|
|
QueryDefaultDevice();
|
|
return true;
|
|
}
|
|
|
|
// This function will check the default device to see if it
|
|
// has a CD in it with the given volume. If it doesn't
|
|
// then it will unmount the device (if it is mounted), in preparation
|
|
// for a CD switch. If it does have the correct CD in it, then
|
|
// it wil be mounted (if it isn't already) and the mount position
|
|
// will be given in mountpoint. If it can't mount it will return false;
|
|
bool system_cdroms::PrepareForVolume(char *volume, char *mountpoint) {
|
|
if (m_DeviceToUse == -1) {
|
|
// uh oh, we don't even know what device to use yet...
|
|
// so, we'll look at everything we have, checking for volumes
|
|
// the first volume successfully returned will be are default
|
|
// device.
|
|
FindDefaultDevice();
|
|
if (m_DeviceToUse == -1) {
|
|
// still nothing
|
|
return false;
|
|
}
|
|
}
|
|
|
|
char *vol = (char *)GetVolumeName();
|
|
if (!vol) {
|
|
// no CD in the default device drive
|
|
return false;
|
|
}
|
|
|
|
// compare the CD in the drive to what we want
|
|
if (!strcmp(vol, volume)) {
|
|
// this is the CD we want!
|
|
// lets make sure it is mounted
|
|
bool ret = Mount();
|
|
if (ret) {
|
|
strcpy(mountpoint, m_MountedDir);
|
|
return true;
|
|
} else {
|
|
// we couldn't mount!
|
|
mprintf((0, "CDROM: Unable to mount drive though we must have it mounted\n"));
|
|
Int3();
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// ok, the CD in there is NOT what we want
|
|
// lets unmount the drive so the user can switch CDs
|
|
bool ret = UnMount();
|
|
if (!ret) {
|
|
mprintf((0, "Unable to unmount drive\n"));
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
// This function will go through our list of devices
|
|
// when it comes across the first CD-ROM (which can only be
|
|
// detected when a CD is in the drive), it will make it the default
|
|
// device.
|
|
void system_cdroms::FindDefaultDevice(void) {
|
|
if (m_DeviceToUse != -1)
|
|
return;
|
|
|
|
// 0 is SDL's default CD-ROM drive id. But use -1 if there are none.
|
|
if (GetNumCDRoms() <= 0) {
|
|
m_DeviceToUse = -1;
|
|
mprintf((0, "CDROM: No drives found to be made default!"));
|
|
return;
|
|
} // if
|
|
else // there WAS at least one drive...
|
|
{
|
|
m_DeviceToUse = 0; // default device.
|
|
mprintf((0, "CDROM: Making device \"%s\" default CD-ROM drive.", CDName(m_DeviceToUse)));
|
|
} // else
|
|
|
|
// we found the device we want to use for our CD-ROM.
|
|
// now we need to query some information about the default drive
|
|
// like if it's currently mounted (if so where, and save that info),
|
|
// and if it's not mounted, then we need to create a mountpoint for it and
|
|
// use that
|
|
QueryDefaultDevice();
|
|
}
|
|
|
|
// Queries the settings for the default drive
|
|
// First it checks to see if the drive is already mounted
|
|
// If it is, it's mountpoint is saved and we continue
|
|
// If it isn't mounted, the it will create a mountpoint for the device
|
|
// and mount it there.
|
|
void system_cdroms::QueryDefaultDevice(void) {
|
|
if (m_DeviceToUse == -1) {
|
|
Int3();
|
|
return;
|
|
}
|
|
|
|
// first check to see if it is already mounted
|
|
char mountpoint[_MAX_PATH];
|
|
bool ismounted = false;
|
|
const char *device = CDName(m_DeviceToUse);
|
|
|
|
if (IsDeviceMounted(device, mountpoint, sizeof(mountpoint))) {
|
|
mprintf((0, "CDROM: Default device already mounted at %s...\n", mountpoint));
|
|
|
|
// save the mountpoint for use
|
|
strcpy(m_MountedDir, mountpoint);
|
|
m_DefaultMounted = true;
|
|
return;
|
|
}
|
|
|
|
#if 0 // rcg10052000 BAD! BADBADBAD!
|
|
// see if there's a default dir for mounting this thing.
|
|
if (checkDevMount(device, "/etc/fstab", m_MountedDir) == false)
|
|
{
|
|
// otherwise, we'll make a mountpoint and mount it
|
|
// remember that the current working directory, unless overridden
|
|
// by the user, is "$HOME/.loki/", so this is "okay", I guess.
|
|
strcpy(mountpoint, loki_getprefpath());
|
|
char *dptr = mountpoint + strlen(mountpoint);
|
|
char *sptr = (char *) device;
|
|
*dptr = 'T'; dptr++;
|
|
*dptr = 'M'; dptr++;
|
|
*dptr = 'P'; dptr++;
|
|
while(*sptr)
|
|
{
|
|
if(*sptr!='/')
|
|
{
|
|
*dptr = *sptr;
|
|
dptr++;
|
|
}
|
|
sptr++;
|
|
}
|
|
*dptr = '0';dptr++;
|
|
*dptr = '\0';
|
|
|
|
dptr = mountpoint + strlen(mountpoint) - 1;
|
|
|
|
// now keep attempting to make the directory until we do or can't even try
|
|
bool bail = true;
|
|
while( ((*dptr)-'0')<=9 )
|
|
{
|
|
if(!ddio_DirExists(mountpoint))
|
|
{
|
|
if(ddio_CreateDir(mountpoint))
|
|
{
|
|
// we did it
|
|
bail = false;
|
|
break;
|
|
}
|
|
}else
|
|
{
|
|
*dptr = (*dptr)++;
|
|
}
|
|
}
|
|
|
|
if(bail)
|
|
{
|
|
Error("Unable to create a mountpoint for device %s\n", device);
|
|
exit(1);
|
|
return;
|
|
}
|
|
|
|
// save the mountpoint for use
|
|
mprintf((0,"CDROM: Mountpoint created for device %s at %s\n",device,mountpoint));
|
|
strcpy(m_MountedDir,mountpoint);
|
|
m_CreatedMountPoint = true;
|
|
} // if
|
|
|
|
Mount();
|
|
#endif
|
|
}
|
|
|
|
// resets the device mountpoint. If the mountpoint was created, it will
|
|
// unmount the drive and remove the mountpoint directory
|
|
void system_cdroms::ResetMountpoint(void) {
|
|
if (!m_CreatedMountPoint)
|
|
return;
|
|
|
|
UnMount();
|
|
ddio_RemoveDir(m_MountedDir);
|
|
}
|
|
|
|
// Locks the CD-ROM
|
|
void system_cdroms::LockDevice(void) {
|
|
/*
|
|
if(m_DeviceToUse==-1)
|
|
return;
|
|
|
|
int retval;
|
|
int fileid;
|
|
fileid = open(m_CDList[m_DeviceToUse]->name, (O_RDONLY|O_EXCL|O_NONBLOCK), 0);
|
|
if(fileid>=0)
|
|
{
|
|
int arg = 1;
|
|
//retval = ioctl(fileid,CDROM_LOCKDOOR,arg);
|
|
retval = ioctl(fileid,CDC_LOCK,arg);
|
|
if(retval<0)
|
|
{
|
|
mprintf((0,"CDROM: ioctl error locking drive (%d)\n",retval));
|
|
}
|
|
close(fileid);
|
|
}
|
|
*/
|
|
}
|
|
|
|
// UnLocks the CD-ROM
|
|
void system_cdroms::UnLockDevice(void) {
|
|
/*
|
|
if(m_DeviceToUse==-1)
|
|
return;
|
|
|
|
int retval;
|
|
int fileid;
|
|
fileid = open(m_CDList[m_DeviceToUse]->name, (O_RDONLY|O_EXCL|O_NONBLOCK), 0);
|
|
if(fileid>=0)
|
|
{
|
|
int arg = 0;
|
|
|
|
//retval = ioctl(fileid,CDROM_LOCKDOOR,arg);
|
|
retval = ioctl(fileid,CDC_LOCK,arg);
|
|
if(retval<0)
|
|
{
|
|
mprintf((0,"CDROM: ioctl error unlocking drive (%d)\n",retval));
|
|
}
|
|
close(fileid);
|
|
}
|
|
*/
|
|
}
|