#ifndef lf_hfs_catalog_h
#define lf_hfs_catalog_h
#include "lf_hfs_format.h"
#include "lf_hfs_locks.h"
#include <sys/queue.h>
#define HFS_IDHASH_DEFAULT (64)
#define CAT_DELETE 0x00010000
#define CAT_CREATE 0x00000002
#define CAT_RENAME 0x00010002
#define CAT_EXCHANGE 0x00010002
typedef struct
{
void* pvBuffer;
uint64_t uBufferResid;
uint64_t uBufferSize;
} ReadDirBuff_s, *ReadDirBuff_t;
#define READDIR_BUF_OFFSET(buf) (buf->uBufferSize - buf->uBufferResid)
typedef u_int32_t cnid_t;
struct cat_desc {
u_int8_t cd_flags;
u_int8_t cd_encoding;
int16_t cd_namelen;
cnid_t cd_parentcnid;
u_int32_t cd_hint;
cnid_t cd_cnid;
const u_int8_t *cd_nameptr;
};
#define CD_HASBUF 0x01
#define CD_DECOMPOSED 0x02
#define CD_EOF 0x04
#define CD_ISMETA 0x40
#define CD_ISDIR 0x80
struct cat_attr {
cnid_t ca_fileid;
mode_t ca_mode;
u_int16_t ca_recflags;
u_int32_t ca_linkcount;
uid_t ca_uid;
gid_t ca_gid;
union {
dev_t cau_rdev;
u_int32_t cau_linkref;
} ca_union1;
time_t ca_atime;
time_t ca_atimeondisk;
time_t ca_mtime;
time_t ca_ctime;
time_t ca_itime;
time_t ca_btime;
u_int32_t ca_flags;
union {
u_int32_t cau_blocks;
u_int32_t cau_entries;
} ca_union2;
union {
u_int32_t cau_dircount;
u_int32_t cau_firstlink;
} ca_union3;
union {
u_int8_t ca_finderinfo[32];
struct {
FndrFileInfo ca_finderfileinfo;
struct FndrExtendedFileInfo ca_finderextendedfileinfo;
};
struct {
FndrDirInfo ca_finderdirinfo;
struct FndrExtendedDirInfo ca_finderextendeddirinfo;
};
};
};
#define ca_rdev ca_union1.cau_rdev
#define ca_linkref ca_union1.cau_linkref
#define ca_blocks ca_union2.cau_blocks
#define ca_entries ca_union2.cau_entries
#define ca_dircount ca_union3.cau_dircount
#define ca_firstlink ca_union3.cau_firstlink
#define ca_bsdflags ca_flags
struct cat_fork {
off_t cf_size;
off_t cf_new_size;
union {
u_int32_t cfu_clump;
u_int64_t cfu_bytesread;
} cf_union;
u_int32_t cf_vblocks;
u_int32_t cf_blocks;
struct HFSPlusExtentDescriptor cf_extents[8];
};
#define cf_clump cf_union.cfu_clump
#define cf_bytesread cf_union.cfu_bytesread
#define HFS_MAXDIRHINTS 32
#define HFS_DIRHINT_TTL 45
#define HFS_INDEX_MASK 0x03ffffff
#define HFS_INDEX_BITS 26
enum {
kHFSAliasType = 0x66647270,
kHFSAliasCreator = 0x4D414353
};
struct directoryhint {
TAILQ_ENTRY(directoryhint) dh_link;
int dh_index;
u_int32_t dh_threadhint;
u_int32_t dh_time;
struct cat_desc dh_desc;
};
typedef struct directoryhint directoryhint_t;
typedef struct cat_cookie_t {
#if defined(__LP64__)
char opaque[40];
#else
char opaque[24];
#endif
} cat_cookie_t;
union CatalogKey {
HFSPlusCatalogKey hfsPlus;
};
typedef union CatalogKey CatalogKey;
union CatalogRecord {
int16_t recordType;
HFSPlusCatalogFolder hfsPlusFolder;
HFSPlusCatalogFile hfsPlusFile;
HFSPlusCatalogThread hfsPlusThread;
};
typedef union CatalogRecord CatalogRecord;
struct cat_entry {
struct cat_desc ce_desc;
struct cat_attr ce_attr;
off_t ce_datasize;
off_t ce_rsrcsize;
u_int32_t ce_datablks;
u_int32_t ce_rsrcblks;
};
struct cat_entrylist {
u_int32_t maxentries;
u_int32_t realentries;
u_int32_t skipentries;
struct cat_entry entry[1];
};
#define CE_LIST_SIZE(entries) \
sizeof (*ce_list) + (((entries) - 1) * sizeof (struct cat_entry))
typedef struct cat_preflightid {
cnid_t fileid;
LIST_ENTRY(cat_preflightid) id_hash;
} cat_preflightid_t;
void hfs_idhash_init (struct hfsmount *hfsmp);
void hfs_idhash_destroy (struct hfsmount *hfsmp);
int cat_binarykeycompare( HFSPlusCatalogKey *searchKey, HFSPlusCatalogKey *trialKey );
int CompareExtendedCatalogKeys( HFSPlusCatalogKey *searchKey, HFSPlusCatalogKey *trialKey );
void cat_releasedesc( struct cat_desc *descp );
int cat_lookup(struct hfsmount *hfsmp, struct cat_desc *descp, int wantrsrc,
struct cat_desc *outdescp, struct cat_attr *attrp,
struct cat_fork *forkp, cnid_t *desc_cnid);
int cat_idlookup(struct hfsmount *hfsmp, cnid_t cnid, int allow_system_files, int wantrsrc,
struct cat_desc *outdescp, struct cat_attr *attrp, struct cat_fork *forkp);
int cat_lookupmangled(struct hfsmount *hfsmp, struct cat_desc *descp, int wantrsrc,
struct cat_desc *outdescp, struct cat_attr *attrp, struct cat_fork *forkp);
int cat_findname(struct hfsmount *hfsmp, cnid_t cnid, struct cat_desc *outdescp);
int cat_getdirentries(struct hfsmount *hfsmp, u_int32_t entrycnt, directoryhint_t *dirhint,
ReadDirBuff_s* psReadDirBuffer, int flags, int *items, bool *eofflag, UVFSDirEntry* psDotDotEntry);
int cat_getentriesattr(struct hfsmount *hfsmp, directoryhint_t *dirhint, struct cat_entrylist *ce_list,
int *reachedeof);
bool IsEntryAJnlFile(struct hfsmount *hfsmp, cnid_t cnid);
int cat_preflight(struct hfsmount *hfsmp, uint32_t ops, cat_cookie_t *cookie);
void cat_postflight(struct hfsmount *hfsmp, cat_cookie_t *cookie);
int cat_rename ( struct hfsmount * hfsmp, struct cat_desc * from_cdp, struct cat_desc * todir_cdp,
struct cat_desc * to_cdp, struct cat_desc * out_cdp );
int cat_delete(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attrp);
int cat_update(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attrp,
const struct cat_fork *dataforkp, const struct cat_fork *rsrcforkp);
int cat_acquire_cnid (struct hfsmount *hfsmp, cnid_t *new_cnid);
int cat_create(struct hfsmount *hfsmp, cnid_t new_fileid, struct cat_desc *descp, struct cat_attr *attrp, struct cat_desc *out_descp);
int cat_set_childlinkbit(struct hfsmount *hfsmp, cnid_t cnid);
int cat_check_link_ancestry(struct hfsmount *hfsmp, cnid_t cnid, cnid_t pointed_at_cnid);
#define HFS_IGNORABLE_LINK 0x00000001
int cat_deletelink(struct hfsmount *hfsmp, struct cat_desc *descp);
int cat_update_siblinglinks(struct hfsmount *hfsmp, cnid_t linkfileid, cnid_t prevlinkid, cnid_t nextlinkid);
int cat_lookup_lastlink(struct hfsmount *hfsmp, cnid_t linkfileid, cnid_t *lastlink, struct cat_desc *cdesc);
int cat_resolvelink(struct hfsmount *hfsmp, u_int32_t linkref, int isdirlink, struct HFSPlusCatalogFile *recp);
int cat_lookuplink(struct hfsmount *hfsmp, struct cat_desc *descp, cnid_t *linkfileid, cnid_t *prevlinkid, cnid_t *nextlinkid);
void cat_convertattr(struct hfsmount *hfsmp, CatalogRecord * recp, struct cat_attr *attrp, struct cat_fork *datafp, struct cat_fork *rsrcfp);
int cat_createlink(struct hfsmount *hfsmp, struct cat_desc *descp, struct cat_attr *attrp, cnid_t nextlinkid, cnid_t *linkfileid);
#endif