/*
 *  extfs.cpp - MacOS file system for native file system access
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  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
 */

/*
 *  SEE ALSO
 *    Guide to the File System Manager (from FSM 1.2 SDK)
 *
 *  TODO
 *    LockRng
 *    UnlockRng
 *    (CatSearch)
 *    (MakeFSSpec)
 *    (GetVolMountInfoSize)
 *    (GetVolMountInfo)
 *    (GetForeignPrivs)
 *    (SetForeignPrivs)
 */

#include "sysdeps.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>

#ifndef WIN32
#include <unistd.h>
#include <dirent.h>
#endif

#if defined __APPLE__ && defined __MACH__
#include <sys/attr.h>
#endif

#include "cpu_emulation.h"
#include "emul_op.h"
#include "main.h"
#include "disk.h"
#include "prefs.h"
#include "user_strings.h"
#include "extfs.h"
#include "extfs_defs.h"

#ifdef WIN32
# include "posix_emu.h"
#endif

#define DEBUG 0
#include "debug.h"


// File system global data and 68k routines
enum {
	fsCommProcStub = 0,
	fsHFSProcStub = 6,
	fsDrvStatus = 12,				// Drive Status record
	fsFSD = 42,						// File system descriptor
	fsPB = 238,						// IOParam (for mounting and renaming), also used for temporary storage
	fsVMI = 288,					// VoumeMountInfoHeader (for mounting)
	fsParseRec = 296,				// ParsePathRec struct
	fsReturn = 306,					// Area for return data of 68k routines
	fsAllocateVCB = 562,			// UTAllocateVCB(uint16 *sysVCBLength{a0}, uint32 *vcb{a1})
	fsAddNewVCB = 578,				// UTAddNewVCB(int drive_number{d0}, int16 *vRefNum{a1}, uint32 vcb{a1})
	fsDetermineVol = 594,			// UTDetermineVol(uint32 pb{a0}, int16 *status{a1}, int16 *more_matches{a2}, int16 *vRefNum{a3}, uint32 *vcb{a4})
	fsResolveWDCB = 614,			// UTResolveWDCB(uint32 procID{d0}, int16 index{d1}, int16 vRefNum{d0}, uint32 *wdcb{a0})
	fsGetDefaultVol = 632,			// UTGetDefaultVol(uint32 wdpb{a0})
	fsGetPathComponentName = 644,	// UTGetPathComponentName(uint32 rec{a0})
	fsParsePathname = 656,			// UTParsePathname(uint32 *start{a0}, uint32 name{a1})
	fsDisposeVCB = 670,				// UTDisposeVCB(uint32 vcb{a0})
	fsCheckWDRefNum = 682,			// UTCheckWDRefNum(int16 refNum{d0})
	fsSetDefaultVol = 694,			// UTSetDefaultVol(uint32 dummy{d0}, int32 dirID{d1}, int16 refNum{d2})
	fsAllocateFCB = 710,			// UTAllocateFCB(int16 *refNum{a0}, uint32 *fcb{a1})
	fsReleaseFCB = 724,				// UTReleaseFCB(int16 refNum{d0})
	fsIndexFCB = 736,				// UTIndexFCB(uint32 vcb{a0}, int16 *refNum{a1}, uint32 *fcb{a2})
	fsResolveFCB = 752,				// UTResolveFCB(int16 refNum{d0}, uint32 *fcb{a0})
	fsAdjustEOF = 766,				// UTAdjustEOF(int16 refNum{d0})
	fsAllocateWDCB = 778,			// UTAllocateWDCB(uint32 pb{a0})
	fsReleaseWDCB = 790,			// UTReleaseWDCB(int16 vRefNum{d0})
	SIZEOF_fsdat = 802
};

static uint32 fs_data = 0;		// Mac address of global data


// File system and volume name
static char FS_NAME[32], VOLUME_NAME[32];

// This directory is our root (read from prefs)
static const char *RootPath;
static bool ready = false;
static struct stat root_stat;

// File system ID/media type
const int16 MY_FSID = EMULATOR_ID_2;
const uint32 MY_MEDIA_TYPE = EMULATOR_ID_4;

// CNID of root and root's parent
const uint32 ROOT_ID = 2;
const uint32 ROOT_PARENT_ID = 1;

// File system stack size
const int STACK_SIZE = 0x10000;

// Allocation block and clump size as reported to MacOS (these are of course
// not the real values and have no meaning on the host OS)
const int AL_BLK_SIZE = 0x4000;
const int CLUMP_SIZE = 0x4000;

// Drive number of our pseudo-drive
static int drive_number;


// Disk/drive icon
const uint8 ExtFSIcon[256] = {
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe,
	0x80, 0x00, 0x00, 0x91, 0x80, 0x00, 0x00, 0x91, 0x80, 0x00, 0x01, 0x21, 0x80, 0x00, 0x01, 0x21,
	0x80, 0x00, 0x02, 0x41, 0x8c, 0x00, 0x02, 0x41, 0x80, 0x00, 0x04, 0x81, 0x80, 0x00, 0x04, 0x81,
	0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0xfe,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};


// These objects are used to map CNIDs to path names
struct FSItem {
	FSItem *next;			// Pointer to next FSItem in list
	uint32 id;				// CNID of this file/dir
	uint32 parent_id;		// CNID of parent file/dir
	FSItem *parent;			// Pointer to parent
	char *name;				// Object name (C string) - Host OS
	char guest_name[32];	// Object name (C string) - Guest OS
	time_t mtime;			// Modification time for get_cat_info caching
	int cache_dircount;		// Cached number of files in directory
};

static FSItem *first_fs_item, *last_fs_item;

static uint32 next_cnid = fsUsrCNID;	// Next available CNID


/*
 *  Get object creation time
 */

#if defined __APPLE__ && defined __MACH__
struct crtimebuf {
	unsigned long length;
	struct timespec crtime;
};

static uint32 do_get_creation_time(const char *path)
{
	struct attrlist attr;
	memset(&attr, 0, sizeof(attr));
	attr.bitmapcount = ATTR_BIT_MAP_COUNT;
	attr.commonattr = ATTR_CMN_CRTIME;

	crtimebuf buf;
	if (getattrlist(path, &attr, &buf, sizeof(buf), FSOPT_NOFOLLOW) < 0)
		return 0;
	return TimeToMacTime(buf.crtime.tv_sec);
}

static uint32 get_creation_time(const char *path)
{
	if (path == NULL)
		return 0;
	if (path == RootPath) {
		static uint32 root_crtime = UINT_MAX;
		if (root_crtime == UINT_MAX)
			root_crtime = do_get_creation_time(path);
		return root_crtime;
	}
	return do_get_creation_time(path);
}
#endif


/*
 *  Find FSItem for given CNID
 */

static FSItem *find_fsitem_by_id(uint32 cnid)
{
	FSItem *p = first_fs_item;
	while (p) {
		if (p->id == cnid)
			return p;
		p = p->next;
	}
	return NULL;
}

/*
 *  Create FSItem with the given parameters
 */

static FSItem *create_fsitem(const char *name, const char *guest_name, FSItem *parent)
{
	FSItem *p = new FSItem;
	last_fs_item->next = p;
	p->next = NULL;
	last_fs_item = p;
	p->id = next_cnid++;
	p->parent_id = parent->id;
	p->parent = parent;
	p->name = new char[strlen(name) + 1];
	strcpy(p->name, name);
	strncpy(p->guest_name, guest_name, 31);
	p->guest_name[31] = 0;
	p->mtime = 0;
	return p;
}

/*
 *  Find FSItem for given name and parent, construct new FSItem if not found
 */

static FSItem *find_fsitem(const char *name, FSItem *parent)
{
	FSItem *p = first_fs_item;
	while (p) {
		if (p->parent == parent && !strcmp(p->name, name))
			return p;
		p = p->next;
	}

	// Not found, construct new FSItem
	return create_fsitem(name, host_encoding_to_macroman(name), parent);
}

/*
 *  Find FSItem for given guest_name and parent, construct new FSItem if not found
 */

static FSItem *find_fsitem_guest(const char *guest_name, FSItem *parent)
{
	FSItem *p = first_fs_item;
	while (p) {
		if (p->parent == parent && !strcmp(p->guest_name, guest_name))
			return p;
		p = p->next;
	}

	// Not found, construct new FSItem
	return create_fsitem(macroman_to_host_encoding(guest_name), guest_name, parent);
}

/*
 *  Get full path (->full_path) for given FSItem
 */

static char full_path[MAX_PATH_LENGTH];

static void add_path_comp(const char *s)
{
	add_path_component(full_path, s);
}

static void get_path_for_fsitem(FSItem *p)
{
	if (p->id == ROOT_PARENT_ID) {
		full_path[0] = 0;
	} else if (p->id == ROOT_ID) {
		strncpy(full_path, RootPath, MAX_PATH_LENGTH-1);
		full_path[MAX_PATH_LENGTH-1] = 0;
	} else {
		get_path_for_fsitem(p->parent);
		add_path_comp(p->name);
	}
}


/*
 *  Exchange parent CNIDs in all FSItems
 */

static void swap_parent_ids(uint32 parent1, uint32 parent2)
{
	FSItem *p = first_fs_item;
	while (p) {
		if (p->parent_id == parent1)
			p->parent_id = parent2;
		else if (p->parent_id == parent2)
			p->parent_id = parent1;
		p = p->next;
	}
}


/*
 *  String handling functions
 */

// Copy pascal string
static void pstrcpy(char *dst, const char *src)
{
	int size = *dst++ = *src++;
	while (size--)
		*dst++ = *src++;
}

// Convert C string to pascal string
static void cstr2pstr(char *dst, const char *src)
{
	*dst++ = char(strlen(src));
	char c;
	while ((c = *src++) != 0) {
		// Note: we are converting host ':' characters to Mac '/' characters here
		// '/' is not a path separator as this function is only used on object names
		if (c == ':')
			c = '/';
		*dst++ = c;
	}
}

