1
0
Fork 0

Add Patch 1001897 by Martin. Disabled modem and ipx networking by default as they depend on libraries not everybody may have. Reduces alarmed firewall people and is nicer on unix hosts as port 23 is a bit tricky

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1904
This commit is contained in:
Peter Veenstra 2004-08-13 19:43:02 +00:00
parent 18f13c2b60
commit 02ff2737d7
11 changed files with 1390 additions and 19 deletions

View file

@ -177,6 +177,16 @@ else
AC_MSG_RESULT(no)
fi
AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support])
AC_CHECK_HEADER(SDL/SDL_sound.h,have_SDL_sound_h=yes,)
AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_lib=yes,,)
if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_lib = xyes ; then
LIBS="$LIBS -lSDL_sound"
AC_DEFINE(C_SDL_SOUND,1)
else
AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled])
fi
dnl Some host detection and actions for them
case "$target" in
*-*-cygwin* | *-*-mingw32*)

View file

@ -5,5 +5,5 @@ EXTRA_DIST = scsidefs.h wnaspi32.h
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \
dev_con.h dos_mscdex.cpp \
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp
drive_iso.cpp dev_con.h dos_mscdex.cpp \
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp

View file

@ -21,6 +21,7 @@
// SDL CDROM
// ******************************************************
#include <sys/stat.h>
#include "SDL.h"
#include "support.h"
#include "cdrom.h"
@ -175,8 +176,13 @@ int CDROM_GetMountType(char* path, int forceCD)
cdName = SDL_CDName(i);
if (strcmp(buffer,cdName)==0) return 0;
};
// TODO: Detect ISO
return 2;
// Detect ISO
struct stat file_stat;
stat(path, &file_stat);
if (S_ISREG(file_stat.st_mode)) return 1;
return 2;
};
// ******************************************************

View file

@ -5,10 +5,17 @@
#define MAX_ASPI_CDROM 5
#include <string.h>
#include <iostream>
#include <vector>
#include "dosbox.h"
#include "mem.h"
#include "mixer.h"
#include "SDL.h"
#include "SDL_thread.h"
#if defined(C_SDL_SOUND)
#include "SDL_sound.h"
#endif
#define RAW_SECTOR_SIZE 2352
#define COOKED_SECTOR_SIZE 2048
@ -95,6 +102,106 @@ public:
bool LoadUnloadMedia (bool unload) { return true; };
};
class CDROM_Interface_Image : public CDROM_Interface
{
private:
class TrackFile {
public:
virtual bool read(Bit8u *buffer, int seek, int count) = 0;
virtual int getLength() = 0;
};
class BinaryFile : public TrackFile {
public:
BinaryFile(const char *filename, bool &error);
~BinaryFile();
bool read(Bit8u *buffer, int seek, int count);
int getLength();
private:
BinaryFile();
std::ifstream *file;
};
#if defined(C_SDL_SOUND)
class AudioFile : public TrackFile {
public:
AudioFile(const char *filename, bool &error);
~AudioFile();
bool read(Bit8u *buffer, int seek, int count);
int getLength();
private:
AudioFile();
Sound_Sample *sample;
int lastCount;
int lastSeek;
};
#endif
struct Track {
int number;
int attr;
int start;
int length;
int skip;
int sectorSize;
bool mode2;
TrackFile *file;
};
public:
CDROM_Interface_Image (Bit8u subUnit);
virtual ~CDROM_Interface_Image (void);
void InitNewMedia (void);
bool SetDevice (char* path, int forceCD);
bool GetUPC (unsigned char& attr, char* upc);
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr);
bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
bool GetAudioStatus (bool& playing, bool& pause);
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
bool PlayAudioSector (unsigned long start,unsigned long len);
bool PauseAudio (bool resume);
bool StopAudio (void);
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
bool LoadUnloadMedia (bool unload);
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
static CDROM_Interface_Image* images[26];
private:
// player
static void CDAudioCallBack(Bit8u *stream, Bit32u len);
int GetTrack(int sector);
static struct imagePlayer {
CDROM_Interface_Image *cd;
MIXER_Channel *channel;
SDL_mutex *mutex;
Bit8u buffer[8192];
int bufLen;
int currFrame;
int targetFrame;
bool isPlaying;
bool isPaused;
} player;
void ClearTracks();
bool LoadIsoFile(char *filename);
bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2);
// cue sheet processing
bool LoadCueSheet(char *cuefile);
bool GetRealFileName(std::string& filename, std::string& pathname);
bool GetCueKeyword(std::string &keyword, std::istream &in);
bool GetCueFrame(int &frames, std::istream &in);
bool GetCueString(std::string &str, std::istream &in);
bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap);
static int refCount;
std::vector<Track> tracks;
std::string mcn;
Bit8u subUnit;
};
#if defined (WIN32) /* Win 32 */
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers

653
src/dos/cdrom_image.cpp Normal file
View file

