#ifndef __HFS__
#define __HFS__
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/queue.h>
#include <sys/attr.h>
#include <sys/dirent.h>
#include <hfs/hfs_format.h>
#include <hfs/hfs_macos_defs.h>
#include <hfs/hfs_encodings.h>
#include <hfs/rangelist.h>
struct uio; struct hfslockf;
#define VERSION_STRING "hfs-2 (4-12-99)"
#define HFS_LINK_MAX 32767
#define FORCE_READONLY 0
enum { kMDBSize = 512 };
enum { kMasterDirectoryBlock = 2 };
enum { kMDBOffset = kMasterDirectoryBlock * 512 };
enum {
kUnknownID = 0,
kRootParID = 1,
kRootDirID = 2
};
enum {
kUndefinedFork = 0,
kDataFork,
kRsrcFork,
kDirectory,
kSysFile,
kDefault,
kAnyFork
};
#define kMaxLockedMetaBuffers 32
enum {
kSymLinkFileType = 0x736C6E6B,
kSymLinkCreator = 0x72686170
};
#define BUFFERPTRLISTSIZE 25
extern char * gBufferAddress[BUFFERPTRLISTSIZE];
extern struct buf *gBufferHeaderPtr[BUFFERPTRLISTSIZE];
extern int gBufferListIndex;
extern simple_lock_data_t gBufferPtrListLock;
extern struct timezone gTimeZone;
#define RELEASE_BUFFER 0x00000001
#define kMaxFreeExtents 10
struct vcb_t {
u_int16_t vcbSigWord;
int16_t vcbAtrb;
int16_t vcbFlags;
int16_t vcbVRefNum;
u_int32_t vcbCrDate;
u_int32_t vcbLsMod;
u_int32_t vcbVolBkUp;
u_int32_t checkedDate;
int32_t vcbFilCnt;
int32_t vcbDirCnt;
u_int32_t blockSize;
u_int32_t totalBlocks;
u_int32_t freeBlocks;
u_int32_t nextAllocation;
int32_t vcbClpSiz;
u_int32_t vcbNxtCNID;
u_int32_t vcbCNIDGen;
int32_t vcbWrCnt;
int32_t vcbFndrInfo[8];
u_int64_t encodingsBitmap;
u_int16_t vcbNmFls;
u_int16_t vcbNmRtDirs;
int16_t vcbVBMSt;
int16_t vcbAlBlSt;
struct vnode * extentsRefNum;
struct vnode * catalogRefNum;
struct vnode * allocationsRefNum;
u_int8_t vcbVN[256];
u_int32_t volumeNameEncodingHint;
u_int32_t altIDSector;
u_int32_t hfsPlusIOPosOffset;
u_int32_t vcbVBMIOSize;
char * hintCachePtr;
u_int32_t vcbFreeExtCnt;
HFSPlusExtentDescriptor vcbFreeExt[kMaxFreeExtents];
u_int32_t localCreateDate;
simple_lock_data_t vcbSimpleLock;
};
typedef struct vcb_t ExtendedVCB;
#define kHFS_DamagedVolume 0x1
#define MARK_VOLUMEDAMAGED(fcb) FCBTOVCB((fcb))->vcbFlags |= kHFS_DamagedVolume;
typedef struct vfsVCB {
ExtendedVCB vcb_vcb;
struct hfsmount *vcb_hfsmp;
} vfsVCB_t;
typedef struct hfsmount {
u_long hfs_mount_flags;
u_int8_t hfs_fs_clean;
u_int8_t hfs_fs_ronly;
u_int8_t hfs_unknownpermissions;
u_long hfs_phys_block_count;
u_long hfs_phys_block_size;
struct mount *hfs_mp;
struct vnode *hfs_devvp;
dev_t hfs_raw_dev;
struct netexport hfs_export;
u_int32_t hfs_logBlockSize;
uid_t hfs_uid;
gid_t hfs_gid;
mode_t hfs_dir_mask;
mode_t hfs_file_mask;
u_long hfs_encoding;
simple_lock_data_t hfs_renamelock;
struct vfsVCB hfs_vcb;
u_long hfs_private_metadata_dir;
u_int32_t hfs_metadata_createdate;
hfs_to_unicode_func_t hfs_get_unicode;
unicode_to_hfs_func_t hfs_get_hfsname;
} hfsmount_t;
#define HFSPLUS_PRIVATE_DIR \
"\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80\xE2\x90\x80HFS+ Private Data"
#define MAXHFSVNODELEN 31
typedef u_char FileNameStr[MAXHFSVNODELEN+1];
CIRCLEQ_HEAD(siblinghead, hfsnode) ;
struct hfsnode {
LIST_ENTRY(hfsnode) h_hash;
CIRCLEQ_ENTRY(hfsnode) h_sibling;
struct lock__bsd__ h_lock;
union {
struct hfslockf *hu_lockf;
void *hu_sysdata;
char hu_symlinkdata[4];
char *hu_symlinkptr;
} h_un;
struct vnode * h_vp;
struct hfsfilemeta * h_meta;
u_int16_t h_nodeflags;
u_int8_t h_type;
int8_t fcbFlags;
struct rl_head h_invalidranges;
u_int64_t fcbEOF;
u_int64_t fcbPLen;
u_int32_t fcbClmpSize;
HFSPlusExtentRecord fcbExtents;
#if HFS_DIAGNOSTIC
u_int32_t h_valid;
#endif
};
#define h_lockf h_un.hu_lockf
#define fcbBTCBPtr h_un.hu_sysdata
#define h_symlinkptr h_un.hu_symlinkptr
#define h_symlinkdata h_un.hu_symlinkdata
typedef struct hfsnode FCB;
typedef struct hfsfilemeta {
struct siblinghead h_siblinghead;
simple_lock_data_t h_siblinglock;
u_int32_t h_metaflags;
struct vnode *h_devvp;
dev_t h_dev;
u_int32_t h_nodeID;
u_int32_t h_dirID;
u_int32_t h_hint;
off_t h_size;
u_int16_t h_usecount;
u_int16_t h_mode;
u_int32_t h_pflags;
u_int32_t h_uid;
u_int32_t h_gid;
union {
dev_t hu_rdev;
u_int32_t hu_indnodeno;
} h_spun;
u_int32_t h_crtime;
u_int32_t h_atime;
u_int32_t h_mtime;
u_int32_t h_ctime;
u_int32_t h_butime;
u_int16_t h_nlink;
u_short h_namelen;
char * h_namePtr;
FileNameStr h_fileName;
} hfsfilemeta;
#define h_rdev h_spun.hu_rdev
#define h_indnodeno h_spun.hu_indnodeno
#define H_EXTENDSIZE(VP,BYTES) ((VP)->h_meta->h_size += (BYTES))
#define H_TRUNCSIZE(VP,BYTES) ((VP)->h_meta->h_size -= (BYTES))
#define MAKE_INODE_NAME(name,linkno) \
(void) sprintf((name), "%s%d", HFS_INODE_PREFIX, (linkno))
#define H_FORKTYPE(HP) ((HP)->h_type)
#define H_FILEID(HP) ((HP)->h_meta->h_nodeID)
#define H_DIRID(HP) ((HP)->h_meta->h_dirID)
#define H_NAME(HP) ((HP)->h_meta->h_namePtr)
#define H_HINT(HP) ((HP)->h_meta->h_hint)
#define H_DEV(HP) ((HP)->h_meta->h_dev)
#define H_ISBIGLINK(HP) ((HP)->fcbEOF > 4)
#define H_SYMLINK(HP) (H_ISBIGLINK((HP)) ? (HP)->h_symlinkptr : (HP)->h_symlinkdata)
#define IN_ACCESS 0x0001
#define IN_CHANGE 0x0002
#define IN_UPDATE 0x0004
#define IN_MODIFIED 0x0008
#define IN_RENAME 0x0010
#define IN_SHLOCK 0x0020
#define IN_EXLOCK 0x0040
#define IN_BYCNID 0x0100
#define IN_ALLOCATING 0x1000
#define IN_WANT 0x2000
#define IN_LONGNAME 0x0400
#define IN_UNSETACCESS 0x0200
#define IN_DELETED 0x0800
#define IN_NOEXISTS 0x1000
#if HFS_HARDLINKS
#define IN_DATANODE 0x2000
#endif
#define IEXEC 0000100
#define IWRITE 0000200
#define IREAD 0000400
#define ISVTX 0001000
#define ISGID 0002000
#define ISUID 0004000
#define IFMT 0170000
#define IFIFO 0010000
#define IFCHR 0020000
#define IFDIR 0040000
#define IFBLK 0060000
#define IFREG 0100000
#define IFLNK 0120000
#define IFSOCK 0140000
#define IFWHT 0160000
#define HFS_VNODE_MAGIC 0x4846532b
#define SIBLING_FORKTYPE(FORK) ((FORK==kDataFork) || (FORK==kRsrcFork))
#define WRITE_CK(VNODE, FUNC_NAME) { \
if ((VNODE)->v_mount->mnt_flag & MNT_RDONLY) { \
DBG_ERR(("%s: ATTEMPT TO WRITE A READONLY VOLUME\n", \
FUNC_NAME)); \
return(EROFS); \
} \
}
#define MVL_LOCKED 0x00000001
#if HFS_DIAGNOSTIC
#define MVL_LOCK(mvip) { \
(simple_lock(&(mvip)->mvl_lock)); \
(mvip)->mvl_flags |= MVL_LOCKED; \
}
#define MVL_UNLOCK(mvip) { \
if(((mvip)->mvl_flags & MVL_LOCKED) == 0) { \
panic("MVL_UNLOCK - hfsnode not locked"); \
} \
(simple_unlock(&(mvip)->mvl_lock)); \
(mvip)->mvl_flags &= ~MVL_LOCKED; \
}
#else
#define MVL_LOCK(mvip) (simple_lock(&(mvip)->mvl_lock))
#define MVL_UNLOCK(mvip) (simple_unlock(&(mvip)->mvl_lock))
#endif
typedef struct hfsdotentry {
u_int32_t d_fileno;
u_int16_t d_reclen;
u_int8_t d_type;
u_int8_t d_namelen;
char d_name[4];
} hfsdotentry;
#define AVERAGE_HFSDIRENTRY_SIZE (8+22+4)
#define MAX_HFSDIRENTRY_SIZE sizeof(struct dirent)
#define DIRENTRY_SIZE(namlen) \
((sizeof(struct dirent) - (NAME_MAX+1)) + (((namlen)+1 + 3) &~ 3))
enum {
kCatNameIsAllocated = 0x1,
kCatNameIsMangled = 0x2,
kCatNameUsesReserved = 0x4,
kCatNameIsConsumed = 0x8,
kCatNameNoCopyName = 0x10,
kCatNameMangleName = 0x20
};
struct CatalogNameSpecifier {
u_int16_t cnm_flags;
u_int16_t cnm_length;
u_int32_t cnm_parID;
unsigned char *cnm_nameptr;
unsigned char cnm_namespace[MAXHFSVNODELEN+1];
};
enum {
kCatalogFolderNode = 1,
kCatalogFileNode = 2
};
struct CatalogNodeData {
int16_t cnd_type;
u_int16_t cnd_flags;
u_int32_t cnd_valence;
u_int32_t cnd_nodeID;
u_int32_t cnd_createDate;
u_int32_t cnd_contentModDate;
u_int32_t cnd_attributeModDate;
u_int32_t cnd_accessDate;
u_int32_t cnd_backupDate;
u_int32_t cnd_ownerID;
u_int32_t cnd_groupID;
u_int8_t cnd_adminFlags;
u_int8_t cnd_ownerFlags;
u_int16_t cnd_mode;
union {
u_int32_t cndu_iNodeNum;
u_int32_t cndu_linkCount;
u_int32_t cndu_rawDevice;
} cnd_un;
u_int8_t cnd_finderInfo[32];
u_int32_t cnd_textEncoding;
u_int32_t cnd_reserved;
HFSPlusForkData cnd_datafork;
HFSPlusForkData cnd_rsrcfork;
u_int32_t cnd_iNodeNumCopy;
u_int32_t cnd_linkCNID;
u_int8_t cnd_extra[264];
struct CatalogNameSpecifier cnd_namespecifier;
};
typedef struct CatalogNodeData CatalogNodeData;
#define cnd_iNodeNum cnd_un.cndu_iNodeNum
#define cnd_linkCount cnd_un.cndu_linkCount
#define cnd_rawDevice cnd_un.cndu_rawDevice
#define cnm_flags cnd_namespecifier.cnm_flags
#define cnm_length cnd_namespecifier.cnm_length
#define cnm_parID cnd_namespecifier.cnm_parID
#define cnm_nameptr cnd_namespecifier.cnm_nameptr
#define cnm_namespace cnd_namespecifier.cnm_namespace
#define INIT_CATALOGDATA(C,F) do { bzero(&((C)->cnd_namespecifier), sizeof(struct CatalogNameSpecifier)); (C)->cnm_flags=(F);}while(0);
#if HFS_DIAGNOSTIC
extern void debug_check_catalogdata(struct CatalogNodeData *cat);
#define CLEAN_CATALOGDATA(C) do { debug_check_catalogdata(C); \
if ((C)->cnm_flags & kCatNameIsAllocated) {\
FREE((C)->cnm_nameptr, M_TEMP);\
(C)->cnm_flags &= ~kCatNameIsAllocated;\
(C)->cnm_nameptr = NULL;\
}}while(0);
#else
#define CLEAN_CATALOGDATA(C) do { if ((C)->cnm_flags & kCatNameIsAllocated) {\
FREE((C)->cnm_nameptr, M_TEMP);\
(C)->cnm_flags &= ~kCatNameIsAllocated;\
(C)->cnm_nameptr = NULL;\
}}while(0);
#endif
typedef struct hfsCatalogInfo {
CatalogNodeData nodeData;
u_int32_t hint;
} hfsCatalogInfo;
enum { kHFSPlusMaxFileNameBytes = kHFSPlusMaxFileNameChars * 3 };
enum { kdirentMaxNameBytes = NAME_MAX };
struct directoryInfoSpec
{
u_long numFiles;
};
struct fileInfoSpec
{
off_t dataLogicalLength;
off_t dataPhysicalLength;
off_t resourceLogicalLength;
off_t resourcePhysicalLength;
};
struct searchinfospec
{
u_char name[kHFSPlusMaxFileNameBytes];
u_long nameLength;
char attributes; u_long nodeID;
u_long parentDirID;
struct timespec creationDate;
struct timespec modificationDate;
struct timespec changeDate;
struct timespec lastBackupDate;
u_long finderInfo[8];
uid_t uid;
gid_t gid;
mode_t mask;
struct fileInfoSpec f;
struct directoryInfoSpec d;
};
typedef struct searchinfospec searchinfospec_t;
#define HFSTIMES(hp, t1, t2) { \
if ((hp)->h_nodeflags & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
(hp)->h_nodeflags |= IN_MODIFIED; \
if ((hp)->h_nodeflags & IN_ACCESS) { \
(hp)->h_meta->h_atime = (t1)->tv_sec; \
}; \
if ((hp)->h_nodeflags & IN_UPDATE) { \
(hp)->h_meta->h_mtime = (t2)->tv_sec; \
} \
if ((hp)->h_nodeflags & IN_CHANGE) { \
(hp)->h_meta->h_ctime = time.tv_sec; \
}; \
(hp)->h_nodeflags &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
} \
}
struct hfsfid {
u_int16_t hfsfid_len;
u_int16_t hfsfid_pad;
u_int32_t hfsfid_cnid;
u_int32_t hfsfid_gen;
};
#define ISHFSPLUS(VCB) ((VCB)->vcbSigWord == kHFSPlusSigWord)
#define ISHFS(VCB) ((VCB)->vcbSigWord == kHFSSigWord)
#define HTOV(HP) ((HP)->h_vp)
#define VTOH(VP) ((struct hfsnode *)((VP)->v_data))
#define FCBTOH(FCB) ((struct hfsnode *)FCB)
#define HTOFCB(HP) (HP)
#define VTOFCB(VP) ((FCB *)((VP)->v_data))
#define VTOVFS(VP) ((VP)->v_mount)
#define HTOVFS(HP) ((HP)->h_vp->v_mount)
#define FCBTOVFS(FCB) ((FCB)->h_vp->v_mount)
#define HFSTOVFS(HFSMP) ((HFSMP)->hfs_mp)
#define VCBTOVFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp->hfs_mp)
#define VTOHFS(VP) ((struct hfsmount *)((VP)->v_mount->mnt_data))
#define HTOHFS(HP) ((struct hfsmount *)(HP)->h_vp->v_mount->mnt_data)
#define FCBTOHFS(FCB) ((struct hfsmount *)(FCB)->h_vp->v_mount->mnt_data)
#define VFSTOHFS(MP) ((struct hfsmount *)(MP)->mnt_data)
#define VCBTOHFS(VCB) (((struct vfsVCB *)(VCB))->vcb_hfsmp)
#define VTOVCB(VP) (&(((struct hfsmount *)((VP)->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
#define HTOVCB(HP) (&(((struct hfsmount *)((HP)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
#define FCBTOVCB(FCB) (&(((struct hfsmount *)((FCB)->h_vp->v_mount->mnt_data))->hfs_vcb.vcb_vcb))
#define VFSTOVCB(MP) (&(((struct hfsmount *)(MP)->mnt_data)->hfs_vcb.vcb_vcb))
#define HFSTOVCB(HFSMP) (&(HFSMP)->hfs_vcb.vcb_vcb)
#define E_NONE 0
#define kHFSBlockSize 512
#define kHFSBlockShift 9
#define IOBLKNOFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBLOCK) / ((BLOCKSIZEINBYTES) >> 9)))
#define IOBLKCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
((int)(IOBLKNOFORBYTE(((STARTINGBLOCK) * 512) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) + 1))
#define IOBYTECCNTFORBLK(STARTINGBLOCK, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
(IOBLKCNTFORBLK((STARTINGBLOCK),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
#define IOBYTEOFFSETFORBLK(STARTINGBLOCK, BLOCKSIZEINBYTES) \
(((STARTINGBLOCK) * 512) - \
(IOBLKNOFORBLK((STARTINGBLOCK), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
#define IOBLKNOFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((daddr_t)((STARTINGBYTE) / (BLOCKSIZEINBYTES)))
#define IOBLKCNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
((int)(IOBLKNOFORBYTE((STARTINGBYTE) + (BYTESTOTRANSFER) - 1, (BLOCKSIZEINBYTES)) - \
IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) + 1))
#define IOBYTECNTFORBYTE(STARTINGBYTE, BYTESTOTRANSFER, BLOCKSIZEINBYTES) \
(IOBLKCNTFORBYTE((STARTINGBYTE),(BYTESTOTRANSFER),(BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES))
#define IOBYTEOFFSETFORBYTE(STARTINGBYTE, BLOCKSIZEINBYTES) ((STARTINGBYTE) - (IOBLKNOFORBYTE((STARTINGBYTE), (BLOCKSIZEINBYTES)) * (BLOCKSIZEINBYTES)))
#define MAKE_VREFNUM(x) ((int32_t)((x) & 0xffff))
#define MAC_GMT_FACTOR 2082844800UL
#define HFS_ATTR_CMN_LOOKUPMASK (ATTR_CMN_SCRIPT | ATTR_CMN_FNDRINFO | ATTR_CMN_NAMEDATTRCOUNT | ATTR_CMN_NAMEDATTRLIST)
#define HFS_ATTR_DIR_LOOKUPMASK (ATTR_DIR_LINKCOUNT | ATTR_DIR_ENTRYCOUNT)
#define HFS_ATTR_FILE_LOOKUPMASK (ATTR_FILE_LINKCOUNT | ATTR_FILE_TOTALSIZE | ATTR_FILE_ALLOCSIZE | \
ATTR_FILE_DATALENGTH | ATTR_FILE_DATAALLOCSIZE | ATTR_FILE_DATAEXTENTS | \
ATTR_FILE_RSRCLENGTH | ATTR_FILE_RSRCALLOCSIZE | ATTR_FILE_RSRCEXTENTS)
u_int32_t to_bsd_time(u_int32_t hfs_time);
u_int32_t to_hfs_time(u_int32_t bsd_time);
int hfs_flushfiles(struct mount *mp, int flags);
short hfs_flushMDB(struct hfsmount *hfsmp, int waitfor);
short hfs_flushvolumeheader(struct hfsmount *hfsmp, int waitfor);
short hfs_getcatalog (ExtendedVCB *vcb, u_int32_t dirID, char *name, short len, hfsCatalogInfo *catInfo);
short hfsMoveRename (ExtendedVCB *vcb, u_int32_t oldDirID, char *oldName, u_int32_t newDirID, char *newName, u_int32_t *hint);
short hfsCreate (ExtendedVCB *vcb, u_int32_t dirID, char *name, int mode, u_int32_t tehint);
short hfsCreateFileID (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, u_int32_t catalogHint, u_int32_t *fileIDPtr);
short hfs_vcreate (ExtendedVCB *vcb, hfsCatalogInfo *catInfo, u_int8_t forkType, struct vnode **vpp);
short hfsDelete (ExtendedVCB *vcb, u_int32_t parentDirID, StringPtr name, short isfile, u_int32_t catalogHint);
short hfsUnmount(struct hfsmount *hfsmp, struct proc *p);
extern int hfs_metafilelocking(struct hfsmount *hfsmp, u_long fileID, u_int flags, struct proc *p);
extern int hasOverflowExtents(struct hfsnode *hp);
void hfs_set_metaname(char *, struct hfsfilemeta *, struct hfsmount *);
short MacToVFSError(OSErr err);
int hfs_owner_rights(struct vnode *vp, struct ucred *cred, struct proc *p, Boolean invokesuperuserstatus);
void CopyVNodeToCatalogNode (struct vnode *vp, struct CatalogNodeData *nodeData);
void CopyCatalogToHFSNode(struct hfsCatalogInfo *catalogInfo, struct hfsnode *hp);
u_long FindMetaDataDirectory(ExtendedVCB *vcb);
short make_dir_entry(FCB **fileptr, char *name, u_int32_t fileID);
int AttributeBlockSize(struct attrlist *attrlist);
void PackCommonAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void PackVolAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void PackFileDirAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void PackForkAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void PackAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void PackCatalogInfoAttributeBlock (struct attrlist *alist,
struct vnode * root_vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void UnpackCommonAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
void UnpackAttributeBlock(struct attrlist *alist,
struct vnode *vp,
struct hfsCatalogInfo *catInfo,
void **attrbufptrptr,
void **varbufptrptr);
unsigned long BestBlockSizeFit(unsigned long allocationBlockSize,
unsigned long blockSizeLimit,
unsigned long baseMultiple);
OSErr hfs_MountHFSVolume(struct hfsmount *hfsmp, HFSMasterDirectoryBlock *mdb,
u_long sectors, struct proc *p);
OSErr hfs_MountHFSPlusVolume(struct hfsmount *hfsmp, HFSPlusVolumeHeader *vhp,
u_long embBlkOffset, u_long sectors, struct proc *p);
OSStatus GetInitializedVNode(struct hfsmount *hfsmp, struct vnode **tmpvnode);
int hfs_getconverter(u_int32_t encoding, hfs_to_unicode_func_t *get_unicode,
unicode_to_hfs_func_t *get_hfsname);
int hfs_relconverter(u_int32_t encoding);
int hfs_to_utf8(ExtendedVCB *vcb, Str31 hfs_str, ByteCount maxDstLen,
ByteCount *actualDstLen, unsigned char* dstStr);
int utf8_to_hfs(ExtendedVCB *vcb, ByteCount srcLen, const unsigned char* srcStr,
Str31 dstStr);
int mac_roman_to_utf8(Str31 hfs_str, ByteCount maxDstLen, ByteCount *actualDstLen,
unsigned char* dstStr);
int utf8_to_mac_roman(ByteCount srcLen, const unsigned char* srcStr, Str31 dstStr);
u_int32_t hfs_pickencoding(const u_int16_t *src, int len);
#endif