// Convert string (no length byte) to C string, length given separately
static void strn2cstr(char *dst, const char *src, int size)
{
	while (size--) {
		char c = *src++;
		// Note: we are converting Mac '/' characters to host ':' characters here
		// '/' is not a path separator as this function is only used on object names
		if (c == '/')
			c = ':';
		*dst++ = c;
	}
	*dst = 0;
}


/*
 *  Convert errno to MacOS error code
 */

static int16 errno2oserr(void)
{
	D(bug(" errno %08x\n", errno));
	switch (errno) {
		case 0:
			return noErr;
		case ENOENT:
		case EISDIR:
			return fnfErr;
		case EACCES:
		case EPERM:
			return permErr;
		case EEXIST:
			return dupFNErr;
		case EBUSY:
		case ENOTEMPTY:
			return fBsyErr;
		case ENOSPC:
			return dskFulErr;
		case EROFS:
			return wPrErr;
		case EMFILE:
			return tmfoErr;
		case ENOMEM:
			return -108;
		case EIO:
		default:
			return ioErr;
	}
}


/*
 *  Initialization
 */

void ExtFSInit(void)
{
	// System specific initialization
	extfs_init();

	// Get file system and volume name
	cstr2pstr(FS_NAME, GetString(STR_EXTFS_NAME));
	cstr2pstr(VOLUME_NAME, GetString(STR_EXTFS_VOLUME_NAME));

	// Create root's parent FSItem
	FSItem *p = new FSItem;
	first_fs_item = last_fs_item = p;
	p->next = NULL;
	p->id = ROOT_PARENT_ID;
	p->parent_id = 0;
	p->parent = NULL;
	p->name = new char[1];
	p->name[0] = 0;
	p->guest_name[0] = 0;

	// Create root FSItem
	p = new FSItem;
	last_fs_item->next = p;
	p->next = NULL;
	last_fs_item = p;
	p->id = ROOT_ID;
	p->parent_id = ROOT_PARENT_ID;
	p->parent = first_fs_item;
	const char *volume_name = GetString(STR_EXTFS_VOLUME_NAME);
	p->name = new char[strlen(volume_name) + 1];
	strcpy(p->name, volume_name);
	strncpy(p->guest_name, host_encoding_to_macroman(p->name), 32);
	p->guest_name[31] = 0;

	// Find path for root
	if ((RootPath = PrefsFindString("extfs")) != NULL) {
		if (stat(RootPath, &root_stat))
			return;
		if (!S_ISDIR(root_stat.st_mode))
			return;
		ready = true;
	}
}


/*
 *  Deinitialization
 */

void ExtFSExit(void)
{
	// Delete all FSItems
	FSItem *p = first_fs_item, *next;
	while (p) {
		next = p->next;
		delete[] p->name;
		delete p;
		p = next;
	}
	first_fs_item = last_fs_item = NULL;

	// System specific deinitialization
	extfs_exit();
}


/*
 *  Install file system
 */

void InstallExtFS(void)
{
	int num_blocks = 0xffff;	// Fake number of blocks of our drive
	M68kRegisters r;

	D(bug("InstallExtFS\n"));
	if (!ready)
		return;

	// FSM present?
	r.d[0] = gestaltFSAttr;
	Execute68kTrap(0xa1ad, &r);	// Gestalt()
	D(bug("FSAttr %d, %08x\n", r.d[0], r.a[0]));
	if ((r.d[0] & 0xffff) || !(r.a[0] & (1 << gestaltHasFileSystemManager))) {
		printf("WARNING: No FSM present, disabling ExtFS\n");
		return;
	}

	// Yes, version >=1.2?
	r.d[0] = gestaltFSMVersion;
	Execute68kTrap(0xa1ad, &r);	// Gestalt()
	D(bug("FSMVersion %d, %08x\n", r.d[0], r.a[0]));
	if ((r.d[0] & 0xffff) || (r.a[0] < 0x0120)) {
		printf("WARNING: FSM <1.2 found, disabling ExtFS\n");
		return;
	}

	D(bug("FSM present\n"));

	// Yes, allocate file system stack
	r.d[0] = STACK_SIZE;
	Execute68kTrap(0xa71e, &r);		// NewPtrSysClear()
	if (r.a[0] == 0)
		return;
	uint32 fs_stack = r.a[0];

	// Allocate memory for our data structures and 68k code
	r.d[0] = SIZEOF_fsdat;
	Execute68kTrap(0xa71e, &r);		// NewPtrSysClear()
	if (r.a[0] == 0)
		return;
	fs_data = r.a[0];

	// Set up 68k code fragments
	int p = fs_data + fsCommProcStub;
	WriteMacInt16(p, M68K_EMUL_OP_EXTFS_COMM); p += 2;
	WriteMacInt16(p, M68K_RTD); p += 2;
	WriteMacInt16(p, 10); p += 2;
	if (p - fs_data != fsHFSProcStub)
		goto fsdat_error;
	WriteMacInt16(p, M68K_EMUL_OP_EXTFS_HFS); p += 2;
	WriteMacInt16(p, M68K_RTD); p += 2;
	WriteMacInt16(p, 16);
	p = fs_data + fsAllocateVCB;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(sp)
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x7006); p+= 2;	// UTAllocateVCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsAddNewVCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(a7)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(a7)
	WriteMacInt16(p, 0x7007); p+= 2;	// UTAddNewVCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsDetermineVol)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(sp)
	WriteMacInt16(p, 0x2f0a); p+= 2;	// move.l a2,-(sp)
	WriteMacInt16(p, 0x2f0b); p+= 2;	// move.l a3,-(sp)
	WriteMacInt16(p, 0x2f0c); p+= 2;	// move.l a4,-(sp)
	WriteMacInt16(p, 0x701d); p+= 2;	// UTDetermineVol
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsResolveWDCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f00); p+= 2;	// move.l d0,-(sp)
	WriteMacInt16(p, 0x3f01); p+= 2;	// move.w d1,-(sp)
	WriteMacInt16(p, 0x3f02); p+= 2;	// move.w d2,-(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x700e); p+= 2;	// UTResolveWDCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsGetDefaultVol)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x7012); p+= 2;	// UTGetDefaultVol
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsGetPathComponentName)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x701c); p+= 2;	// UTGetPathComponentName
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsParsePathname)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(sp)
	WriteMacInt16(p, 0x701b); p+= 2;	// UTParsePathname
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsDisposeVCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x7008); p+= 2;	// UTDisposeVCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsCheckWDRefNum)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x7013); p+= 2;	// UTCheckWDRefNum
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsSetDefaultVol)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f00); p+= 2;	// move.l d0,-(sp)
	WriteMacInt16(p, 0x2f01); p+= 2;	// move.l d1,-(sp)
	WriteMacInt16(p, 0x3f02); p+= 2;	// move.w d2,-(sp)
	WriteMacInt16(p, 0x7011); p+= 2;	// UTSetDefaultVol
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsAllocateFCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(sp)
	WriteMacInt16(p, 0x7000); p+= 2;	// UTAllocateFCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsReleaseFCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x7001); p+= 2;	// UTReleaseFCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsIndexFCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x2f09); p+= 2;	// move.l a1,-(sp)
	WriteMacInt16(p, 0x2f0a); p+= 2;	// move.l a2,-(sp)
	WriteMacInt16(p, 0x7004); p+= 2;	// UTIndexFCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsResolveFCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x7005); p+= 2;	// UTResolveFCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsAdjustEOF)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x7010); p+= 2;	// UTAdjustEOF
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsAllocateWDCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x2f08); p+= 2;	// move.l a0,-(sp)
	WriteMacInt16(p, 0x700c); p+= 2;	// UTAllocateWDCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != fsReleaseWDCB)
		goto fsdat_error;
	WriteMacInt16(p, 0x4267); p+= 2;	// clr.w -(sp)
	WriteMacInt16(p, 0x3f00); p+= 2;	// move.w d0,-(sp)
	WriteMacInt16(p, 0x700d); p+= 2;	// UTReleaseWDCB
	WriteMacInt16(p, 0xa824); p+= 2;	// FSMgr
	WriteMacInt16(p, 0x301f); p+= 2;	// move.w (sp)+,d0
	WriteMacInt16(p, M68K_RTS); p+= 2;
	if (p - fs_data != SIZEOF_fsdat)
		goto fsdat_error;

	// Set up drive status
	WriteMacInt8(fs_data + fsDrvStatus + dsDiskInPlace, 8);	// Fixed disk
	WriteMacInt8(fs_data + fsDrvStatus + dsInstalled, 1);
	WriteMacInt16(fs_data + fsDrvStatus + dsQType, hard20);
	WriteMacInt16(fs_data + fsDrvStatus + dsDriveSize, num_blocks & 0xffff);
	WriteMacInt16(fs_data + fsDrvStatus + dsDriveS1, num_blocks >> 16);
	WriteMacInt16(fs_data + fsDrvStatus + dsQFSID, MY_FSID);

	// Add drive to drive queue
	drive_number = FindFreeDriveNumber(1);
	D(bug(" adding drive %d\n", drive_number));
	r.d[0] = (drive_number << 16) | (DiskRefNum & 0xffff);
	r.a[0] = fs_data + fsDrvStatus + dsQLink;
	Execute68kTrap(0xa04e, &r);	// AddDrive()

	// Init FSDRec and install file system
	D(bug(" installing file system\n"));
	WriteMacInt16(fs_data + fsFSD + fsdLength, SIZEOF_FSDRec);
	WriteMacInt16(fs_data + fsFSD + fsdVersion, fsdVersion1);
	WriteMacInt16(fs_data + fsFSD + fileSystemFSID, MY_FSID);
	Host2Mac_memcpy(fs_data + fsFSD + fileSystemName, FS_NAME, 32);
	WriteMacInt32(fs_data + fsFSD + fileSystemCommProc, fs_data + fsCommProcStub);
	WriteMacInt32(fs_data + fsFSD + fsdHFSCI + compInterfProc, fs_data + fsHFSProcStub);
	WriteMacInt32(fs_data + fsFSD + fsdHFSCI + stackTop, fs_stack + STACK_SIZE);
	WriteMacInt32(fs_data + fsFSD + fsdHFSCI + stackSize, STACK_SIZE);
	WriteMacInt32(fs_data + fsFSD + fsdHFSCI + idSector, (uint32)-1);
	r.a[0] = fs_data + fsFSD;
	r.d[0] = 0;					// InstallFS
	Execute68kTrap(0xa0ac, &r);	// FSMDispatch()
	D(bug(" InstallFS() returned %d\n", r.d[0]));

	// Enable HFS component
	D(bug(" enabling HFS component\n"));
	WriteMacInt32(fs_data + fsFSD + fsdHFSCI + compInterfMask, ReadMacInt32(fs_data + fsFSD + fsdHFSCI + compInterfMask) | (fsmComponentEnableMask | hfsCIResourceLoadedMask | hfsCIDoesHFSMask));
	r.a[0] = fs_data + fsFSD;
	r.d[3] = SIZEOF_FSDRec;
	r.d[4] = MY_FSID;
	r.d[0] = 5;					// SetFSInfo
	Execute68kTrap(0xa0ac, &r);	// FSMDispatch()
	D(bug(" SetFSInfo() returned %d\n", r.d[0]));

	// Mount volume
	D(bug(" mounting volume\n"));
	WriteMacInt32(fs_data + fsPB + ioBuffer, fs_data + fsVMI);
	WriteMacInt16(fs_data + fsVMI + vmiLength, SIZEOF_VolumeMountInfoHeader);
	WriteMacInt32(fs_data + fsVMI + vmiMedia, MY_MEDIA_TYPE);
	r.a[0] = fs_data + fsPB;
	r.d[0] = 0x41;				// PBVolumeMount
	Execute68kTrap(0xa260, &r);	// HFSDispatch()
	D(bug(" PBVolumeMount() returned %d\n", r.d[0]));
	return;