@ -0,0 +1,653 @@
/*
* Copyright (C) 2002-2004 The DOSBox Team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cdrom_image.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */
#include <cctype>
#include <cmath>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <limits>
#include <sstream>
#include <vector>
#include <sys/stat.h>
#include "cdrom.h"
#include "drives.h"
#if not defined(WIN32)
#include <libgen.h>
#endif
using namespace std;
#define MAX_LINE_LENGTH 512
#define MAX_FILENAME_LENGTH 256
CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error)
{
file = new ifstream(filename, ios::in | ios::binary);
error = (file == NULL) || (file->fail());
}
CDROM_Interface_Image::BinaryFile::~BinaryFile()
{
delete file;
}
bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count)
{
file->seekg(seek, ios::beg);
file->read((char*)buffer, count);
return !(file->fail());
}
int CDROM_Interface_Image::BinaryFile::getLength()
{
file->seekg(0, ios::end);
int length = file->tellg();
if (file->fail()) return -1;
return length;
}
#if defined(C_SDL_SOUND)
CDROM_Interface_Image::AudioFile::AudioFile(const char *filename, bool &error)
{
Sound_AudioInfo desired = {AUDIO_S16, 2, 44100};
sample = Sound_NewSampleFromFile(filename, &desired, RAW_SECTOR_SIZE);
lastCount = RAW_SECTOR_SIZE;
lastSeek = 0;
error = (sample == NULL);
}
CDROM_Interface_Image::AudioFile::~AudioFile()
{
Sound_FreeSample(sample);
}
bool CDROM_Interface_Image::AudioFile::read(Bit8u *buffer, int seek, int count)
{
if (lastCount != count) {
int success = Sound_SetBufferSize(sample, count);
if (!success) return false;
}
if (lastSeek != (seek - count)) {
int success = Sound_Seek(sample, (int)((double)(seek) / 176.4f));
if (!success) return false;
}
lastSeek = seek;
int bytes = Sound_Decode(sample);
if (bytes < count) {
memcpy(buffer, sample->buffer, bytes);
memset(buffer + bytes, 0, count - bytes);
} else {
memcpy(buffer, sample->buffer, count);
}
return !(sample->flags & SOUND_SAMPLEFLAG_ERROR);
}
int CDROM_Interface_Image::AudioFile::getLength()
{
int time = 1;
int shift = 0;
if (!(sample->flags & SOUND_SAMPLEFLAG_CANSEEK)) return -1;
while (true) {
int success = Sound_Seek(sample, (unsigned int)(shift + time));
if (!success) {
if (time == 1) return lround((double)shift * 176.4f);
shift += time >> 1;
time = 1;
} else {
if (time > ((numeric_limits<int>::max() - shift) / 2)) return -1;
time = time << 1;
}
}
}
#endif
// initialize static members
int CDROM_Interface_Image::refCount = 0;
CDROM_Interface_Image* CDROM_Interface_Image::images[26];
CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = {
NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false };
CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit)
{
images[subUnit] = this;
if (refCount == 0) {
#if defined(C_SDL_SOUND)
Sound_Init();
#endif
player.mutex = SDL_CreateMutex();
if (!player.channel) {
player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO");
MIXER_SetMode(player.channel, MIXER_16STEREO);
}
MIXER_Enable(player.channel, true);
}
refCount++;
}
CDROM_Interface_Image::~CDROM_Interface_Image()
{
refCount--;
if (player.cd == this) player.cd = NULL;
ClearTracks();
if (refCount == 0) {
#if defined(C_SDL_SOUND)
Sound_Quit();
#endif
SDL_DestroyMutex(player.mutex);
MIXER_Enable(player.channel, false);
}
}
void CDROM_Interface_Image::InitNewMedia()
{
}
bool CDROM_Interface_Image::SetDevice(char* path, int forceCD)
{
if (LoadCueSheet(path)) return true;
if (LoadIsoFile(path)) return true;
// print error message on dosbox console
char buf[MAX_LINE_LENGTH];
snprintf(buf, MAX_LINE_LENGTH, "Could not load image file: %s\n", path);
Bit16u size = strlen(buf);
DOS_WriteFile(STDOUT, (Bit8u*)buf, &size);
return false;
}
bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc)
{
attr = 0;
strcpy(upc, this->mcn.c_str());
return true;
}
bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut)
{
stTrack = 1;
end = tracks.size() - 1;
FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr);
return true;
}
bool CDROM_Interface_Image::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr)
{
if (track < 1 || track > tracks.size()) return false;
FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr);
attr = tracks[track - 1].attr;
return true;
}
bool CDROM_Interface_Image::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
{
track = GetTrack(player.currFrame);
if (track < 1) return false;
attr = tracks[track - 1].attr;
index = 1;
FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr);
FRAMES_TO_MSF(player.currFrame - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr);
return true;
}
bool CDROM_Interface_Image::GetAudioStatus(bool& playing, bool& pause)
{
playing = player.isPlaying;
pause = player.isPaused;
return true;
}
bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
{
mediaPresent = true;
mediaChanged = false;
trayOpen = false;
return true;
}
bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long len)
{
SDL_mutexP(player.mutex);
player.cd = this;
player.currFrame = start;
player.targetFrame = start + len;
player.isPlaying = true;
player.isPaused = false;
SDL_mutexV(player.mutex);
return true;
}
bool CDROM_Interface_Image::PauseAudio(bool resume)
{
player.isPaused = !resume;
return true;
}
bool CDROM_Interface_Image::StopAudio(void)
{
player.isPlaying = false;
player.isPaused = false;
return true;
}
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
{
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
Bitu buflen = num * sectorSize;
Bit8u* buf = new Bit8u[buflen];
bool success;
for(int i = 0; i < num; i++) {
success = ReadSector(&buf[i * sectorSize], raw, sector);
if (!success) break;
}
MEM_BlockWrite(buffer, buf, buflen);
delete[] buf;
return success;
}
bool CDROM_Interface_Image::LoadUnloadMedia(bool unload)
{
return true;
}
int CDROM_Interface_Image::GetTrack(int sector)
{
vector<Track>::iterator i = tracks.begin();
vector<Track>::iterator end = tracks.end() - 1;
while(i != end) {
Track &curr = *i;
Track &next = *(i + 1);
if (curr.start <= sector && sector < next.start) return curr.number;
i++;
}
return -1;
}
bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector)
{
int track = GetTrack(sector) - 1;
if (track < 0) return false;
int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize;
int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false;
if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16;
if (tracks[track].mode2 && !raw) seek += 24;
return tracks[track].file->read(buffer, seek, length);
}
void CDROM_Interface_Image::CDAudioCallBack(Bit8u *stream, Bit32u len)
{
len *= 4; // 16 bit, stereo
if (!len) return;
if (!player.isPlaying || player.isPaused) {
memset(stream, 0, len);
return;
}
SDL_mutexP(player.mutex);
while (player.bufLen < len) {
bool success;
if (player.targetFrame > player.currFrame)
success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame);
else success = false;
if (success) {
player.currFrame++;
player.bufLen += RAW_SECTOR_SIZE;
} else {
memset(&player.buffer[player.bufLen], 0, len - player.bufLen);
player.bufLen = len;
player.isPlaying = false;
}
}
SDL_mutexV(player.mutex);
memcpy(stream, player.buffer, len);
memmove(player.buffer, &player.buffer[len], player.bufLen - len);
player.bufLen -= len;
}
bool CDROM_Interface_Image::LoadIsoFile(char* filename)
{
tracks.clear();
// data track
Track track = {0, 0, 0, 0, 0, 0, false, NULL};
bool error;
track.file = new BinaryFile(filename, error);
if (error) {
delete track.file;
return false;
}
track.number = 1;
track.attr = 4;
// try to detect iso type
if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) {
track.sectorSize = COOKED_SECTOR_SIZE;
track.mode2 = false;
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) {
track.sectorSize = RAW_SECTOR_SIZE;
track.mode2 = false;
} else if (CanReadPVD(track.file, 2336, true)) {
track.sectorSize = 2336;
track.mode2 = true;
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) {
track.sectorSize = RAW_SECTOR_SIZE;
track.mode2 = true;
} else return false;
track.length = track.file->getLength() / track.sectorSize;
tracks.push_back(track);
// leadout track
track.number = 2;
track.attr = 0;
track.start = track.length;
track.length = 0;
track.file = NULL;
tracks.push_back(track);
return true;
}
bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2)
{
Bit8u pvd[COOKED_SECTOR_SIZE];
int seek = 16 * sectorSize; // first vd is located at sector 16
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
if (mode2) seek += 24;
file->read(pvd, seek, COOKED_SECTOR_SIZE);
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version
return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1);
}
bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
{
Track track = {0, 0, 0, 0, 0, 0, false, NULL};
tracks.clear();
int shift = 0;
int currPregap = 0;
int totalPregap = 0;
int prestart = 0;
bool success;
bool canAddTrack = false;
char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument
strncpy(tmp, cuefile, MAX_FILENAME_LENGTH);
#if defined(WIN32)
string pathname("");
#else
string pathname(dirname(tmp));
#endif
ifstream in;
in.open(cuefile, ios::in);
if (in.fail()) return false;
while(!in.eof()) {
// get next line
char buf[MAX_LINE_LENGTH];
in.getline(buf, MAX_LINE_LENGTH);
if (in.fail() && !in.eof()) return false; // probably a binary file
istringstream line(buf);
string command;
GetCueKeyword(command, line);
if (command == "TRACK") {
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
else success = true;
track.start = 0;
track.skip = 0;
currPregap = 0;
prestart = 0;
line >> track.number;
string type;
GetCueKeyword(type, line);
if (type == "AUDIO") {
track.sectorSize = RAW_SECTOR_SIZE;
track.attr = 0;
track.mode2 = false;
} else if (type == "MODE1/2048") {
track.sectorSize = COOKED_SECTOR_SIZE;
track.attr = 4;
track.mode2 = false;
} else if (type == "MODE1/2352") {
track.sectorSize = RAW_SECTOR_SIZE;
track.attr = 4;
track.mode2 = false;
} else if (type == "MODE2/2336") {
track.sectorSize = 2336;
track.attr = 4;
track.mode2 = true;
} else if (type == "MODE2/2352") {
track.sectorSize = RAW_SECTOR_SIZE;
track.attr = 4;
track.mode2 = true;
} else success = false;
canAddTrack = true;
}
else if (command == "INDEX") {
int index;
line >> index;
int frame;
success = GetCueFrame(frame, line);
if (index == 1) track.start = frame;
else if (index == 0) prestart = frame;
// ignore other indices
}
else if (command == "FILE") {
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
else success = true;
canAddTrack = false;
string filename;
GetCueString(filename, line);
GetRealFileName(filename, pathname);
string type;
GetCueKeyword(type, line);
track.file = NULL;
bool error = true;
if (type == "BINARY") {
track.file = new BinaryFile(filename.c_str(), error);
}
#if defined(C_SDL_SOUND)
else if (type == "WAVE" || type == "AIFF" || type == "MP3") {
track.file = new AudioFile(filename.c_str(), error);
}
#endif
if (error) {
delete track.file;
success = false;
}
}
else if (command == "PREGAP") success = GetCueFrame(currPregap, line);
else if (command == "CATALOG") success = GetCueString(mcn, line);
// ignored commands
else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC"
|| command == "PERFORMER" || command == "POSTGAP" || command == "REM"
|| command == "SONGWRITER" || command == "TITLE" || command == "") success = true;
// failure
else success = false;
if (!success) return false;
}
// add last track
if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false;
// add leadout track
track.number++;
track.start = 0;
track.length = 0;
track.file = NULL;
if(!AddTrack(track, shift, 0, totalPregap, 0)) return false;
return true;
}
bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap)
{
// frames between index 0(prestart) and 1(curr.start) must be skipped
int skip;
if (prestart > 0) {
if (prestart > curr.start) return false;
skip = curr.start - prestart;
} else skip = 0;
// first track (track number must be 1)
if (tracks.empty()) {
if (curr.number != 1) return false;
curr.skip = skip * curr.sectorSize;
curr.start += currPregap;
totalPregap = currPregap;
tracks.push_back(curr);
return true;
}
Track &prev = *(tracks.end() - 1);
// current track consumes data from the same file as the previous
if (prev.file == curr.file) {
curr.start += shift;
prev.length = curr.start + totalPregap - prev.start - skip;
curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize;
totalPregap += currPregap;
curr.start += totalPregap;
// current track uses a different file as the previous track
} else {
int tmp = prev.file->getLength() - prev.skip;
prev.length = tmp / prev.sectorSize;
if (tmp % prev.sectorSize != 0) prev.length++; // padding
curr.start += prev.start + prev.length + currPregap;
curr.skip = skip * curr.sectorSize;
shift += prev.start + prev.length;
totalPregap = currPregap;
}
// error checks
if (curr.number <= 1) return false;
if (prev.number + 1 != curr.number) return false;
if (curr.start < prev.start + prev.length) return false;
if (curr.length < 0) return false;
tracks.push_back(curr);
return true;
}
bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname)
{
// check if file exists
struct stat test;
if (stat(filename.c_str(), &test) == 0) return true;
// check if file with path relative to cue file exists
#if not defined(WIN32)
string tmpstr(pathname + "/" + filename);
if (stat(tmpstr.c_str(), &test) == 0) {
filename = tmpstr;
return true;
}
#endif
// finally check if file is in a dosbox local drive
char fullname[CROSS_LEN];
char tmp[CROSS_LEN];
strncpy(tmp, filename.c_str(), CROSS_LEN);
Bit8u drive;
if (!DOS_MakeName(tmp, fullname, &drive)) return false;
localDrive *ldp = (localDrive*)Drives[drive];
ldp->GetSystemFilename(tmp, fullname);
if (stat(tmp, &test) == 0) {
filename = tmp;
return true;
}
return false;
}
bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in)
{
in >> keyword;
for(int i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]);
return true;
}
bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in)
{
string msf;
in >> msf;
int min, sec, fr;
bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3;
frames = MSF_TO_FRAMES(min, sec, fr);
return success;
}
bool CDROM_Interface_Image::GetCueString(string &str, istream &in)
{
int pos = in.tellg();
in >> str;
if (str[0] == '\"') {
if (str[str.size() - 1] == '\"') {
str.assign(str, 1, str.size() - 2);
} else {
in.seekg(pos, ios::beg);
char buffer[MAX_FILENAME_LENGTH];
in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip
in.getline(buffer, MAX_FILENAME_LENGTH, '\"');
str = buffer;
}
}
return true;
}
void CDROM_Interface_Image::ClearTracks()
{
vector<Track>::iterator i = tracks.begin();
vector<Track>::iterator end = tracks.end();
TrackFile* last = NULL;
while(i != end) {
Track &curr = *i;
if (curr.file != last) {
delete curr.file;
last = curr.file;
}
i++;
}
tracks.clear();
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_mscdex.cpp,v 1.23 2004-08-04 09:12:53 qbix79 Exp $ */
/* $Id: dos_mscdex.cpp,v 1.24 2004-08-13 19:43:02 qbix79 Exp $ */
#include <string.h>
#include <ctype.h>
@ -275,11 +275,9 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
cdrom[numDrives] = new CDROM_Interface_SDL();
LOG(LOG_MISC,LOG_NORMAL)("MSCDEX: SDL Interface.");
} break;
case 0x01 : // iso cdrom interface
// FIXME: Not yet supported
LOG(LOG_MISC,LOG_ERROR)("MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath);
cdrom[numDrives] = new CDROM_Interface_Fake;
return 2;
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;

View file

@ -1147,9 +1147,10 @@ public:
if (type=="floppy") {
mediaid=0xF0;
} else if (type=="cdrom") {
} else if (type=="cdrom" || type=="iso") {
str_size="650,127,16513,1700";
mediaid=0xF8;
fstype = "iso";
}
cmd->FindString("-size",str_size,true);
if ((type=="hdd") && (str_size.size()==0)) {
@ -1170,7 +1171,7 @@ public:
}
number[index]=0;sizes[count++]=atoi(number);
if(fstype=="fat") {
if(fstype=="fat" || fstype=="iso") {
// get the drive letter
cmd->FindCommand(1,temp_line);
if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) {
@ -1208,8 +1209,25 @@ public:
}
struct stat test;
if (stat(temp_line.c_str(),&test)) {
WriteOut("Image file not found\n");
return;
// convert dosbox filename to system filename
char fullname[CROSS_LEN];
char tmp[CROSS_LEN];
strncpy(tmp, temp_line.c_str(), CROSS_LEN);
Bit8u drive;
if (!DOS_MakeName(tmp, fullname, &drive)) {
WriteOut("Image file not found\n");
return;
}
localDrive *ldp = (localDrive*)Drives[drive];
ldp->GetSystemFilename(tmp, fullname);
temp_line = tmp;
if (stat(temp_line.c_str(),&test)) {
WriteOut("Image file not found\n");
return;
}
}
if ((test.st_mode & S_IFDIR)) {
@ -1219,6 +1237,22 @@ public:
if(fstype=="fat") {
newdrive=new fatDrive(temp_line.c_str(),sizes[0],sizes[1],sizes[2],sizes[3],0);
} else if (fstype=="iso") {
int error;
newdrive = new isoDrive(drive, temp_line.c_str(), mediaid, error);
switch (error) {
case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break;
case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break;
case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break;
case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break;
case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break;
case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break;
default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break;
};
if (error) {
delete newdrive;
return;
}
} else {
FILE *newDisk = fopen(temp_line.c_str(), "rb+");
fseek(newDisk,0L, SEEK_END);
@ -1254,6 +1288,17 @@ public:
if(!((fatDrive *)newdrive)->loadedDisk->hardDrive) {
imageDiskList[0] = ((fatDrive *)newdrive)->loadedDisk;
}
} else if (fstype=="iso") {
if (Drives[drive-'A']) {
WriteOut("Drive already mounted at that letter\n");
if (newdrive) delete newdrive;
return;
}
if (!newdrive) WriteOut("Can't create drive from file\n");
Drives[drive-'A']=newdrive;
// Set the correct media byte in the table
mem_writeb(Real2Phys(dos.tables.mediaid)+drive-'A',mediaid);
WriteOut("Drive %c mounted as %s\n",drive,temp_line.c_str());
} else if (fstype=="none") {
if(imageDiskList[drive] != NULL) delete imageDiskList[drive];
imageDiskList[drive] = newImage;

435
src/dos/drive_iso.cpp Normal file
View file

@ -0,0 +1,435 @@
/*
* Copyright (C) 2002-2004 The DOSBox Team
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_iso.cpp,v 1.1 2004-08-13 19:43:02 qbix79 Exp $ */
#include <cctype>
#include <cstring>
#include "cdrom.h"
#include "dosbox.h"
#include "dos_system.h"
#include "drives.h"
using namespace std;
class isoFile : public DOS_File {
public:
isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info);
bool Read(Bit8u *data, Bit16u *size);
bool Write(Bit8u *data, Bit16u *size);
bool Seek(Bit32u *pos, Bit32u type);
bool Close();
Bit16u GetInformation(void);
private:
isoDrive *drive;
Bit8u buffer[ISO_FRAMESIZE];
int cachedSector;
Bit32u fileBegin;
Bit32u filePos;
Bit32u fileEnd;
Bit16u info;
};
isoFile::isoFile(isoDrive *drive, const char *name, FileStat_Block *stat, Bit32u offset, Bit16u info)
{
this->drive = drive;
time = stat->time;
date = stat->date;
attr = stat->attr;
size = stat->size;
fileBegin = offset;
filePos = fileBegin;
fileEnd = fileBegin + size;
cachedSector = -1;
open = true;
info = info;
this->name = NULL;
SetName(name);
}
bool isoFile::Read(Bit8u *data, Bit16u *size)
{
if (filePos + *size > fileEnd)
*size = fileEnd - filePos;
Bit16u nowSize = 0;
int sector = filePos / ISO_FRAMESIZE;
Bit16u sectorPos = filePos % ISO_FRAMESIZE;
if (sector != cachedSector) {
if (drive->readSector(buffer, sector)) cachedSector = sector;
else { *size = 0; cachedSector = -1; }
}
while (nowSize < *size) {
Bit16u remSector = ISO_FRAMESIZE - sectorPos;
Bit16u remSize = *size - nowSize;
if(remSector < remSize) {
memcpy(&data[nowSize], &buffer[sectorPos], remSector);
nowSize += remSector;
sectorPos = 0;
sector++;
cachedSector++;
if (!drive->readSector(buffer, sector)) {
*size = nowSize;
cachedSector = -1;
}
} else {
memcpy(&data[nowSize], &buffer[sectorPos], remSize);
nowSize += remSize;
}
}
*size = nowSize;
filePos += *size;
return true;
}
bool isoFile::Write(Bit8u *data, Bit16u *size)
{
return false;
}
bool isoFile::Seek(Bit32u *pos, Bit32u type)
{
switch (type) {
case DOS_SEEK_SET:
filePos = fileBegin + *pos;
break;
case DOS_SEEK_CUR:
filePos += *pos;
break;
case DOS_SEEK_END:
filePos = fileEnd + *pos;
break;
default:
return false;
}
if (filePos > fileEnd || filePos < fileBegin)
filePos = fileEnd;
*pos = filePos - fileBegin;
return true;
}
bool isoFile::Close()
{
if (refCtr == 1) open = false;
return true;
}
Bit16u isoFile::GetInformation(void)
{
return info;
}
int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit);
bool MSCDEX_HasMediaChanged(Bit8u subUnit);
bool MSCDEX_GetVolumeName(Bit8u subUnit, char* name);
isoDrive::isoDrive(char driveLetter, const char *fileName, Bit8u mediaid, int &error)
{
error = MSCDEX_AddDrive(driveLetter, fileName, subUnit);
if (!error) {
if (loadImage()) {
strcpy(info, "isoDrive");
searchCache.clear();
dirIter = searchCache.end();
this->mediaid = mediaid;
if (!MSCDEX_GetVolumeName(subUnit, discLabel)) strcpy(discLabel, "");
} else error = 6;
}
}
isoDrive::~isoDrive() { }
bool isoDrive::FileOpen(DOS_File **file, char *name, Bit32u flags)
{
if (flags == OPEN_WRITE) {
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
isoDirEntry de;
bool success = lookup(&de, name) && !IS_DIR(de.fileFlags);
if (success) {
FileStat_Block file_stat;
file_stat.size = DATA_LENGTH(de);
file_stat.attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY;
file_stat.date = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay);
file_stat.time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec);
*file = new isoFile(this, name, &file_stat, EXTENT_LOCATION(de) * ISO_FRAMESIZE, 0x202);
(*file)->flags = flags;
}
return success;
}
bool isoDrive::FileCreate(DOS_File **file, char *name, Bit16u attributes)
{
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::FileUnlink(char *name)
{
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::RemoveDir(char *dir)
{
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::MakeDir(char *dir)
{
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::TestDir(char *dir)
{
isoDirEntry de;
return (lookup(&de, dir) && IS_DIR(de.fileFlags));
}
bool isoDrive::FindFirst(char *dir, DOS_DTA &dta, bool fcb_findfirst)
{
isoDirEntry de;
if (!lookup(&de, dir)) {
DOS_SetError(DOSERR_PATH_NOT_FOUND);
return false;
}
Bit32u sectorStart = EXTENT_LOCATION(de);
Bit32u sectorEnd = sectorStart + DATA_LENGTH(de) / ISO_FRAMESIZE;
if (DATA_LENGTH(de) % ISO_FRAMESIZE != 0) sectorEnd++;
searchCache.clear();
for(Bit32u sector = sectorStart; sector < sectorEnd; sector++) {
Bit8u block[ISO_FRAMESIZE];
readSector(block, sector);
Bit32u pos = 0;
while (pos < ISO_FRAMESIZE && block[pos] != 0) {
isoDirEntry tmp;
int length = readDirEntry(&tmp, &block[pos]);
if (length < 0) return false;
searchCache.push_back(tmp);
pos += length;
}
}
dirIter = searchCache.begin();
Bit8u attr;
char pattern[ISO_MAXPATHNAME];
dta.GetSearchParams(attr, pattern);
if ((attr & DOS_ATTR_VOLUME) && ((*dir == 0) || fcb_findfirst)) {
// Get Volume Label (DOS_ATTR_VOLUME) and only in basedir
dta.SetResult(discLabel, 0, 0, 0, DOS_ATTR_VOLUME);
return true;
}
return FindNext(dta);
}
bool isoDrive::FindNext(DOS_DTA &dta)
{
Bit8u attr;
char pattern[DOS_NAMELENGTH_ASCII];
dta.GetSearchParams(attr, pattern);
while (dirIter != searchCache.end()) {
isoDirEntry &de = *dirIter;
Bit8u findAttr;
if (IS_DIR(de.fileFlags)) findAttr = DOS_ATTR_DIRECTORY;
else findAttr = DOS_ATTR_ARCHIVE;
if (WildFileCmp((char*)de.ident, pattern)
&& !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) {
/* file is okay, setup everything to be copied in DTA Block */
char findName[DOS_NAMELENGTH_ASCII];
if(strlen((char*)de.ident) < DOS_NAMELENGTH_ASCII) {
strcpy(findName, (char*)de.ident);
upcase(findName);
}
Bit32u findSize = DATA_LENGTH(de);
Bit16u findDate = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay);
Bit16u findTime = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec);
dta.SetResult(findName, findSize, findDate, findTime, findAttr);
dirIter++;
return true;
}
dirIter++;
}
DOS_SetError(DOSERR_NO_MORE_FILES);
return false;
}
bool isoDrive::Rename(char *oldname, char *newname)
{
DOS_SetError(DOSERR_ACCESS_DENIED);
return false;
}
bool isoDrive::GetFileAttr(char *name, Bit16u *attr)
{
*attr = 0;
isoDirEntry de;
bool success = lookup(&de, name);
if (success) {
*attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY;
if (IS_DIR(de.fileFlags)) *attr |= DOS_ATTR_DIRECTORY;
}
return success;
}
bool isoDrive::AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters)
{
*bytes_sector = 2048;
*sectors_cluster = 1; // cluster size for cdroms ?
*total_clusters = 60000;
*free_clusters = 0;
return true;
}
bool isoDrive::FileExists(const char *name)
{
isoDirEntry de;
return (lookup(&de, name) && !IS_DIR(de.fileFlags));
}
bool isoDrive::FileStat(const char *name, FileStat_Block *const stat_block)
{
isoDirEntry de;
bool success = lookup(&de, name);
if (success) {
stat_block->date = DOS_PackDate(1900 + de.dateYear, de.dateMonth, de.dateDay);
stat_block->time = DOS_PackTime(de.timeHour, de.timeMin, de.timeSec);
stat_block->size = DATA_LENGTH(de);
stat_block->attr = DOS_ATTR_ARCHIVE | DOS_ATTR_READ_ONLY;
if (IS_DIR(de.fileFlags)) stat_block->attr |= DOS_ATTR_DIRECTORY;
}
return success;
}
Bit8u isoDrive::GetMediaByte(void)
{
return mediaid;
}
bool isoDrive::isRemote(void)
{
return true;
}
inline bool isoDrive :: readSector(Bit8u *buffer, Bit32u sector)
{
return CDROM_Interface_Image::images[subUnit]->ReadSector(buffer, false, sector);
}
int isoDrive :: readDirEntry(isoDirEntry *de, Bit8u *data)
{
// copy data into isoDirEntry struct, data[0] = length of DirEntry
memcpy(de, data, data[0]);
// xa not supported
if (de->extAttrLength != 0) return -1;
// interleaved mode not supported
if (de->fileUnitSize != 0 || de->interleaveGapSize != 0) return -1;
// modify file identifier for use with dosbox
if (IS_DIR(de->fileFlags)) {
if (de->fileIdentLength == 1 && de->ident[0] == 0) strcpy((char*)de->ident, ".");
else if (de->fileIdentLength == 1 && de->ident[0] == 1) strcpy((char*)de->ident, "..");
else {
if (de->fileIdentLength > 31) return -1;
de->ident[de->fileIdentLength] = 0;
}
} else {
if (de->fileIdentLength > 37) return -1;
de->ident[de->fileIdentLength] = 0;
// remove any file version identifiers as there are some cdroms that don't have them
strreplace((char*)de->ident, ';', 0);
// if file has no extension remove the trailing dot
int tmp = strlen((char*)de->ident);
if (tmp > 0 && de->ident[tmp - 1] == '.') de->ident[tmp - 1] = 0;
}
return de->length;
}
bool isoDrive :: loadImage()
{
isoPVD pvd;
readSector((Bit8u*)(&pvd), ISO_FIRST_VD);
if (pvd.type != 1 || strncmp((char*)pvd.standardIdent, "CD001", 5) || pvd.version != 1) return false;
return (readDirEntry(&this->rootEntry, pvd.rootEntry));
}
bool isoDrive :: lookupSingle(isoDirEntry *de, const char *name, Bit32u start, Bit32u length)
{
Bit32u end = start + length / ISO_FRAMESIZE;
if (length % ISO_FRAMESIZE != 0) end++;
for(Bit32u i = start; i < end; i++) {
Bit8u sector[ISO_FRAMESIZE];
if (!readSector(sector, i)) return false;
int pos = 0;
while (sector[pos] != 0 && pos < ISO_FRAMESIZE) {
int deLength = readDirEntry(de, &sector[pos]);
if (deLength < 1) return false;
pos += deLength;
int tmp = strncasecmp((char*)de->ident, name, 38);
if (tmp == 0) return true;
}
}
return false;
}
bool isoDrive :: lookup(isoDirEntry *de, const char *path)
{
*de = this->rootEntry;
if (!strcmp(path, "")) return true;
char isoPath[ISO_MAXPATHNAME];
strncpy(isoPath, path, ISO_MAXPATHNAME);
strreplace(isoPath, '\\', '/');
int beginPos = 0;
int pos = 0;
while (isoPath[pos] != 0) {
if (isoPath[pos] == '/') {
char name[38];
strncpy(name, &isoPath[beginPos], pos - beginPos);
name[pos - beginPos] = 0;
beginPos = pos + 1;
if (!IS_DIR(de->fileFlags)) return false;
if (!lookupSingle(de, name, EXTENT_LOCATION(*de), DATA_LENGTH(*de))) return false;
}
pos++;
}
return lookupSingle(de, &isoPath[beginPos], EXTENT_LOCATION(*de), DATA_LENGTH(*de));
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_local.cpp,v 1.50 2004-08-08 12:39:54 qbix79 Exp $ */
/* $Id: drive_local.cpp,v 1.51 2004-08-13 19:43:02 qbix79 Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -114,6 +114,15 @@ FILE * localDrive::GetSystemFilePtr(char * name, char * type) {
return fopen(newname,type);
}
bool localDrive::GetSystemFilename(char *sysName, char *dosName) {
strcpy(sysName, basedir);
strcat(sysName, dosName);
CROSS_FILENAME(sysName);
dirCache.ExpandName(sysName);
return true;
}
bool localDrive::FileUnlink(char * name) {
char newname[CROSS_LEN];
strcpy(newname,basedir);

View file

@ -16,11 +16,12 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drives.h,v 1.22 2004-08-04 09:12:53 qbix79 Exp $ */
/* $Id: drives.h,v 1.23 2004-08-13 19:43:02 qbix79 Exp $ */
#ifndef _DRIVES_H__
#define _DRIVES_H__
#include <vector>
#include <sys/types.h>
#include "dos_system.h"
#include "shell.h" /* for DOS_Shell */
@ -33,6 +34,7 @@ public:
localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
virtual FILE *GetSystemFilePtr(char * name, char * type);
virtual bool GetSystemFilename(char *sysName, char *dosName);
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
virtual bool FileUnlink(char * name);
virtual bool RemoveDir(char * dir);
@ -202,6 +204,112 @@ private:
Bit8u subUnit;
};
#ifdef _MSC_VER
#pragma pack (1)
#endif
struct isoPVD {
Bit8u type;
Bit8u standardIdent[5];
Bit8u version;
Bit8u unused1;
Bit8u systemIdent[32];
Bit8u volumeIdent[32];
Bit8u unused2[8];
Bit32u volumeSpaceSizeL;
Bit32u volumeSpaceSizeM;
Bit8u unused3[32];
Bit16u volumeSetSizeL;
Bit16u volumeSetSizeM;
Bit16u volumeSeqNumberL;
Bit16u volumeSeqNumberM;
Bit16u logicBlockSizeL;
Bit16u logicBlockSizeM;
Bit32u pathTableSizeL;
Bit32u pathTableSizeM;
Bit32u locationPathTableL;
Bit32u locationOptPathTableL;
Bit32u locationPathTableM;
Bit32u locationOptPathTableM;
Bit8u rootEntry[34];
Bit32u unused4[1858];
} GCC_ATTRIBUTE(packed);
struct isoDirEntry {
Bit8u length;
Bit8u extAttrLength;
Bit32u extentLocationL;
Bit32u extentLocationM;
Bit32u dataLengthL;
Bit32u dataLengthM;
Bit8u dateYear;
Bit8u dateMonth;
Bit8u dateDay;
Bit8u timeHour;
Bit8u timeMin;
Bit8u timeSec;
Bit8u timeZone;
Bit8u fileFlags;
Bit8u fileUnitSize;
Bit8u interleaveGapSize;
Bit16u VolumeSeqNumberL;
Bit16u VolumeSeqNumberM;
Bit8u fileIdentLength;
Bit8u ident[38]; // can be smaller
} GCC_ATTRIBUTE(packed);
#ifdef _MSC_VER
#pragma pack ()
#endif
#if defined (WORD_BIGENDIAN)
#define EXTENT_LOCATION(de) ((de).extentLocationM)
#define DATA_LENGTH(de) ((de).dataLengthM)
#else
#define EXTENT_LOCATION(de) ((de).extentLocationL)
#define DATA_LENGTH(de) ((de).dataLengthL)
#endif
#define ISO_FRAMESIZE 2048
#define ISO_DIRECTORY 2
#define ISO_MAXPATHNAME 256
#define ISO_FIRST_VD 16
#define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY)
class isoDrive : public DOS_Drive {
public:
isoDrive(char driveLetter, const char* device_name, Bit8u mediaid, int &error);
~isoDrive();
virtual bool FileOpen(DOS_File **file, char *name, Bit32u flags);
virtual bool FileCreate(DOS_File **file, char *name, Bit16u attributes);
virtual bool FileUnlink(char *name);
virtual bool RemoveDir(char *dir);
virtual bool MakeDir(char *dir);
virtual bool TestDir(char *dir);
virtual bool FindFirst(char *_dir, DOS_DTA &dta, bool fcb_findfirst);
virtual bool FindNext(DOS_DTA &dta);
virtual bool GetFileAttr(char *name, Bit16u *attr);
virtual bool Rename(char * oldname,char * newname);
virtual bool AllocationInfo(Bit16u *bytes_sector, Bit8u *sectors_cluster, Bit16u *total_clusters, Bit16u *free_clusters);
virtual bool FileExists(const char *name);
virtual bool FileStat(const char *name, FileStat_Block *const stat_block);
virtual Bit8u GetMediaByte(void);
virtual void EmptyCache(void){}
virtual bool isRemote(void);
bool readSector(Bit8u *buffer, Bit32u sector);
private:
int readDirEntry(isoDirEntry *de, Bit8u *data);
bool loadImage();
bool lookupSingle(isoDirEntry *de, const char *name, Bit32u sectorStart, Bit32u length);
bool lookup(isoDirEntry *de, const char *path);
std::vector<isoDirEntry> searchCache;
std::vector<isoDirEntry>::iterator dirIter;
isoDirEntry rootEntry;
Bit8u mediaid;
Bit8u subUnit;
char discLabel[32];
};
struct VFILE_Block;
class Virtual_Drive: public DOS_Drive {

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dosbox.cpp,v 1.73 2004-08-04 09:12:51 qbix79 Exp $ */
/* $Id: dosbox.cpp,v 1.74 2004-08-13 19:43:02 qbix79 Exp $ */
#include <stdlib.h>
#include <stdarg.h>
@ -369,7 +369,7 @@ void DOSBOX_Init(void) {
secprop->AddInitFunction(&MSCDEX_Init);
#if C_MODEM
secprop=control->AddSection_prop("modem",&MODEM_Init);
secprop->Add_bool("modem",true);
secprop->Add_bool("modem",false);
secprop->Add_hex("comport",2);
secprop->Add_int("listenport",23);
@ -400,7 +400,7 @@ void DOSBOX_Init(void) {
#endif
#if C_IPX
secprop=control->AddSection_prop("ipx",&IPX_Init);
secprop->Add_bool("ipx", true);
secprop->Add_bool("ipx", false);
MSG_Add("IPX_CONFIGFILE_HELP",
"ipx -- Enable ipx over UDP/IP emulation.\n"
);