mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-11-26 10:49:21 +00:00
commit
3b177f141f
@ -50,7 +50,8 @@ SRCS = ../main.cpp ../prefs.cpp ../prefs_items.cpp \
|
||||
timer_unix.cpp ../adb.cpp ../serial.cpp ../ether.cpp \
|
||||
../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp ../video.cpp \
|
||||
video_blit.cpp \
|
||||
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp \
|
||||
vm_alloc.cpp sigsegv.cpp ../audio.cpp ../extfs.cpp disk_sparsebundle.cpp \
|
||||
tinyxml2.cpp \
|
||||
../user_strings.cpp user_strings_unix.cpp sshpty.c strlcpy.c rpc_unix.cpp \
|
||||
$(SYSSRCS) $(CPUSRCS) $(SLIRP_SRCS)
|
||||
APP_FLAVOR ?=
|
||||
|
315
BasiliskII/src/Unix/disk_sparsebundle.cpp
Normal file
315
BasiliskII/src/Unix/disk_sparsebundle.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
/*
|
||||
* disk_sparsebundle.cpp - Apple sparse bundle implementation
|
||||
*
|
||||
* Basilisk II (C) Dave Vasilevsky
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#include "disk_unix.h"
|
||||
#include "tinyxml2.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined __APPLE__ && defined __MACH__
|
||||
#define __MACOSX__ 1
|
||||
#endif
|
||||
|
||||
struct disk_sparsebundle : disk_generic {
|
||||
disk_sparsebundle(const char *bands, int fd, bool read_only,
|
||||
loff_t band_size, loff_t total_size)
|
||||
: token_fd(fd), read_only(read_only), band_size(band_size),
|
||||
total_size(total_size), band_dir(strdup(bands)),
|
||||
band_cur(-1), band_fd(-1), band_alloc(-1) {
|
||||
}
|
||||
|
||||
virtual ~disk_sparsebundle() {
|
||||
if (band_fd != -1)
|
||||
close(band_fd);
|
||||
close(token_fd);
|
||||
free(band_dir);
|
||||
}
|
||||
|
||||
virtual bool is_read_only() { return read_only; }
|
||||
virtual loff_t size() { return total_size; }
|
||||
|
||||
virtual size_t read(void *buf, loff_t offset, size_t length) {
|
||||
return band_do(&disk_sparsebundle::band_read, buf, offset, length);
|
||||
}
|
||||
|
||||
virtual size_t write(void *buf, loff_t offset, size_t length) {
|
||||
return band_do(&disk_sparsebundle::band_write, buf, offset, length);
|
||||
}
|
||||
|
||||
protected:
|
||||
int token_fd; // lockfile
|
||||
bool read_only;
|
||||
loff_t band_size, total_size;
|
||||
char *band_dir; // directory containing band files
|
||||
|
||||
// Currently open band
|
||||
loff_t band_cur; // index of the band
|
||||
int band_fd; // -1 if not open
|
||||
loff_t band_alloc; // how much space is already used?
|
||||
|
||||
typedef ssize_t (disk_sparsebundle::*band_func)(char *buf, loff_t band,
|
||||
size_t offset, size_t len);
|
||||
|
||||
// Split an (offset, length) operation into bands.
|
||||
size_t band_do(band_func func, void *buf, loff_t offset, size_t length) {
|
||||
char *b = (char*)buf;
|
||||
loff_t band = offset / band_size;
|
||||
size_t done = 0;
|
||||
while (length) {
|
||||
if (offset >= total_size)
|
||||
break;
|
||||
size_t start = offset % band_size;
|
||||
size_t segment = std::min((size_t)band_size - start, length);
|
||||
|
||||
ssize_t err = (this->*func)(b, band, start, segment);
|
||||
if (err > 0)
|
||||
done += err;
|
||||
if (err < segment)
|
||||
break;
|
||||
|
||||
b += segment;
|
||||
offset += segment;
|
||||
length -= segment;
|
||||
++band;
|
||||
}
|
||||
return done;
|
||||
}
|
||||
|
||||
// Open a band by index. It's ok if the band is already open.
|
||||
enum open_ret {
|
||||
OPEN_FAILED = 0,
|
||||
OPEN_NOENT, // Band doesn't exist yet
|
||||
OPEN_OK,
|
||||
};
|
||||
open_ret open_band(loff_t band, bool create) {
|
||||
if (band_cur == band)
|
||||
return OPEN_OK;
|
||||
|
||||
char path[PATH_MAX + 1];
|
||||
if (snprintf(path, PATH_MAX, "%s/%lx", band_dir,
|
||||
(unsigned long)band) >= PATH_MAX) {
|
||||
return OPEN_FAILED;
|
||||
}
|
||||
|
||||
if (band_fd != -1)
|
||||
close(band_fd);
|
||||
band_alloc = -1;
|
||||
band_cur = -1;
|
||||
|
||||
int oflags = read_only ? O_RDONLY : O_RDWR;
|
||||
if (create)
|
||||
oflags |= O_CREAT;
|
||||
band_fd = open(path, oflags, 0644);
|
||||
if (band_fd == -1) {
|
||||
return (!create && errno == ENOENT) ? OPEN_NOENT : OPEN_FAILED;
|
||||
}
|
||||
|
||||
// Get the allocated size
|
||||
if (!read_only) {
|
||||
band_alloc = lseek(band_fd, 0, SEEK_END);
|
||||
if (band_alloc == -1)
|
||||
band_alloc = band_size;
|
||||
}
|
||||
band_cur = band;
|
||||
return OPEN_OK;
|
||||
}
|
||||
|
||||
ssize_t band_read(char *buf, loff_t band, size_t off, size_t len) {
|
||||
open_ret st = open_band(band, false);
|
||||
if (st == OPEN_FAILED)
|
||||
return -1;
|
||||
|
||||
// Unallocated bytes
|
||||
size_t want = (st == OPEN_NOENT || off >= band_alloc) ? 0
|
||||
: std::min(len, (size_t)band_alloc - off);
|
||||
if (want) {
|
||||
if (lseek(band_fd, off, SEEK_SET) == -1)
|
||||
return -1;
|
||||
ssize_t err = ::read(band_fd, buf, want);
|
||||
if (err < want)
|
||||
return err;
|
||||
}
|
||||
memset(buf + want, 0, len - want);
|
||||
return len;
|
||||
}
|
||||
|
||||
ssize_t band_write(char *buf, loff_t band, size_t off, size_t len) {
|
||||
// If space is unused, don't needlessly fill it with zeros
|
||||
|
||||
// Find min length such that all trailing chars are zero:
|
||||
size_t nz = len;
|
||||
for (; nz > 0 && !buf[nz-1]; --nz)
|
||||
; // pass
|
||||
|
||||
open_ret st = open_band(band, nz);
|
||||
if (st != OPEN_OK)
|
||||
return st == OPEN_NOENT ? len : -1;
|
||||
|
||||
if (lseek(band_fd, off, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
size_t space = (off >= band_alloc ? 0 : band_alloc - off);
|
||||
size_t want = std::max(nz, std::min(space, len));
|
||||
ssize_t err = ::write(band_fd, buf, want);
|
||||
if (err >= 0)
|
||||
band_alloc = std::max(band_alloc, loff_t(off + err));
|
||||
if (err < want)
|
||||
return err;
|
||||
return len;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
using tinyxml2::XML_NO_ERROR;
|
||||
using tinyxml2::XMLElement;
|
||||
|
||||
// Simplistic plist parser
|
||||
struct plist {
|
||||
plist() : doc(true, tinyxml2::COLLAPSE_WHITESPACE) { }
|
||||
|
||||
bool open(const char *path) {
|
||||
if (doc.LoadFile(path) != XML_NO_ERROR)
|
||||
return false;
|
||||
tinyxml2::XMLHandle hnd(&doc);
|
||||
dict = hnd.FirstChildElement("plist").FirstChildElement("dict")
|
||||
.ToElement();
|
||||
return dict;
|
||||
}
|
||||
|
||||
const char *str_val(const char *key) {
|
||||
return value(key, "string");
|
||||
}
|
||||
|
||||
bool int_val(const char *key, loff_t *i) {
|
||||
const char *v = value(key, "integer");
|
||||
if (!v || !*v)
|
||||
return false;
|
||||
|
||||
char *endp;
|
||||
long long ll = strtoll(v, &endp, 10);
|
||||
if (*endp)
|
||||
return false;
|
||||
*i = ll;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
tinyxml2::XMLDocument doc;
|
||||
XMLElement *dict;
|
||||
|
||||
const char *value(const char *key, const char *type) {
|
||||
// Assume it's a flat plist
|
||||
XMLElement *cur = dict->FirstChildElement();
|
||||
bool found_key = false;
|
||||
while (cur) {
|
||||
if (found_key) {
|
||||
if (strcmp(cur->Name(), type) != 0)
|
||||
return NULL;
|
||||
return cur->GetText();
|
||||
}
|
||||
found_key = strcmp(cur->Name(), "key") == 0
|
||||
&& strcmp(cur->GetText(), key) == 0;
|
||||
cur = cur->NextSiblingElement();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int try_open(const char *path, bool read_only, bool *locked) {
|
||||
int oflags = (read_only ? O_RDONLY : O_RDWR);
|
||||
int lockflags = 0;
|
||||
#if defined(__MACOSX__)
|
||||
lockflags = O_NONBLOCK | (read_only ? O_SHLOCK : O_EXLOCK);
|
||||
#endif
|
||||
int fd = open(path, oflags | lockflags);
|
||||
#if defined(__MACOSX__)
|
||||
if (fd == -1) {
|
||||
if (errno == EOPNOTSUPP) { // no locking support, try again
|
||||
fd = open(path, oflags);
|
||||
} else if (errno == EAGAIN) { // locked
|
||||
*locked = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
disk_generic::status disk_sparsebundle_factory(const char *path,
|
||||
bool read_only, disk_generic **disk) {
|
||||
// Does it look like a sparsebundle?
|
||||
char buf[PATH_MAX + 1];
|
||||
if (snprintf(buf, PATH_MAX, "%s/%s", path, "Info.plist") >= PATH_MAX)
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
|
||||
plist pl;
|
||||
if (!pl.open(buf))
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
|
||||
const char *type;
|
||||
if (!(type = pl.str_val("diskimage-bundle-type")))
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
if (strcmp(type, "com.apple.diskimage.sparsebundle") != 0)
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
|
||||
|
||||
// Find the sparsebundle parameters
|
||||
loff_t version, band_size, total_size;
|
||||
if (!pl.int_val("bundle-backingstore-version", &version) || version != 1) {
|
||||
fprintf(stderr, "sparsebundle: Bad version\n");
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
}
|
||||
if (!pl.int_val("band-size", &band_size)
|
||||
|| !pl.int_val("size", &total_size)) {
|
||||
fprintf(stderr, "sparsebundle: Can't find size\n");
|
||||
return disk_generic::DISK_INVALID;
|
||||
}
|
||||
|
||||
|
||||
// Check if we can open it
|
||||
if (snprintf(buf, PATH_MAX, "%s/%s", path, "token") >= PATH_MAX)
|
||||
return disk_generic::DISK_INVALID;
|
||||
bool locked = false;
|
||||
int token = try_open(buf, read_only, &locked);
|
||||
if (token == -1 && !read_only) { // try again, read-only
|
||||
token = try_open(buf, true, &locked);
|
||||
if (token != -1 && !read_only)
|
||||
fprintf(stderr, "sparsebundle: Can only mount read-only\n");
|
||||
read_only = true;
|
||||
}
|
||||
if (token == -1) {
|
||||
if (locked)
|
||||
fprintf(stderr, "sparsebundle: Refusing to double-mount\n");
|
||||
else
|
||||
perror("sparsebundle: open failed:");
|
||||
return disk_generic::DISK_INVALID;
|
||||
}
|
||||
|
||||
|
||||
// We're good to go!
|
||||
if (snprintf(buf, PATH_MAX, "%s/%s", path, "bands") >= PATH_MAX)
|
||||
return disk_generic::DISK_INVALID;
|
||||
*disk = new disk_sparsebundle(buf, token, read_only, band_size,
|
||||
total_size);
|
||||
return disk_generic::DISK_VALID;
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* vhd_unix.h -- support for disk images in vhd format
|
||||
* disk_unix.h - Generic disk interface
|
||||
*
|
||||
* (C) 2010 Geoffrey Brown
|
||||
* Basilisk II (C) Dave Vasilevsky
|
||||
*
|
||||
* 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
|
||||
@ -18,12 +18,31 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef VHD_H
|
||||
#define VHD_H
|
||||
#ifndef DISK_UNIX_H
|
||||
#define DISK_UNIX_H
|
||||
|
||||
void *vhd_unix_open(const char *name, int *size, bool read_only);
|
||||
int vhd_unix_read(void *arg, void *buffer, loff_t offset, size_t length);
|
||||
int vhd_unix_write(void *arg, void *buffer, loff_t offset, size_t length);
|
||||
void vhd_unix_close(void *arg);
|
||||
#include "sysdeps.h"
|
||||
|
||||
struct disk_generic {
|
||||
enum status {
|
||||
DISK_UNKNOWN,
|
||||
DISK_INVALID,
|
||||
DISK_VALID,
|
||||
};
|
||||
|
||||
disk_generic() { }
|
||||
virtual ~disk_generic() { };
|
||||
|
||||
virtual bool is_read_only() = 0;
|
||||
virtual size_t read(void *buf, loff_t offset, size_t length) = 0;
|
||||
virtual size_t write(void *buf, loff_t offset, size_t length) = 0;
|
||||
virtual loff_t size() = 0;
|
||||
};
|
||||
|
||||
typedef disk_generic::status (disk_factory)(const char *path, bool read_only,
|
||||
disk_generic **disk);
|
||||
|
||||
extern disk_factory disk_sparsebundle_factory;
|
||||
extern disk_factory disk_vhd_factory;
|
||||
|
||||
#endif
|
@ -56,19 +56,25 @@
|
||||
#include "prefs.h"
|
||||
#include "user_strings.h"
|
||||
#include "sys.h"
|
||||
#include "disk_unix.h"
|
||||
|
||||
#if defined(BINCUE)
|
||||
#include "bincue_unix.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
#include "vhd_unix.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
static disk_factory *disk_factories[] = {
|
||||
disk_sparsebundle_factory,
|
||||
#if defined(HAVE_LIBVHD)
|
||||
disk_vhd_factory,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
// File handles are pointers to these structures
|
||||
struct mac_file_handle {
|
||||
char *name; // Copy of device/file name
|
||||
@ -83,6 +89,7 @@ struct mac_file_handle {
|
||||
loff_t file_size; // Size of file data (only valid if is_file is true)
|
||||
|
||||
bool is_media_present; // Flag: media is inserted and available
|
||||
disk_generic *generic_disk;
|
||||
|
||||
#if defined(__linux__)
|
||||
int cdrom_cap; // CD-ROM capability flags (only valid if is_cdrom is true)
|
||||
@ -97,11 +104,6 @@ struct mac_file_handle {
|
||||
bool is_bincue; // Flag: BIN CUE file
|
||||
void *bincue_fd;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
bool is_vhd; // Flag: VHD file
|
||||
void *vhd_fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Open file handles
|
||||
@ -525,6 +527,7 @@ static mac_file_handle *open_filehandle(const char *name)
|
||||
memset(fh, 0, sizeof(mac_file_handle));
|
||||
fh->name = strdup(name);
|
||||
fh->fd = -1;
|
||||
fh->generic_disk = NULL;
|
||||
#if defined __MACOSX__
|
||||
fh->ioctl_fd = -1;
|
||||
fh->ioctl_name = NULL;
|
||||
@ -600,21 +603,22 @@ void *Sys_open(const char *name, bool read_only)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
int vhdsize;
|
||||
void *vhdfd = vhd_unix_open(name, &vhdsize, read_only);
|
||||
if (vhdfd) {
|
||||
mac_file_handle *fh = open_filehandle(name);
|
||||
D(bug("opening %s as vnd\n", name));
|
||||
fh->is_vhd = true;
|
||||
fh->vhd_fd = vhdfd;
|
||||
fh->read_only = read_only;
|
||||
fh->file_size = vhdsize;
|
||||
fh->is_media_present = true;
|
||||
sys_add_mac_file_handle(fh);
|
||||
return fh;
|
||||
for (int i = 0; disk_factories[i]; ++i) {
|
||||
disk_factory *f = disk_factories[i];
|
||||
disk_generic *generic;
|
||||
disk_generic::status st = f(name, read_only, &generic);
|
||||
if (st == disk_generic::DISK_INVALID)
|
||||
return NULL;
|
||||
if (st == disk_generic::DISK_VALID) {
|
||||
mac_file_handle *fh = open_filehandle(name);
|
||||
fh->generic_disk = generic;
|
||||
fh->file_size = generic->size();
|
||||
fh->read_only = generic->is_read_only();
|
||||
fh->is_media_present = true;
|
||||
sys_add_mac_file_handle(fh);
|
||||
return fh;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int open_flags = (read_only ? O_RDONLY : O_RDWR);
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__MACOSX__)
|
||||
@ -718,15 +722,12 @@ void Sys_close(void *arg)
|
||||
|
||||
sys_remove_mac_file_handle(fh);
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
vhd_unix_close(fh->vhd_fd);
|
||||
#endif
|
||||
|
||||
#if defined(BINCUE)
|
||||
if (fh->is_bincue)
|
||||
close_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
if (fh->generic_disk)
|
||||
delete fh->generic_disk;
|
||||
|
||||
if (fh->is_cdrom)
|
||||
cdrom_close(fh);
|
||||
@ -754,11 +755,9 @@ size_t Sys_read(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
return read_bincue(fh->bincue_fd, buffer, offset, length);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
return vhd_unix_read(fh->vhd_fd, buffer, offset, length);
|
||||
#endif
|
||||
|
||||
if (fh->generic_disk)
|
||||
return fh->generic_disk->read(buffer, offset, length);
|
||||
|
||||
// Seek to position
|
||||
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
|
||||
return 0;
|
||||
@ -779,10 +778,8 @@ size_t Sys_write(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
if (!fh)
|
||||
return 0;
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
return vhd_unix_write(fh->vhd_fd, buffer, offset, length);
|
||||
#endif
|
||||
if (fh->generic_disk)
|
||||
return fh->generic_disk->write(buffer, offset, length);
|
||||
|
||||
// Seek to position
|
||||
if (lseek(fh->fd, offset + fh->start_byte, SEEK_SET) < 0)
|
||||
@ -808,10 +805,8 @@ loff_t SysGetFileSize(void *arg)
|
||||
return size_bincue(fh->bincue_fd);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
if (fh->generic_disk)
|
||||
return fh->file_size;
|
||||
#endif
|
||||
|
||||
if (fh->is_file)
|
||||
return fh->file_size;
|
||||
@ -946,10 +941,8 @@ bool SysIsFixedDisk(void *arg)
|
||||
if (!fh)
|
||||
return true;
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
if (fh->generic_disk)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (fh->is_file)
|
||||
return true;
|
||||
@ -970,11 +963,9 @@ bool SysIsDiskInserted(void *arg)
|
||||
if (!fh)
|
||||
return false;
|
||||
|
||||
#if defined(HAVE_LIBVHD)
|
||||
if (fh->is_vhd)
|
||||
if (fh->generic_disk)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
|
||||
if (fh->is_file) {
|
||||
return true;
|
||||
|
||||
|
2095
BasiliskII/src/Unix/tinyxml2.cpp
Executable file
2095
BasiliskII/src/Unix/tinyxml2.cpp
Executable file
File diff suppressed because it is too large
Load Diff
1968
BasiliskII/src/Unix/tinyxml2.h
Executable file
1968
BasiliskII/src/Unix/tinyxml2.h
Executable file
File diff suppressed because it is too large
Load Diff
@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "vhd_unix.h"
|
||||
#include "disk_unix.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@ -32,7 +32,8 @@ extern "C" {
|
||||
#define DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
void *vhd_unix_open(const char *name, int *size, bool read_only)
|
||||
static disk_generic::status vhd_unix_open(const char *name, int *size,
|
||||
bool read_only, vhd_context_t **ctx)
|
||||
{
|
||||
int amode = read_only ? R_OK : (R_OK | W_OK);
|
||||
int fid;
|
||||
@ -42,12 +43,12 @@ void *vhd_unix_open(const char *name, int *size, bool read_only)
|
||||
|
||||
if (access(name, amode)) {
|
||||
D(bug("vhd open -- incorrect permissions %s\n", name));
|
||||
return NULL;
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
}
|
||||
|
||||
if (! (fid = open(name, O_RDONLY))) {
|
||||
D(bug("vhd open -- couldn't open file %s\n", name));
|
||||
return NULL;
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
}
|
||||
else {
|
||||
char buf[9];
|
||||
@ -56,7 +57,7 @@ void *vhd_unix_open(const char *name, int *size, bool read_only)
|
||||
close(fid);
|
||||
if (strcmp("conectix", buf) != 0) {
|
||||
D(bug("vhd open -- not vhd magic = %s\n", buf));
|
||||
return NULL;
|
||||
return disk_generic::DISK_UNKNOWN;
|
||||
}
|
||||
if (vhd = (vhd_context_t *) malloc(sizeof(vhd_context_t))) {
|
||||
int err;
|
||||
@ -64,24 +65,25 @@ void *vhd_unix_open(const char *name, int *size, bool read_only)
|
||||
VHD_OPEN_RDONLY : VHD_OPEN_RDWR)) {
|
||||
D(bug("vhd_open failed (%d)\n", err));
|
||||
free(vhd);
|
||||
return NULL;
|
||||
return disk_generic::DISK_INVALID;
|
||||
}
|
||||
else {
|
||||
*size = (int) vhd->footer.curr_size;
|
||||
printf("VHD Open %s\n", name);
|
||||
return (void *) vhd;
|
||||
*ctx = vhd;
|
||||
return disk_generic::DISK_VALID;
|
||||
}
|
||||
}
|
||||
else {
|
||||
D(bug("vhd open -- malloc failed\n"));
|
||||
return NULL;
|
||||
return disk_generic::DISK_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int vhd_unix_read(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
static int vhd_unix_read(vhd_context_t *ctx, void *buffer, loff_t offset,
|
||||
size_t length)
|
||||
{
|
||||
vhd_context_t *ctx = (vhd_context_t *) arg;
|
||||
int err;
|
||||
if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) {
|
||||
printf("vhd read only supported on sector boundaries (%d)\n",
|
||||
@ -97,10 +99,10 @@ int vhd_unix_read(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
return length;
|
||||
}
|
||||
|
||||
int vhd_unix_write(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
static int vhd_unix_write(vhd_context_t *ctx, void *buffer, loff_t offset,
|
||||
size_t length)
|
||||
{
|
||||
int err;
|
||||
vhd_context_t *ctx = (vhd_context_t *) arg;
|
||||
|
||||
if ((offset % VHD_SECTOR_SIZE) || (length % VHD_SECTOR_SIZE)) {
|
||||
printf("vhd write only supported on sector boundaries (%d)\n",
|
||||
@ -116,9 +118,43 @@ int vhd_unix_write(void *arg, void *buffer, loff_t offset, size_t length)
|
||||
return length;
|
||||
}
|
||||
|
||||
void vhd_unix_close(void *arg)
|
||||
|
||||
static void vhd_unix_close(vhd_context_t *ctx)
|
||||
{
|
||||
D(bug("vhd close\n"));
|
||||
vhd_close((vhd_context_t *) arg);
|
||||
free(arg);
|
||||
vhd_close(ctx);
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
|
||||
struct disk_vhd : disk_generic {
|
||||
disk_vhd(vhd_context_t *ctx, bool read_only, loff_t size)
|
||||
: ctx(ctx), read_only(read_only), file_size(size) { }
|
||||
|
||||
virtual ~disk_vhd() { vhd_unix_close(ctx); }
|
||||
virtual bool is_read_only() { return read_only; }
|
||||
virtual loff_t size() { return file_size; }
|
||||
|
||||
virtual size_t read(void *buf, loff_t offset, size_t length) {
|
||||
return vhd_unix_read(ctx, buf, offset, length);
|
||||
}
|
||||
|
||||
virtual size_t write(void *buf, loff_t offset, size_t length) {
|
||||
return vhd_unix_write(ctx, buf, offset, length);
|
||||
}
|
||||
|
||||
protected:
|
||||
vhd_context_t *ctx;
|
||||
bool read_only;
|
||||
loff_t file_size;
|
||||
};
|
||||
|
||||
disk_generic::status disk_vhd_factory(const char *path,
|
||||
bool read_only, disk_generic **disk) {
|
||||
int size;
|
||||
vhd_context_t *ctx = NULL;
|
||||
disk_generic::status st = vhd_unix_open(path, &size, read_only, &ctx);
|
||||
if (st == disk_generic::DISK_VALID)
|
||||
*disk = new disk_vhd(ctx, read_only, size);
|
||||
return st;
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ links:
|
||||
BeOS/serial_beos.cpp BeOS/sys_beos.cpp BeOS/timer_beos.cpp \
|
||||
BeOS/xpram_beos.cpp BeOS/SheepDriver BeOS/SheepNet \
|
||||
Unix/audio_oss_esd.cpp Unix/bincue_unix.cpp Unix/bincue_unix.h \
|
||||
Unix/vhd_unix.cpp Unix/vhd_unix.h \
|
||||
Unix/vhd_unix.cpp \
|
||||
Unix/extfs_unix.cpp Unix/serial_unix.cpp \
|
||||
Unix/sshpty.h Unix/sshpty.c Unix/strlcpy.h Unix/strlcpy.c \
|
||||
Unix/sys_unix.cpp Unix/timer_unix.cpp Unix/xpram_unix.cpp \
|
||||
@ -70,7 +70,9 @@ links:
|
||||
Unix/video_blit.cpp Unix/config.sub Unix/config.guess Unix/m4 \
|
||||
Unix/keycodes Unix/tunconfig Unix/clip_unix.cpp Unix/Irix/audio_irix.cpp \
|
||||
Unix/Linux/scsi_linux.cpp Unix/Linux/NetDriver Unix/ether_unix.cpp \
|
||||
Unix/rpc.h Unix/rpc_unix.cpp Unix/ldscripts Unix/Darwin/mkstandalone \
|
||||
Unix/rpc.h Unix/rpc_unix.cpp Unix/ldscripts \
|
||||
Unix/tinyxml2.h Unix/tinyxml2.cpp Unix/disk_unix.h \
|
||||
Unix/disk_sparsebundle.cpp Unix/Darwin/mkstandalone \
|
||||
Unix/Darwin/lowmem.c Unix/Darwin/pagezero.c Unix/Darwin/testlmem.sh \
|
||||
dummy/audio_dummy.cpp dummy/clip_dummy.cpp dummy/serial_dummy.cpp \
|
||||
dummy/prefs_editor_dummy.cpp dummy/scsi_dummy.cpp SDL slirp \
|
||||
|
@ -59,7 +59,7 @@ SRCS = ../main.cpp main_unix.cpp ../prefs.cpp ../prefs_items.cpp prefs_unix.cpp
|
||||
../macos_util.cpp ../timer.cpp timer_unix.cpp ../xpram.cpp xpram_unix.cpp \
|
||||
../adb.cpp ../sony.cpp ../disk.cpp ../cdrom.cpp ../scsi.cpp \
|
||||
../gfxaccel.cpp ../video.cpp video_blit.cpp ../audio.cpp ../ether.cpp ../thunks.cpp \
|
||||
../serial.cpp ../extfs.cpp \
|
||||
../serial.cpp ../extfs.cpp disk_sparsebundle.cpp tinyxml2.cpp \
|
||||
about_window_unix.cpp ../user_strings.cpp user_strings_unix.cpp \
|
||||
vm_alloc.cpp sigsegv.cpp rpc_unix.cpp \
|
||||
sshpty.c strlcpy.c $(SYSSRCS) $(CPUSRCS) $(MONSRCS) $(SLIRP_SRCS)
|
||||
|
1
SheepShaver/src/Unix/disk_sparsebundle.cpp
Symbolic link
1
SheepShaver/src/Unix/disk_sparsebundle.cpp
Symbolic link
@ -0,0 +1 @@
|
||||
../../../BasiliskII/src/Unix/disk_sparsebundle.cpp
|
1
SheepShaver/src/Unix/disk_unix.h
Symbolic link
1
SheepShaver/src/Unix/disk_unix.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../../BasiliskII/src/Unix/disk_unix.h
|
1
SheepShaver/src/Unix/tinyxml2.cpp
Symbolic link
1
SheepShaver/src/Unix/tinyxml2.cpp
Symbolic link
@ -0,0 +1 @@
|
||||
../../../BasiliskII/src/Unix/tinyxml2.cpp
|
1
SheepShaver/src/Unix/tinyxml2.h
Symbolic link
1
SheepShaver/src/Unix/tinyxml2.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../../BasiliskII/src/Unix/tinyxml2.h
|
@ -1 +0,0 @@
|
||||
../../../BasiliskII/src/Unix/vhd_unix.h
|
Loading…
Reference in New Issue
Block a user