fsdat_error:
	printf("FATAL: ExtFS data block initialization error\n");
	QuitEmulator();
}


/*
 *  FS communications function
 */

int16 ExtFSComm(uint16 message, uint32 paramBlock, uint32 globalsPtr)
{
	D(bug("ExtFSComm(%d, %08lx, %08lx)\n", message, paramBlock, globalsPtr));

	switch (message) {
		case ffsNopMessage:
		case ffsLoadMessage:
		case ffsUnloadMessage:
			return noErr;

		case ffsGetIconMessage: {		// Get disk/drive icon
			if (ReadMacInt8(paramBlock + iconType) == kLargeIcon && ReadMacInt32(paramBlock + requestSize) >= sizeof(ExtFSIcon)) {
				Host2Mac_memcpy(ReadMacInt32(paramBlock + iconBufferPtr), ExtFSIcon, sizeof(ExtFSIcon));
				WriteMacInt32(paramBlock + actualSize, sizeof(ExtFSIcon));
				return noErr;
			} else
				return -5012;	// afpItemNotFound
		}

		case ffsIDDiskMessage: {		// Check if volume is handled by our FS
			if ((int16)ReadMacInt16(paramBlock + ioVRefNum) == drive_number)
				return noErr;
			else
				return extFSErr;
		}

		case ffsIDVolMountMessage: {	// Check if volume can be mounted by our FS
			if (ReadMacInt32(ReadMacInt32(paramBlock + ioBuffer) + vmiMedia) == MY_MEDIA_TYPE)
				return noErr;
			else
				return extFSErr;
		}

		default:
			return fsmUnknownFSMMessageErr;
	}
}


/*
 *  Get current directory specified by given ParamBlock/dirID
 */

static int16 get_current_dir(uint32 pb, uint32 dirID, uint32 &current_dir, bool no_vol_name = false)
{
	M68kRegisters r;
	int16 result;

	// Determine volume
	D(bug("  determining volume, dirID %d\n", dirID));
	r.a[0] = pb;
	r.a[1] = fs_data + fsReturn;
	r.a[2] = fs_data + fsReturn + 2;
	r.a[3] = fs_data + fsReturn + 4;
	r.a[4] = fs_data + fsReturn + 6;
	uint32 name_ptr = 0;
	if (no_vol_name) {
		name_ptr = ReadMacInt32(pb + ioNamePtr);
		WriteMacInt32(pb + ioNamePtr, 0);
	}
	Execute68k(fs_data + fsDetermineVol, &r);
	if (no_vol_name)
		WriteMacInt32(pb + ioNamePtr, name_ptr);
	int16 status = ReadMacInt16(fs_data + fsReturn);
	D(bug("  UTDetermineVol() returned %d, status %d\n", r.d[0], status));
	result = (int16)(r.d[0] & 0xffff);

	if (result == noErr) {
		switch (status) {
			case dtmvFullPathname:	// Determined by full pathname
				current_dir = ROOT_ID;
				break;

			case dtmvVRefNum:		// Determined by refNum or by drive number
			case dtmvDriveNum:
				current_dir = dirID ? dirID : ROOT_ID;
				break;

			case dtmvWDRefNum:		// Determined by working directory refNum
				if (dirID) {
					current_dir = dirID;
				} else {
					D(bug("  resolving WDCB\n"));
					r.d[0] = 0;
					r.d[1] = 0;
					r.d[2] = ReadMacInt16(pb + ioVRefNum);
					r.a[0] = fs_data + fsReturn;
					Execute68k(fs_data + fsResolveWDCB, &r);
					uint32 wdcb = ReadMacInt32(fs_data + fsReturn);
					D(bug("  UTResolveWDCB() returned %d, dirID %d\n", r.d[0], ReadMacInt32(wdcb + wdDirID)));
					result = (int16)(r.d[0] & 0xffff);
					if (result == noErr)
						current_dir = ReadMacInt32(wdcb + wdDirID);
				}
				break;

			case dtmvDefault:		// Determined by default volume
				if (dirID) {
					current_dir = dirID;
				} else {
					uint32 wdpb = fs_data + fsReturn;
					WriteMacInt32(wdpb + ioNamePtr, 0);
					D(bug("  getting default volume\n"));
					r.a[0] = wdpb;
					Execute68k(fs_data + fsGetDefaultVol, &r);
					D(bug("  UTGetDefaultVol() returned %d, dirID %d\n", r.d[0], ReadMacInt32(wdpb + ioWDDirID)));
					result = (int16)(r.d[0] & 0xffff);
					if (result == noErr)
						current_dir = ReadMacInt32(wdpb + ioWDDirID);
				}
				break;

			default:
				result = paramErr;
				break;
		}
	}
	return result;
}


/*
 *  Get path component name
 */

static int16 get_path_component_name(uint32 rec)
{
//	D(bug("  getting path component\n"));
	M68kRegisters r;
	r.a[0] = rec;
	Execute68k(fs_data + fsGetPathComponentName, &r);
//	D(bug("  UTGetPathComponentName returned %d\n", r.d[0]));
	return (int16)(r.d[0] & 0xffff);
}


/*
 *  Get FSItem and full path (->full_path) for file/dir specified in ParamBlock
 */

static int16 get_item_and_path(uint32 pb, uint32 dirID, FSItem *&item, bool no_vol_name = false)
{
	M68kRegisters r;

	// Find FSItem for parent directory
	int16 result;
	uint32 current_dir;
	if ((result = get_current_dir(pb, dirID, current_dir, no_vol_name)) != noErr)
		return result;
	D(bug("  current dir %08x\n", current_dir));
	FSItem *p = find_fsitem_by_id(current_dir);
	if (p == NULL)
		return dirNFErr;

	// Start parsing
	uint32 parseRec = fs_data + fsParseRec;
	WriteMacInt32(parseRec + ppNamePtr, ReadMacInt32(pb + ioNamePtr));
	WriteMacInt16(parseRec + ppStartOffset, 0);
	WriteMacInt16(parseRec + ppComponentLength, 0);
	WriteMacInt8(parseRec + ppMoreName, false);
	WriteMacInt8(parseRec + ppFoundDelimiter, false);

	// Get length of volume name
	D(bug("  parsing pathname\n"));
	r.a[0] = parseRec + ppStartOffset;
	r.a[1] = ReadMacInt32(parseRec + ppNamePtr);
	Execute68k(fs_data + fsParsePathname, &r);
	D(bug("  UTParsePathname() returned %d, startOffset %d\n", r.d[0], ReadMacInt16(parseRec + ppStartOffset)));
	result = (int16)(r.d[0] & 0xffff);
	if (result == noErr) {

		// Check for leading delimiter of the partial pathname
		result = get_path_component_name(parseRec);
		if (result == noErr) {
			if (ReadMacInt16(parseRec + ppComponentLength) == 0 && ReadMacInt8(parseRec + ppFoundDelimiter)) {
				// Get past initial delimiter
				WriteMacInt16(parseRec + ppStartOffset, ReadMacInt16(parseRec + ppStartOffset) + 1);
			}

			// Parse until there is no more pathname to parse
			while ((result == noErr) && ReadMacInt8(parseRec + ppMoreName)) {

				// Search for the next delimiter from startOffset
				result = get_path_component_name(parseRec);
				if (result == noErr) {
					if (ReadMacInt16(parseRec + ppComponentLength) == 0) {

						// Delimiter immediately following another delimiter, get parent
						if (current_dir != ROOT_ID) {
							p = p->parent;
							current_dir = p->id;
						} else
							result = bdNamErr;

						// startOffset = start of next component
						WriteMacInt16(parseRec + ppStartOffset, ReadMacInt16(parseRec + ppStartOffset) + 1);

					} else if (ReadMacInt8(parseRec + ppMoreName)) {

						// Component found and isn't the last, so it must be a directory, enter it
						char name[32];
						strn2cstr(name, (char *)Mac2HostAddr(ReadMacInt32(parseRec + ppNamePtr)) + ReadMacInt16(parseRec + ppStartOffset) + 1, ReadMacInt16(parseRec + ppComponentLength));
						D(bug("  entering %s\n", name));
						p = find_fsitem_guest(name, p);
						current_dir = p->id;

						// startOffset = start of next component
						WriteMacInt16(parseRec + ppStartOffset, ReadMacInt16(parseRec + ppStartOffset) + ReadMacInt16(parseRec + ppComponentLength) + 1);
					}
				}
			}

			if (result == noErr) {

				// There is no more pathname to parse
				if (ReadMacInt16(parseRec + ppComponentLength) == 0) {

					// Pathname ended with '::' or was simply a volume name, so current directory is the object
					item = p;

				} else {

					// Pathname ended with 'name:' or 'name', so name is the object
					char name[32];
					strn2cstr(name, (char *)Mac2HostAddr(ReadMacInt32(parseRec + ppNamePtr)) + ReadMacInt16(parseRec + ppStartOffset) + 1, ReadMacInt16(parseRec + ppComponentLength));
					D(bug("  object is %s\n", name));
					item = find_fsitem_guest(name, p);
				}
			}
		}

	} else {

		// Default to bad name
		result = bdNamErr;

		if (ReadMacInt32(pb + ioNamePtr) == 0 || ReadMacInt8(ReadMacInt32(pb + ioNamePtr)) == 0) {

			// Pathname was NULL or a zero length string, so we found a directory at the end of the string
			item = p;
			result = noErr;
		}
	}

	// Eat the path
	if (result == noErr) {
		get_path_for_fsitem(item);
		D(bug("  path %s\n", full_path));
	}
	return result;
}


/*
 *  Find FCB for given file RefNum
 */

static uint32 find_fcb(int16 refNum)
{
	D(bug("  finding FCB\n"));
	M68kRegisters r;
	r.d[0] = refNum;
	r.a[0] = fs_data + fsReturn;
	Execute68k(fs_data + fsResolveFCB, &r);
	uint32 fcb = ReadMacInt32(fs_data + fsReturn);
	D(bug("  UTResolveFCB() returned %d, fcb %08lx\n", r.d[0], fcb));
	if (r.d[0] & 0xffff)
		return 0;
	else
		return fcb;
}


/*
 *  HFS interface functions
 */

// Check if volume belongs to our FS
static int16 fs_mount_vol(uint32 pb)
{
	D(bug(" fs_mount_vol(%08lx), vRefNum %d\n", pb, ReadMacInt16(pb + ioVRefNum)));
	if ((int16)ReadMacInt16(pb + ioVRefNum) == drive_number)
		return noErr;
	else
		return extFSErr;
}

// Mount volume
static int16 fs_volume_mount(uint32 pb)
{
	D(bug(" fs_volume_mount(%08lx)\n", pb));
	M68kRegisters r;

	// Create new VCB
	D(bug("  creating VCB\n"));
	r.a[0] = fs_data + fsReturn;
	r.a[1] = fs_data + fsReturn + 2;
	Execute68k(fs_data + fsAllocateVCB, &r);
#if DEBUG
	uint16 sysVCBLength = ReadMacInt16(fs_data + fsReturn);
#endif
	uint32 vcb = ReadMacInt32(fs_data + fsReturn + 2);
	D(bug("  UTAllocateVCB() returned %d, vcb %08lx, size %d\n", r.d[0], vcb, sysVCBLength));
	if (r.d[0] & 0xffff)
		return (int16)r.d[0];

	// Init VCB
	WriteMacInt16(vcb + vcbSigWord, 0x4244);
#if defined(__BEOS__) || defined(WIN32)
	WriteMacInt32(vcb + vcbCrDate, TimeToMacTime(root_stat.st_crtime));
#elif defined __APPLE__ && defined __MACH__
	WriteMacInt32(vcb + vcbCrDate, get_creation_time(RootPath));
#else
	WriteMacInt32(vcb + vcbCrDate, 0);
#endif
	WriteMacInt32(vcb + vcbLsMod, TimeToMacTime(root_stat.st_mtime));
	WriteMacInt32(vcb + vcbVolBkUp, 0);
	WriteMacInt16(vcb + vcbNmFls, 1);			//!!
	WriteMacInt16(vcb + vcbNmRtDirs, 1);		//!!
	WriteMacInt16(vcb + vcbNmAlBlks, 0xffff);	//!!
	WriteMacInt32(vcb + vcbAlBlkSiz, AL_BLK_SIZE);
	WriteMacInt32(vcb + vcbClpSiz, CLUMP_SIZE);
	WriteMacInt32(vcb + vcbNxtCNID, next_cnid);
	WriteMacInt16(vcb + vcbFreeBks, 0xffff);	//!!
	Host2Mac_memcpy(vcb + vcbVN, VOLUME_NAME, 28);
	WriteMacInt16(vcb + vcbFSID, MY_FSID);
	WriteMacInt32(vcb + vcbFilCnt, 1);			//!!
	WriteMacInt32(vcb + vcbDirCnt, 1);			//!!

	// Add VCB to VCB queue
	D(bug("  adding VCB to queue\n"));
	r.d[0] = drive_number;
	r.a[0] = fs_data + fsReturn;
	r.a[1] = vcb;
	Execute68k(fs_data + fsAddNewVCB, &r);
	int16 vRefNum = (int16)ReadMacInt32(fs_data + fsReturn);
	D(bug("  UTAddNewVCB() returned %d, vRefNum %d\n", r.d[0], vRefNum));
	if (r.d[0] & 0xffff)
		return (int16)r.d[0];

	// Post diskInsertEvent
	D(bug("  posting diskInsertEvent\n"));
	r.d[0] = drive_number;
	r.a[0] = 7;	// diskEvent
	Execute68kTrap(0xa02f, &r);		// PostEvent()

	// Return volume RefNum
	WriteMacInt16(pb + ioVRefNum, vRefNum);
	return noErr;
}

// Unmount volume
static int16 fs_unmount_vol(uint32 vcb)
{
	D(bug(" fs_unmount_vol(%08lx), vRefNum %d\n", vcb, ReadMacInt16(vcb + vcbVRefNum)));
	M68kRegisters r;

	// Remove and free VCB
	D(bug("  freeing VCB\n"));
	r.a[0] = vcb;
	Execute68k(fs_data + fsDisposeVCB, &r);
	D(bug("  UTDisposeVCB() returned %d\n", r.d[0]));
	return (int16)r.d[0];
}

// Get information about a volume (HVolumeParam)
static int16 fs_get_vol_info(uint32 pb, bool hfs)
{
//	D(bug(" fs_get_vol_info(%08lx)\n", pb));

	// Fill in struct
	if (ReadMacInt32(pb + ioNamePtr))
		pstrcpy((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), VOLUME_NAME);
#if defined(__BEOS__) || defined(WIN32)
	WriteMacInt32(pb + ioVCrDate, TimeToMacTime(root_stat.st_crtime));
#elif defined __APPLE__ && defined __MACH__
	WriteMacInt32(pb + ioVCrDate, get_creation_time(RootPath));
#else
	WriteMacInt32(pb + ioVCrDate, 0);
#endif
	WriteMacInt32(pb + ioVLsMod, TimeToMacTime(root_stat.st_mtime));
	WriteMacInt16(pb + ioVAtrb, 0);
	WriteMacInt16(pb + ioVNmFls, 1);			//!!
	WriteMacInt16(pb + ioVBitMap, 0);
	WriteMacInt16(pb + ioAllocPtr, 0);
	WriteMacInt16(pb + ioVNmAlBlks, 0xffff);	//!!
	WriteMacInt32(pb + ioVAlBlkSiz, AL_BLK_SIZE);
	WriteMacInt32(pb + ioVClpSiz, CLUMP_SIZE);
	WriteMacInt16(pb + ioAlBlSt, 0);
	WriteMacInt32(pb + ioVNxtCNID, next_cnid);
	WriteMacInt16(pb + ioVFrBlk, 0xffff);		//!!
	if (hfs) {
		WriteMacInt16(pb + ioVDrvInfo, drive_number);
		WriteMacInt16(pb + ioVDRefNum, ReadMacInt16(fs_data + fsDrvStatus + dsQRefNum));
		WriteMacInt16(pb + ioVFSID, MY_FSID);
		WriteMacInt32(pb + ioVBkUp, 0);
		WriteMacInt16(pb + ioVSeqNum, 0);
		WriteMacInt32(pb + ioVWrCnt, 0);
		WriteMacInt32(pb + ioVFilCnt, 1);			//!!
		WriteMacInt32(pb + ioVDirCnt, 1);			//!!
		Mac_memset(pb + ioVFndrInfo, 0, 32);
	}
	return noErr;
}

// Change volume information (HVolumeParam)
static int16 fs_set_vol_info(uint32 pb)
{
	D(bug(" fs_set_vol_info(%08lx)\n", pb));

	//!! times
	return noErr;
}

// Get volume parameter block
static int16 fs_get_vol_parms(uint32 pb)
{
//	D(bug(" fs_get_vol_parms(%08lx)\n", pb));

	// Return parameter block
	uint32 actual = ReadMacInt32(pb + ioReqCount);
	if (actual > SIZEOF_GetVolParmsInfoBuffer)
		actual = SIZEOF_GetVolParmsInfoBuffer;
	WriteMacInt32(pb + ioActCount, actual);
	uint32 p = ReadMacInt32(pb + ioBuffer);
	if (actual > vMVersion) WriteMacInt16(p + vMVersion, 2);
	if (actual > vMAttrib) WriteMacInt32(p + vMAttrib, kNoMiniFndr | kNoVNEdit | kNoLclSync | kTrshOffLine | kNoSwitchTo | kNoBootBlks | kNoSysDir | kHasExtFSVol);
	if (actual > vMLocalHand) WriteMacInt32(p + vMLocalHand, 0);
	if (actual > vMServerAdr) WriteMacInt32(p + vMServerAdr, 0);
	if (actual > vMVolumeGrade) WriteMacInt32(p + vMVolumeGrade, 0);
	if (actual > vMForeignPrivID) WriteMacInt16(p + vMForeignPrivID, 0);
	return noErr;
}

// Get default volume (WDParam)
static int16 fs_get_vol(uint32 pb)
{
	D(bug(" fs_get_vol(%08lx)\n", pb));
	M68kRegisters r;

	// Getting default volume
	D(bug("  getting default volume\n"));
	r.a[0] = pb;
	Execute68k(fs_data + fsGetDefaultVol, &r);
	D(bug("  UTGetDefaultVol() returned %d\n", r.d[0]));
	return (int16)r.d[0];
}

// Set default volume (WDParam)
static int16 fs_set_vol(uint32 pb, bool hfs, uint32 vcb)
{
	D(bug(" fs_set_vol(%08lx), vRefNum %d, name %.31s, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt32(pb + ioWDDirID)));
	M68kRegisters r;

	// Determine parameters
	uint32 dirID;
	int16 refNum;
	if (hfs) {

		// Find FSItem for given dir
		FSItem *fs_item;
		int16 result = get_item_and_path(pb, ReadMacInt32(pb + ioWDDirID), fs_item);
		if (result != noErr)
			return result;

		// Is it a directory?
		struct stat st;
		if (stat(full_path, &st))
			return dirNFErr;
		if (!S_ISDIR(st.st_mode))
			return dirNFErr;

		// Get dirID and refNum
		dirID = fs_item->id;
		refNum = ReadMacInt16(vcb + vcbVRefNum);

	} else {

		// Is the given vRefNum a working directory number?
		D(bug("  checking for WDRefNum\n"));
		r.d[0] = ReadMacInt16(pb + ioVRefNum);
		Execute68k(fs_data + fsCheckWDRefNum, &r);
		D(bug("  UTCheckWDRefNum() returned %d\n", r.d[0]));
		if (r.d[0] & 0xffff) {
			// Volume refNum
			dirID = ROOT_ID;
			refNum = ReadMacInt16(vcb + vcbVRefNum);
		} else {
			// WD refNum
			dirID = 0;
			refNum = ReadMacInt16(pb + ioVRefNum);
		}
	}

	// Setting default volume
	D(bug("  setting default volume\n"));
	r.d[0] = 0;
	r.d[1] = dirID;
	r.d[2] = refNum;
	Execute68k(fs_data + fsSetDefaultVol, &r);
	D(bug("  UTSetDefaultVol() returned %d\n", r.d[0]));
	return (int16)r.d[0];
}

// Query file attributes (HFileParam)
static int16 fs_get_file_info(uint32 pb, bool hfs, uint32 dirID)
{
	D(bug(" fs_get_file_info(%08lx), vRefNum %d, name %.31s, idx %d, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt16(pb + ioFDirIndex), dirID));

	FSItem *fs_item;
	int16 dir_index = ReadMacInt16(pb + ioFDirIndex);
	if (dir_index <= 0) {		// Query item specified by ioDirID and ioNamePtr

		// Find FSItem for given file
		int16 result = get_item_and_path(pb, dirID, fs_item);
		if (result != noErr)
			return result;

	} else {					// Query item in directory specified by ioDirID by index

		// Find FSItem for parent directory
		int16 result;
		uint32 current_dir;
		if ((result = get_current_dir(pb, dirID, current_dir, true)) != noErr)
			return result;
		FSItem *p = find_fsitem_by_id(current_dir);
		if (p == NULL)
			return dirNFErr;
		get_path_for_fsitem(p);

		// Look for nth item in directory and add name to path
		DIR *d = opendir(full_path);
		if (d == NULL)
			return dirNFErr;
		struct dirent *de = NULL;
		for (int i=0; i<dir_index; i++) {
read_next_de:
			de = readdir(d);
			if (de == NULL) {
				closedir(d);
				return fnfErr;
			}
			if (de->d_name[0] == '.')
				goto read_next_de;	// Suppress names beginning with '.' (MacOS could interpret these as driver names)
			//!! suppress directories
		}
		add_path_comp(de->d_name);

		// Get FSItem for queried item
		fs_item = find_fsitem(de->d_name, p);
		closedir(d);
	}

	// Get stats
	struct stat st;
	if (stat(full_path, &st))
		return fnfErr;
	if (S_ISDIR(st.st_mode))
		return fnfErr;

	// Fill in struct from fs_item and stats
	if (ReadMacInt32(pb + ioNamePtr))
		cstr2pstr((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), fs_item->guest_name);
	WriteMacInt16(pb + ioFRefNum, 0);
	WriteMacInt8(pb + ioFlAttrib, access(full_path, W_OK) == 0 ? 0 : faLocked);
	WriteMacInt32(pb + ioDirID, fs_item->id);

#if defined(__BEOS__) || defined(WIN32)
	WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime));
#elif defined __APPLE__ && defined __MACH__
	WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path));
#else
	WriteMacInt32(pb + ioFlCrDat, 0);
#endif
	WriteMacInt32(pb + ioFlMdDat, TimeToMacTime(st.st_mtime));

	get_finfo(full_path, pb + ioFlFndrInfo, hfs ? pb + ioFlXFndrInfo : 0, false);

	WriteMacInt16(pb + ioFlStBlk, 0);
	uint32 file_size = (uint32) st.st_size;
	WriteMacInt32(pb + ioFlLgLen, file_size);
	WriteMacInt32(pb + ioFlPyLen, (file_size | (AL_BLK_SIZE - 1)) + 1);
	WriteMacInt16(pb + ioFlRStBlk, 0);
	uint32 rf_size = get_rfork_size(full_path);
	WriteMacInt32(pb + ioFlRLgLen, rf_size);
	WriteMacInt32(pb + ioFlRPyLen, (rf_size | (AL_BLK_SIZE - 1)) + 1);

	if (hfs) {
		WriteMacInt32(pb + ioFlBkDat, 0);
		WriteMacInt32(pb + ioFlParID, fs_item->parent_id);
		WriteMacInt32(pb + ioFlClpSiz, 0);
	}
	return noErr;
}

// Set file attributes (HFileParam)
static int16 fs_set_file_info(uint32 pb, bool hfs, uint32 dirID)
{
	D(bug(" fs_set_file_info(%08lx), vRefNum %d, name %.31s, idx %d, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt16(pb + ioFDirIndex), dirID));

	// Find FSItem for given file/dir
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, dirID, fs_item);
	if (result != noErr)
		return result;

	// Get stats
	struct stat st;
	if (stat(full_path, &st) < 0)
		return errno2oserr();
	if (S_ISDIR(st.st_mode))
		return fnfErr;

	// Set Finder info
	set_finfo(full_path, pb + ioFlFndrInfo, hfs ? pb + ioFlXFndrInfo : 0, false);

	//!! times
	return noErr;
}

// Query file/directory attributes
static int16 fs_get_cat_info(uint32 pb)
{
	D(bug(" fs_get_cat_info(%08lx), vRefNum %d, name %.31s, idx %d, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt16(pb + ioFDirIndex), ReadMacInt32(pb + ioDirID)));

	FSItem *fs_item;
	int16 dir_index = ReadMacInt16(pb + ioFDirIndex);
	if (dir_index < 0) {			// Query directory specified by ioDirID

		// Find FSItem for directory
		fs_item = find_fsitem_by_id(ReadMacInt32(pb + ioDrDirID));
		if (fs_item == NULL)
			return dirNFErr;
		get_path_for_fsitem(fs_item);

	} else if (dir_index == 0) {	// Query item specified by ioDirID and ioNamePtr

		// Find FSItem for given file/dir
		int16 result = get_item_and_path(pb, ReadMacInt32(pb + ioDirID), fs_item);
		if (result != noErr)
			return result;

	} else {							// Query item in directory specified by ioDirID by index

		// Find FSItem for parent directory
		int16 result;
		uint32 current_dir;
		if ((result = get_current_dir(pb, ReadMacInt32(pb + ioDirID), current_dir, true)) != noErr)
			return result;
		FSItem *p = find_fsitem_by_id(current_dir);
		if (p == NULL)
			return dirNFErr;
		get_path_for_fsitem(p);

		// Look for nth item in directory and add name to path
		DIR *d = opendir(full_path);
		if (d == NULL)
			return dirNFErr;
		struct dirent *de = NULL;
		for (int i=0; i<dir_index; i++) {
read_next_de:
			de = readdir(d);
			if (de == NULL) {
				closedir(d);
				return fnfErr;
			}
			if (de->d_name[0] == '.')
				goto read_next_de;	// Suppress names beginning with '.' (MacOS could interpret these as driver names)
		}
		add_path_comp(de->d_name);

		// Get FSItem for queried item
		fs_item = find_fsitem(de->d_name, p);
		closedir(d);
	}
	D(bug("  path %s\n", full_path));

	// Get stats
	struct stat st;
	if (stat(full_path, &st) < 0)
		return errno2oserr();
	if (dir_index == -1 && !S_ISDIR(st.st_mode))
		return dirNFErr;

	// Fill in struct from fs_item and stats
	if (ReadMacInt32(pb + ioNamePtr))
		cstr2pstr((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), fs_item->guest_name);
	WriteMacInt16(pb + ioFRefNum, 0);
	WriteMacInt8(pb + ioFlAttrib, (S_ISDIR(st.st_mode) ? faIsDir : 0) | (access(full_path, W_OK) == 0 ? 0 : faLocked));
	WriteMacInt8(pb + ioACUser, 0);
	WriteMacInt32(pb + ioDirID, fs_item->id);
	WriteMacInt32(pb + ioFlParID, fs_item->parent_id);
#if defined(__BEOS__) || defined(WIN32)
	WriteMacInt32(pb + ioFlCrDat, TimeToMacTime(st.st_crtime));
#elif defined __APPLE__ && defined __MACH__
	WriteMacInt32(pb + ioFlCrDat, get_creation_time(full_path));
#else
	WriteMacInt32(pb + ioFlCrDat, 0);
#endif
	time_t mtime = st.st_mtime;
	bool cached = true;
	if (mtime > fs_item->mtime) {
		fs_item->mtime = mtime;
		cached = false;
	}
	WriteMacInt32(pb + ioFlMdDat, TimeToMacTime(mtime));
	WriteMacInt32(pb + ioFlBkDat, 0);

	get_finfo(full_path, pb + ioFlFndrInfo, pb + ioFlXFndrInfo, S_ISDIR(st.st_mode));

	if (S_ISDIR(st.st_mode)) {

		// Determine number of files in directory (cached)
		int count;
		if (cached)
			count = fs_item->cache_dircount;
		else {
			count = 0;
			DIR *d = opendir(full_path);
			if (d) {
				struct dirent *de;
				for (;;) {
					de = readdir(d);
					if (de == NULL)
						break;
					if (de->d_name[0] == '.')
						continue;	// Suppress names beginning with '.'
					count++;
				}
				closedir(d);
			}
			fs_item->cache_dircount = count;
		}
		WriteMacInt16(pb + ioDrNmFls, count);
	} else {
		WriteMacInt16(pb + ioFlStBlk, 0);
		uint32 file_size = (uint32) st.st_size;
		WriteMacInt32(pb + ioFlLgLen, file_size);
		WriteMacInt32(pb + ioFlPyLen, (file_size | (AL_BLK_SIZE - 1)) + 1);
		WriteMacInt16(pb + ioFlRStBlk, 0);
		uint32 rf_size = get_rfork_size(full_path);
		WriteMacInt32(pb + ioFlRLgLen, rf_size);
		WriteMacInt32(pb + ioFlRPyLen, (rf_size | (AL_BLK_SIZE - 1)) + 1);
		WriteMacInt32(pb + ioFlClpSiz, 0);
	}
	return noErr;
}

// Set file/directory attributes
static int16 fs_set_cat_info(uint32 pb)
{
	D(bug(" fs_set_cat_info(%08lx), vRefNum %d, name %.31s, idx %d, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt16(pb + ioFDirIndex), ReadMacInt32(pb + ioDirID)));

	// Find FSItem for given file/dir
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, ReadMacInt32(pb + ioDirID), fs_item);
	if (result != noErr)
		return result;

	// Get stats
	struct stat st;
	if (stat(full_path, &st) < 0)
		return errno2oserr();

	// Set Finder info
	set_finfo(full_path, pb + ioFlFndrInfo, pb + ioFlXFndrInfo, S_ISDIR(st.st_mode));

	//!! times
	return noErr;
}

// Open file
static int16 fs_open(uint32 pb, uint32 dirID, uint32 vcb, bool resource_fork)
{
	D(bug(" fs_open(%08lx), %s, vRefNum %d, name %.31s, dirID %d, perm %d\n", pb, resource_fork ? "rsrc" : "data", ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), dirID, ReadMacInt8(pb + ioPermssn)));
	M68kRegisters r;

	// Find FSItem for given file
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, dirID, fs_item);
	if (result != noErr)
		return result;

	// Convert ioPermssn to open() flag
	int flag = 0;
	bool write_ok = (access(full_path, W_OK) == 0);
	switch (ReadMacInt8(pb + ioPermssn)) {
		case fsCurPerm:		// Whatever is currently allowed
			if (write_ok)
				flag = O_RDWR;
			else
				flag = O_RDONLY;
			break;
		case fsRdPerm:		// Exclusive read
			flag = O_RDONLY;
			break;
		case fsWrPerm:		// Exclusive write
			flag = O_WRONLY;
			break;
		case fsRdWrPerm:	// Exclusive read/write
		case fsRdWrShPerm:	// Shared read/write
		default:
			flag = O_RDWR;
			break;
	}

	// Try to open and stat the file
	int fd = -1;
	struct stat st;
	if (resource_fork) {
		if (access(full_path, F_OK))
			return fnfErr;
		fd = open_rfork(full_path, flag);
		if (fd >= 0) {
			if (fstat(fd, &st) < 0) {
				close(fd);
				return errno2oserr();
			}
		} else {	// Resource fork not supported, silently ignore it ("pseudo" resource fork)
			st.st_size = 0;
			st.st_mode = 0;
		}
	} else {
		fd = open(full_path, flag);
		if (fd < 0)
			return errno2oserr();
		if (fstat(fd, &st) < 0) {
			close(fd);
			return errno2oserr();
		}
	}

	// File open, allocate FCB
	D(bug("  allocating FCB\n"));
	r.a[0] = pb + ioRefNum;
	r.a[1] = fs_data + fsReturn;
	Execute68k(fs_data + fsAllocateFCB, &r);
	uint32 fcb = ReadMacInt32(fs_data + fsReturn);
	D(bug("  UTAllocateFCB() returned %d, fRefNum %d, fcb %08lx\n", r.d[0], ReadMacInt16(pb + ioRefNum), fcb));
	if (r.d[0] & 0xffff) {
		close(fd);
		return (int16)r.d[0];
	}

	// Initialize FCB, fd is stored in fcbCatPos
	WriteMacInt32(fcb + fcbFlNm, fs_item->id);
	WriteMacInt8(fcb + fcbFlags, ((flag == O_WRONLY || flag == O_RDWR) ? fcbWriteMask : 0) | (resource_fork ? fcbResourceMask : 0) | (write_ok ? 0 : fcbFileLockedMask));
	uint32 file_size = (uint32) st.st_size;
	WriteMacInt32(fcb + fcbEOF, file_size);
	WriteMacInt32(fcb + fcbPLen, (file_size | (AL_BLK_SIZE - 1)) + 1);
	WriteMacInt32(fcb + fcbCrPs, 0);
	WriteMacInt32(fcb + fcbVPtr, vcb);
	WriteMacInt32(fcb + fcbClmpSize, CLUMP_SIZE);

	get_finfo(full_path, fs_data + fsPB, 0, false);
	WriteMacInt32(fcb + fcbFType, ReadMacInt32(fs_data + fsPB + fdType));

	WriteMacInt32(fcb + fcbCatPos, fd);
	WriteMacInt32(fcb + fcbDirID, fs_item->parent_id);
	cstr2pstr((char *)Mac2HostAddr(fcb + fcbCName), fs_item->guest_name);
	return noErr;
}

// Close file
static int16 fs_close(uint32 pb)
{
	D(bug(" fs_close(%08lx), refNum %d\n", pb, ReadMacInt16(pb + ioRefNum)));
	M68kRegisters r;

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);

	// Close file
	if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {
		FSItem *item = find_fsitem_by_id(ReadMacInt32(fcb + fcbFlNm));
		if (item) {
			get_path_for_fsitem(item);
			close_rfork(full_path, fd);
		}
	} else
		close(fd);
	WriteMacInt32(fcb + fcbCatPos, (uint32)-1);

	// Release FCB
	D(bug("  releasing FCB\n"));
	r.d[0] = ReadMacInt16(pb + ioRefNum);
	Execute68k(fs_data + fsReleaseFCB, &r);
	D(bug("  UTReleaseFCB() returned %d\n", r.d[0]));
	return (int16)r.d[0];
}

// Query information about FCB (FCBPBRec)
static int16 fs_get_fcb_info(uint32 pb, uint32 vcb)
{
	D(bug(" fs_get_fcb_info(%08lx), vRefNum %d, refNum %d, idx %d\n", pb, ReadMacInt16(pb + ioVRefNum), ReadMacInt16(pb + ioRefNum), ReadMacInt16(pb + ioFCBIndx)));
	M68kRegisters r;

	uint32 fcb = 0;
	if (ReadMacInt16(pb + ioFCBIndx) == 0) {	// Get information about single file

		// Find FCB for file
		fcb = find_fcb(ReadMacInt16(pb + ioRefNum));

	} else {					// Get information about file specified by index

		// Find FCB by index
		WriteMacInt16(pb + ioRefNum, 0);
		for (int i=0; i<(int)ReadMacInt16(pb + ioFCBIndx); i++) {
			D(bug("  indexing FCBs\n"));
			r.a[0] = vcb;
			r.a[1] = pb + ioRefNum;
			r.a[2] = fs_data + fsReturn;
			Execute68k(fs_data + fsIndexFCB, &r);
			fcb = ReadMacInt32(fs_data + fsReturn);
			D(bug("  UTIndexFCB() returned %d, fcb %p\n", r.d[0], fcb));
			if (r.d[0] & 0xffff)
				return (int16)r.d[0];
		}
	}
	if (fcb == 0)
		return rfNumErr;

	// Copy information from FCB
	if (ReadMacInt32(pb + ioNamePtr))
		pstrcpy((char *)Mac2HostAddr(ReadMacInt32(pb + ioNamePtr)), (char *)Mac2HostAddr(fcb + fcbCName));
	WriteMacInt32(pb + ioFCBFlNm, ReadMacInt32(fcb + fcbFlNm));
	WriteMacInt8(pb + ioFCBFlags, ReadMacInt8(fcb + fcbFlags));
	WriteMacInt16(pb + ioFCBStBlk, ReadMacInt16(fcb + fcbSBlk));
	WriteMacInt32(pb + ioFCBEOF, ReadMacInt32(fcb + fcbEOF));
	WriteMacInt32(pb + ioFCBPLen, ReadMacInt32(fcb + fcbPLen));
	WriteMacInt32(pb + ioFCBCrPs, ReadMacInt32(fcb + fcbCrPs));
	WriteMacInt16(pb + ioFCBVRefNum, ReadMacInt16(ReadMacInt32(fcb + fcbVPtr) + vcbVRefNum));
	WriteMacInt32(pb + ioFCBClpSiz, ReadMacInt32(fcb + fcbClmpSize));
	WriteMacInt32(pb + ioFCBParID, ReadMacInt32(fcb + fcbDirID));
	return noErr;
}

// Obtain logical size of an open file
static int16 fs_get_eof(uint32 pb)
{
	D(bug(" fs_get_eof(%08lx), refNum %d\n", pb, ReadMacInt16(pb + ioRefNum)));
	M68kRegisters r;

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {	// "pseudo" resource fork
			WriteMacInt32(pb + ioMisc, 0);
			return noErr;
		} else
			return fnOpnErr;
	}

	// Get file size
	struct stat st;
	if (fstat(fd, &st) < 0)
		return errno2oserr();

	// Adjust FCBs
	uint32 file_size = (uint32) st.st_size;
	WriteMacInt32(fcb + fcbEOF, file_size);
	WriteMacInt32(fcb + fcbPLen, (file_size | (AL_BLK_SIZE - 1)) + 1);
	WriteMacInt32(pb + ioMisc, file_size);
	D(bug("  adjusting FCBs\n"));
	r.d[0] = ReadMacInt16(pb + ioRefNum);
	Execute68k(fs_data + fsAdjustEOF, &r);
	D(bug("  UTAdjustEOF() returned %d\n", r.d[0]));
	return noErr;
}

// Truncate file
static int16 fs_set_eof(uint32 pb)
{
	D(bug(" fs_set_eof(%08lx), refNum %d, size %d\n", pb, ReadMacInt16(pb + ioRefNum), ReadMacInt32(pb + ioMisc)));
	M68kRegisters r;

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask)	// "pseudo" resource fork
			return noErr;
		else
			return fnOpnErr;
	}

	// Truncate file
	uint32 size = ReadMacInt32(pb + ioMisc);
	if (ftruncate(fd, size) < 0)
		return errno2oserr();

	// Adjust FCBs
	WriteMacInt32(fcb + fcbEOF, size);
	WriteMacInt32(fcb + fcbPLen, (size | (AL_BLK_SIZE - 1)) + 1);
	D(bug("  adjusting FCBs\n"));
	r.d[0] = ReadMacInt16(pb + ioRefNum);
	Execute68k(fs_data + fsAdjustEOF, &r);
	D(bug("  UTAdjustEOF() returned %d\n", r.d[0]));
	return noErr;
}

// Query current file position
static int16 fs_get_fpos(uint32 pb)
{
	D(bug(" fs_get_fpos(%08lx), refNum %d\n", pb, ReadMacInt16(pb + ioRefNum)));

	WriteMacInt32(pb + ioReqCount, 0);
	WriteMacInt32(pb + ioActCount, 0);
	WriteMacInt16(pb + ioPosMode, 0);

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {	// "pseudo" resource fork
			WriteMacInt32(pb + ioPosOffset, 0);
			return noErr;
		} else
			return fnOpnErr;
	}

	// Get file position
	uint32 pos = (uint32) lseek(fd, 0, SEEK_CUR);
	WriteMacInt32(fcb + fcbCrPs, pos);
	WriteMacInt32(pb + ioPosOffset, pos);
	return noErr;
}

// Set current file position
static int16 fs_set_fpos(uint32 pb)
{
	D(bug(" fs_set_fpos(%08lx), refNum %d, posMode %d, offset %d\n", pb, ReadMacInt16(pb + ioRefNum), ReadMacInt16(pb + ioPosMode), ReadMacInt32(pb + ioPosOffset)));

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {	// "pseudo" resource fork
			WriteMacInt32(pb + ioPosOffset, 0);
			return noErr;
		} else
			return fnOpnErr;
	}

	// Set file position
	switch (ReadMacInt16(pb + ioPosMode) & 3) {
		case fsFromStart:
			if (lseek(fd, ReadMacInt32(pb + ioPosOffset), SEEK_SET) < 0)
				return posErr;
			break;
		case fsFromLEOF:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_END) < 0)
				return posErr;
			break;
		case fsFromMark:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_CUR) < 0)
				return posErr;
			break;
		default:
			break;
	}
	uint32 pos = (uint32) lseek(fd, 0, SEEK_CUR);
	WriteMacInt32(fcb + fcbCrPs, pos);
	WriteMacInt32(pb + ioPosOffset, pos);
	return noErr;
}

// Read from file
static int16 fs_read(uint32 pb)
{
	D(bug(" fs_read(%08lx), refNum %d, buffer %p, count %d, posMode %d, posOffset %d\n", pb, ReadMacInt16(pb + ioRefNum), ReadMacInt32(pb + ioBuffer), ReadMacInt32(pb + ioReqCount), ReadMacInt16(pb + ioPosMode), ReadMacInt32(pb + ioPosOffset)));

	// Check parameters
	if ((int32)ReadMacInt32(pb + ioReqCount) < 0)
		return paramErr;

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {	// "pseudo" resource fork
			WriteMacInt32(pb + ioActCount, 0);
			return eofErr;
		} else
			return fnOpnErr;
	}

	// Seek
	switch (ReadMacInt16(pb + ioPosMode) & 3) {
		case fsFromStart:
			if (lseek(fd, ReadMacInt32(pb + ioPosOffset), SEEK_SET) < 0)
				return posErr;
			break;
		case fsFromLEOF:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_END) < 0)
				return posErr;
			break;
		case fsFromMark:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_CUR) < 0)
				return posErr;
			break;
	}

	// Read
	ssize_t actual = extfs_read(fd, Mac2HostAddr(ReadMacInt32(pb + ioBuffer)), ReadMacInt32(pb + ioReqCount));
	int16 read_err = errno2oserr();
	D(bug("  actual %d\n", actual));
	WriteMacInt32(pb + ioActCount, actual >= 0 ? actual : 0);
	uint32 pos = (uint32) lseek(fd, 0, SEEK_CUR);
	WriteMacInt32(fcb + fcbCrPs, pos);
	WriteMacInt32(pb + ioPosOffset, pos);
	if (actual != (ssize_t)ReadMacInt32(pb + ioReqCount))
		return actual < 0 ? read_err : eofErr;
	else
		return noErr;
}

// Write to file
static int16 fs_write(uint32 pb)
{
	D(bug(" fs_write(%08lx), refNum %d, buffer %p, count %d, posMode %d, posOffset %d\n", pb, ReadMacInt16(pb + ioRefNum), ReadMacInt32(pb + ioBuffer), ReadMacInt32(pb + ioReqCount), ReadMacInt16(pb + ioPosMode), ReadMacInt32(pb + ioPosOffset)));

	// Check parameters
	if ((int32)ReadMacInt32(pb + ioReqCount) < 0)
		return paramErr;

	// Find FCB and fd for file
	uint32 fcb = find_fcb(ReadMacInt16(pb + ioRefNum));
	if (fcb == 0)
		return rfNumErr;
	if (ReadMacInt32(fcb + fcbFlNm) == 0)
		return fnOpnErr;
	int fd = ReadMacInt32(fcb + fcbCatPos);
	if (fd < 0) {
		if (ReadMacInt8(fcb + fcbFlags) & fcbResourceMask) {	// "pseudo" resource fork
			WriteMacInt32(pb + ioActCount, ReadMacInt32(pb + ioReqCount));
			return noErr;
		} else
			return fnOpnErr;
	}

	// Seek
	switch (ReadMacInt16(pb + ioPosMode) & 3) {
		case fsFromStart:
			if (lseek(fd, ReadMacInt32(pb + ioPosOffset), SEEK_SET) < 0)
				return posErr;
			break;
		case fsFromLEOF:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_END) < 0)
				return posErr;
			break;
		case fsFromMark:
			if (lseek(fd, (int32)ReadMacInt32(pb + ioPosOffset), SEEK_CUR) < 0)
				return posErr;
			break;
	}

	// Write
	ssize_t actual = extfs_write(fd, Mac2HostAddr(ReadMacInt32(pb + ioBuffer)), ReadMacInt32(pb + ioReqCount));
	int16 write_err = errno2oserr();
	D(bug("  actual %d\n", actual));
	WriteMacInt32(pb + ioActCount, actual >= 0 ? actual : 0);
	uint32 pos = (uint32) lseek(fd, 0, SEEK_CUR);
	WriteMacInt32(fcb + fcbCrPs, pos);
	WriteMacInt32(pb + ioPosOffset, pos);
	if (actual != (ssize_t)ReadMacInt32(pb + ioReqCount))
		return write_err;
	else
		return noErr;
}

// Create file
static int16 fs_create(uint32 pb, uint32 dirID)
{
	D(bug(" fs_create(%08lx), vRefNum %d, name %.31s, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), dirID));

	// Find FSItem for given file
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, dirID, fs_item);
	if (result != noErr)
		return result;

	// Does the file already exist?
	if (access(full_path, F_OK) == 0)
		return dupFNErr;

	// Create file
	int fd = creat(full_path, 0666);
	if (fd < 0)
		return errno2oserr();
	else {
		close(fd);
		return noErr;
	}
}

// Create directory
static int16 fs_dir_create(uint32 pb)
{
	D(bug(" fs_dir_create(%08lx), vRefNum %d, name %.31s, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt32(pb + ioDirID)));

	// Find FSItem for given directory
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, ReadMacInt32(pb + ioDirID), fs_item);
	if (result != noErr)
		return result;

	// Does the directory already exist?
	if (access(full_path, F_OK) == 0)
		return dupFNErr;

	// Create directory
	if (mkdir(full_path, 0777) < 0)
		return errno2oserr();
	else {
		WriteMacInt32(pb + ioDirID, fs_item->id);
		return noErr;
	}
}

// Delete file/directory
static int16 fs_delete(uint32 pb, uint32 dirID)
{
	D(bug(" fs_delete(%08lx), vRefNum %d, name %.31s, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), dirID));

	// Find FSItem for given file/dir
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, dirID, fs_item);
	if (result != noErr)
		return result;

	// Delete file
	if (!extfs_remove(full_path))
		return errno2oserr();
	else
		return noErr;
}

// Rename file/directory
static int16 fs_rename(uint32 pb, uint32 dirID)
{
	D(bug(" fs_rename(%08lx), vRefNum %d, name %.31s, dirID %d, new name %.31s\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), dirID, Mac2HostAddr(ReadMacInt32(pb + ioMisc) + 1)));

	// Find path of given file/dir
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, dirID, fs_item);
	if (result != noErr)
		return result;

	// Save path of existing item
	char old_path[MAX_PATH_LENGTH];
	strcpy(old_path, full_path);

	// Find path for new name
	Mac2Mac_memcpy(fs_data + fsPB, pb, SIZEOF_IOParam);
	WriteMacInt32(fs_data + fsPB + ioNamePtr, ReadMacInt32(pb + ioMisc));
	FSItem *new_item;
	result = get_item_and_path(fs_data + fsPB, dirID, new_item);
	if (result != noErr)
		return result;

	// Does the new name already exist?
	if (access(full_path, F_OK) == 0)
		return dupFNErr;

	// Rename item
	D(bug("  renaming %s -> %s\n", old_path, full_path));
	if (!extfs_rename(old_path, full_path))
		return errno2oserr();
	else {
		// The ID of the old file/dir has to stay the same, so we swap the IDs of the FSItems
		swap_parent_ids(fs_item->id, new_item->id);
		uint32 t = fs_item->id;
		fs_item->id = new_item->id;
		new_item->id = t;
		return noErr;
	}
}

// Move file/directory (CMovePBRec)
static int16 fs_cat_move(uint32 pb)
{
	D(bug(" fs_cat_move(%08lx), vRefNum %d, name %.31s, dirID %d, new name %.31s, new dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt32(pb + ioDirID), Mac2HostAddr(ReadMacInt32(pb + ioNewName) + 1), ReadMacInt32(pb + ioNewDirID)));

	// Find path of given file/dir
	FSItem *fs_item;
	int16 result = get_item_and_path(pb, ReadMacInt32(pb + ioDirID), fs_item);
	if (result != noErr)
		return result;

	// Save path of existing item
	char old_path[MAX_PATH_LENGTH];
	strcpy(old_path, full_path);

	// Find path for new directory
	Mac2Mac_memcpy(fs_data + fsPB, pb, SIZEOF_IOParam);
	WriteMacInt32(fs_data + fsPB + ioNamePtr, ReadMacInt32(pb + ioNewName));
	FSItem *new_dir_item;
	result = get_item_and_path(fs_data + fsPB, ReadMacInt32(pb + ioNewDirID), new_dir_item);
	if (result != noErr)
		return result;

	// Append old file/dir name
	add_path_comp(fs_item->name);

	// Does the new name already exist?
	if (access(full_path, F_OK) == 0)
		return dupFNErr;

	// Move item
	D(bug("  moving %s -> %s\n", old_path, full_path));
	if (!extfs_rename(old_path, full_path))
		return errno2oserr();
	else {
		// The ID of the old file/dir has to stay the same, so we swap the IDs of the FSItems
		FSItem *new_item = find_fsitem(fs_item->name, new_dir_item);
		if (new_item) {
			swap_parent_ids(fs_item->id, new_item->id);
			uint32 t = fs_item->id;
			fs_item->id = new_item->id;
			new_item->id = t;
		}
		return noErr;
	}
}

// Open working directory (WDParam)
static int16 fs_open_wd(uint32 pb)
{
	D(bug(" fs_open_wd(%08lx), vRefNum %d, name %.31s, dirID %d\n", pb, ReadMacInt16(pb + ioVRefNum), Mac2HostAddr(ReadMacInt32(pb + ioNamePtr) + 1), ReadMacInt32(pb + ioWDDirID)));
	M68kRegisters r;

	// Allocate WDCB
	D(bug("  allocating WDCB\n"));
	r.a[0] = pb;
	Execute68k(fs_data + fsAllocateWDCB, &r);
	D(bug("  UTAllocateWDCB returned %d, refNum is %d\n", r.d[0], ReadMacInt16(pb + ioVRefNum)));
	return (int16)r.d[0];
}

// Close working directory (WDParam)
static int16 fs_close_wd(uint32 pb)
{
	D(bug(" fs_close_wd(%08lx), vRefNum %d\n", pb, ReadMacInt16(pb + ioVRefNum)));
	M68kRegisters r;

	// Release WDCB
	D(bug("  releasing WDCB\n"));
	r.d[0] = ReadMacInt16(pb + ioVRefNum);
	Execute68k(fs_data + fsReleaseWDCB, &r);
	D(bug("  UTReleaseWDCB returned %d\n", r.d[0]));
	return (int16)r.d[0];
}

// Query information about working directory (WDParam)
static int16 fs_get_wd_info(uint32 pb, uint32 vcb)
{
	D(bug(" fs_get_wd_info(%08lx), vRefNum %d, idx %d, procID %d\n", pb, ReadMacInt16(pb + ioVRefNum), ReadMacInt16(pb + ioWDIndex), ReadMacInt32(pb + ioWDProcID)));
	M68kRegisters r;

	// Querying volume?
	if (ReadMacInt16(pb + ioWDIndex) == 0 && ReadMacInt16(pb + ioVRefNum) == ReadMacInt16(vcb + vcbVRefNum)) {
		WriteMacInt32(pb + ioWDProcID, 0);
		WriteMacInt16(pb + ioWDVRefNum, ReadMacInt16(vcb + vcbVRefNum));
		if (ReadMacInt32(pb + ioNamePtr))
			Mac2Mac_memcpy(ReadMacInt32(pb + ioNamePtr), vcb + vcbVN, 28);
		WriteMacInt32(pb + ioWDDirID, ROOT_ID);
		return noErr;
	}

	// Resolve WDCB
	D(bug("  resolving WDCB\n"));
	r.d[0] = ReadMacInt32(pb + ioWDProcID);
	r.d[1] = ReadMacInt16(pb + ioWDIndex);
	r.d[2] = ReadMacInt16(pb + ioVRefNum);
	r.a[0] = fs_data + fsReturn;
	Execute68k(fs_data + fsResolveWDCB, &r);
	uint32 wdcb = ReadMacInt32(fs_data + fsReturn);
	D(bug("  UTResolveWDCB() returned %d, dirID %d\n", r.d[0], ReadMacInt32(wdcb + wdDirID)));
	if (r.d[0] & 0xffff)
		return (int16)r.d[0];

	// Return information
	WriteMacInt32(pb + ioWDProcID, ReadMacInt32(wdcb + wdProcID));
	WriteMacInt16(pb + ioWDVRefNum, ReadMacInt16(ReadMacInt32(wdcb + wdVCBPtr) + vcbVRefNum));
	if (ReadMacInt32(pb + ioNamePtr))
		Mac2Mac_memcpy(ReadMacInt32(pb + ioNamePtr), ReadMacInt32(wdcb + wdVCBPtr) + vcbVN, 28);
	WriteMacInt32(pb + ioWDDirID, ReadMacInt32(wdcb + wdDirID));
	return noErr;
}

// Main dispatch routine
int16 ExtFSHFS(uint32 vcb, uint16 selectCode, uint32 paramBlock, uint32 globalsPtr, int16 fsid)
{
	uint16 trapWord = selectCode & 0xf0ff;
	bool hfs = (selectCode & kHFSMask) != 0;
	switch (trapWord) {
		case kFSMOpen:
			return fs_open(paramBlock, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0, vcb, false);

		case kFSMClose:
			return fs_close(paramBlock);

		case kFSMRead:
			return fs_read(paramBlock);

		case kFSMWrite:
			return fs_write(paramBlock);

		case kFSMGetVolInfo:
			return fs_get_vol_info(paramBlock, hfs);

		case kFSMCreate:
			return fs_create(paramBlock, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0);

		case kFSMDelete:
			return fs_delete(paramBlock, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0);

		case kFSMOpenRF:
			return fs_open(paramBlock, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0, vcb, true);

		case kFSMRename:
			return fs_rename(paramBlock, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0);

		case kFSMGetFileInfo:
			return fs_get_file_info(paramBlock, hfs, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0);

		case kFSMSetFileInfo:
			return fs_set_file_info(paramBlock, hfs, hfs ? ReadMacInt32(paramBlock + ioDirID) : 0);

		case kFSMUnmountVol:
			return fs_unmount_vol(vcb);

		case kFSMMountVol:
			return fs_mount_vol(paramBlock);

		case kFSMAllocate:
			D(bug(" allocate\n"));
			WriteMacInt32(paramBlock + ioActCount, ReadMacInt32(paramBlock + ioReqCount));
			return noErr;

		case kFSMGetEOF:
			return fs_get_eof(paramBlock);

		case kFSMSetEOF:
			return fs_set_eof(paramBlock);

		case kFSMGetVol:
			return fs_get_vol(paramBlock);

		case kFSMSetVol:
			return fs_set_vol(paramBlock, hfs, vcb);

		case kFSMEject:
			D(bug(" eject\n"));
			return noErr;

		case kFSMGetFPos:
			return fs_get_fpos(paramBlock);

		case kFSMOffline:
			D(bug(" offline\n"));
			return noErr;

		case kFSMSetFilLock:
			return noErr;	//!!

		case kFSMRstFilLock:
			return noErr;	//!!

		case kFSMSetFPos:
			return fs_set_fpos(paramBlock);

		case kFSMOpenWD:
			return fs_open_wd(paramBlock);

		case kFSMCloseWD:
			return fs_close_wd(paramBlock);

		case kFSMCatMove:
			return fs_cat_move(paramBlock);

		case kFSMDirCreate:
			return fs_dir_create(paramBlock);

		case kFSMGetWDInfo:
			return fs_get_wd_info(paramBlock, vcb);

		case kFSMGetFCBInfo:
			return fs_get_fcb_info(paramBlock, vcb);

		case kFSMGetCatInfo:
			return fs_get_cat_info(paramBlock);

		case kFSMSetCatInfo:
			return fs_set_cat_info(paramBlock);

		case kFSMSetVolInfo:
			return fs_set_vol_info(paramBlock);

		case kFSMGetVolParms:
			return fs_get_vol_parms(paramBlock);

		case kFSMVolumeMount:
			return fs_volume_mount(paramBlock);

		case kFSMFlushVol:
		case kFSMFlushFile:
			D(bug(" flush_vol/flush_file\n"));
			return noErr;

		default:
			D(bug("ExtFSHFS(%08lx, %04x, %08lx, %08lx, %d)\n", vcb, selectCode, paramBlock, globalsPtr, fsid));
			return paramErr;
	}
}
