}
ctx.pathname = strdup(rawname);
+ if (ctx.pathname == NULL) {
+ warn("Cannot strdup the pathname");
+ goto done;
+ }
retctx = malloc(sizeof(ctx));
if (retctx == NULL) {
warn("Cannot allocate space for device context");
#include <err.h>
#include <errno.h>
#include <zlib.h>
+#include <limits.h>
+#include <assert.h>
#include "hfsmeta.h"
#include "Data.h"
if (nread != amt) {
warnx("Tried to read %zu bytes, only read %zd", amt, nread);
}
- nwritten = gzwrite(outf, (char*)buffer, amt);
+ nwritten = gzwrite(outf, (char*)buffer, (unsigned)amt);
if (nwritten == -1) {
warn("tried to gzwrite %zu bytes", amt);
return -1;
HFSDataObject *objs = NULL, *op;
ExtentList_t *ep;
int i;
+ size_t len;
hdr.version = S32(kHFSInfoHeaderVersion);
hdr.deviceBlockSize = S32((uint32_t)vop->devp->blockSize);
}
gzwrite(outf, &hdr, sizeof(hdr));
- gzwrite(outf, objs, sizeof(HFSDataObject) * vop->count);
+ len = sizeof(HFSDataObject) * vop->count;
+ assert(len < UINT_MAX);
+ gzwrite(outf, objs, (unsigned)len);
int count = 0;
for (ep = vop->list;
off_t vBlockSize;
size_t nodeSize;
size_t bufferSize;
- int blocksPerNode;
void *nodePtr = NULL;
unsigned int nodeNum = 0;
* does mean it is less efficient than it should be.
*/
if (nodeSize < vBlockSize) {
- blocksPerNode = 1; // 1 block will hold multiple nodes
bufferSize = vBlockSize;
} else {
- blocksPerNode = nodeSize / vBlockSize;
bufferSize = nodeSize;
}
free(bandName);
bandName = NULL;
ctx->cfd = fd;
- ctx->cBandNum = bandNum;
+ assert(bandNum < INT_MAX);
+ ctx->cBandNum = (int)bandNum;
} else {
fd = ctx->cfd;
}
if (*tmp)
allzeroes = 0;
}
- for (i = gap; i >= 0; i--) {
+ for (i = (int)gap; i >= 0; i--) {
printf(" ");
if (i % 2 == 1)
printf(" ");
+++ /dev/null
-hfs_key_roll.c
-hfs_key_roll.h
BTreeControlBlockPtr btreePtr;
if (filePtr == nil) return paramErr;
-
+ if (recordLen == 0) return paramErr;
btreePtr = (BTreeControlBlockPtr) filePtr->fcbBTCBPtr;
if (btreePtr == nil) return fsBTInvalidFileErr;
if (iterator == nil) return paramErr;
struct BTreeIterator *btIterator = NULL;
FSBufferDescriptor btRecord;
OSErr err;
- u_int16_t btRecordSize;
+ u_int16_t btRecordSize = 0;
err = noErr;
if (foundHint)
{
struct BTreeIterator *btIterator = NULL;
FSBufferDescriptor btRecord;
- u_int16_t btRecordSize;
+ u_int16_t btRecordSize = 0;
int lockflags;
OSErr err;
int allowFlushTxns;
u_int32_t actualStartBlock;
u_int32_t actualNumBlocks;
- u_int32_t numExtentsPerRecord;
+ u_int32_t numExtentsPerRecord = 0;
int64_t maximumBytes;
int64_t availbytes;
int64_t peof;
#include <sys/types.h>
#include <sys/buf.h>
-#if !HFS_ALLOC_TEST
+#if HFS_ALLOC_TEST
+#define KERNEL_DEBUG_CONSTANT(x, a, b, c, d, e) do {} while (0)
+#else // !HFS_ALLOC_TEST
#include "hfs_macos_defs.h"
#include <sys/systm.h>
hfs_zone_kind_t hze_kind;
size_t hze_elem_size;
const char * hze_name;
- boolean_t hze_noencrypt;
} hfs_zone_entry_t;
typedef struct hfs_zone {
{
int std_hfs = HFSTOVCB(hfsmp)->vcbSigWord == kHFSSigWord;
HFSPlusCatalogKey * pluskey = NULL;
- u_int32_t encoding;
+ u_int32_t encoding = 0;
cnid_t cnid = 0;
int err = 0;
void * buffer;
int bufsize;
int maxlinks;
- int result;
+ int result = 0;
int index;
int have_key;
int extended;
extern int hfs_removefile_callback(struct buf *bp, void *hfsmp);
+uint32_t _hfs_max_origins = MAX_CACHED_ORIGINS_DEFAULT;
+uint32_t _hfs_max_file_origins = MAX_CACHED_FILE_ORIGINS_DEFAULT;
__inline__ int hfs_checkdeleted (struct cnode *cp) {
return ((cp->c_flag & (C_DELETED | C_NOEXISTS)) ? ENOENT : 0);
};
typedef struct linkorigin linkorigin_t;
-#define MAX_CACHED_ORIGINS 10
-#define MAX_CACHED_FILE_ORIGINS 8
+extern uint32_t _hfs_max_origins;
+extern uint32_t _hfs_max_file_origins;
+
+#define MAX_CACHED_ORIGINS_DEFAULT 10
+#define MAX_CACHED_ORIGINS (_hfs_max_origins)
+#define MAX_CACHED_FILE_ORIGINS_DEFAULT 8
+#define MAX_CACHED_FILE_ORIGINS (_hfs_max_file_origins)
/*
* The cnode is used to represent each active (or recently active)
{
cpkp->cpkp_max_pers_key_len = max_pers_key_len;
cpkp->cpkp_pers_key_len = 0;
+
+ cpx_t embedded_cpx = cpkp_cpx(cpkp);
+ /* XNU requires us to allocate the AES context separately */
+ cpx_alloc_ctx (embedded_cpx);
+
cpx_init(cpkp_cpx(cpkp), max_cached_key_len);
// Default to using offsets
*/
int cpx_gentempkeys(cpx_t *pcpx, __unused struct hfsmount *hfsmp)
{
- cpx_t cpx = cpx_alloc(CP_MAX_KEYSIZE);
+ cpx_t cpx = cpx_alloc(CP_MAX_KEYSIZE, true);
cpx_set_key_len(cpx, CP_MAX_KEYSIZE);
read_random(cpx_key(cpx), CP_MAX_KEYSIZE);
goto out;
}
- cp_key_pair_t *cpkp;
+ cp_key_pair_t *cpkp = NULL;
cprotect_t new_entry = cp_entry_alloc(NULL, 0, CP_MAX_KEYSIZE, &cpkp);
if (!new_entry) {
size += 4; // Extra for magic2
#endif
- cp_entry = hfs_malloc(size);
+ cp_entry = hfs_mallocz(size);
if (old) {
memcpy(cp_entry, old, offsetof(struct cprotect, cp_keys));
// We don't copy the key roll context
cp_entry->cp_key_roll_ctx = NULL;
#endif
- } else {
- bzero(cp_entry, offsetof(struct cprotect, cp_keys));
}
#if DEBUG
size_t entry_size = (sizeof(struct cprotect) - sizeof(cp_key_pair_t)
+ cpkp_sizex(&entry->cp_keys));
+
+ /*
+ * We are freeing the HFS cprotect, which contains the memory for 'cpx'
+ * Don't forget to release the CPX AES context
+ */
+ cpx_t embedded_cpx = cpkp_cpx(&entry->cp_keys);
+ cpx_free_ctx (embedded_cpx);
#if DEBUG
hfs_assert(entry->cp_magic1 == cp_magic1);
}
/* set up entry with information from xattr */
- cp_key_pair_t *cpkp;
+ cp_key_pair_t *cpkp = NULL;
cprotect_t entry;
if (ISSET(options, CP_GET_XATTR_BASIC_INFO)) {
}
#endif
- cp_key_pair_t *cpkp;
+ cp_key_pair_t *cpkp = NULL;
cprotect_t entry;
/*
#define HFSIOC_FORCE_ENABLE_DEFRAG _IOWR('h', 49, u_int32_t)
+/* NOTE: fsctl selector 'h' 50 is defined in XNU */
+
+
/* These fsctls are ported from apfs. */
#ifndef APFSIOC_SET_NEAR_LOW_DISK
#define APFSIOC_SET_NEAR_LOW_DISK _IOW('J', 17, u_int32_t)
#include "hfs_iokit.h"
#include "hfs.h"
#include "hfs_dbg.h"
+#include "hfs_cnode.h"
#ifndef panic_on_assert
bool panic_on_assert;
hfs_sysctl_register();
+ uint32_t num_cpus;
+ size_t sz = sizeof(num_cpus);
+
+ if (sysctlbyname("hw.physicalcpu", &num_cpus, &sz, NULL, 0) == 0) {
+ if ((2 * num_cpus) > MAX_CACHED_ORIGINS_DEFAULT) {
+ _hfs_max_origins = 2 * num_cpus;
+ _hfs_max_file_origins = 2 * num_cpus;
+ } else if ((2 * num_cpus) > MAX_CACHED_FILE_ORIGINS_DEFAULT) {
+ _hfs_max_file_origins = 2 * num_cpus;
+ }
+ }
+
return true;
}
* corresponding write to the btree.
*/
task_update_logical_writes(current_task(), (2 * bsize), TASK_WRITE_METADATA, vp);
+ /*
+ * Update the physical writes counter for metadata writes.
+ * We use (2 * bsize) to account for the write to the on-disk journal
+ * followed by write to actual location later.
+ */
+ task_update_physical_writes(current_task(), TASK_PHYSICAL_WRITE_METADATA,
+ (2 * bsize),
+ TASK_BALANCE_CREDIT);
if (func) {
void (*old_func)(buf_t, void *)=NULL, *old_arg=NULL;
lock_oldstart(jnl);
/*
- * Because old_start is locked above, we can cast away the volatile qualifier before passing it to memcpy.
+ * Because old_start is locked above, we can cast away the volatile qualifier before passing it to memmove.
* slide everyone else down and put our latest guy in the last
* entry in the old_start array
*/
- memcpy(__CAST_AWAY_QUALIFIER(&jnl->old_start[0], volatile, void *), __CAST_AWAY_QUALIFIER(&jnl->old_start[1], volatile, void *), sizeof(jnl->old_start)-sizeof(jnl->old_start[0]));
+ memmove(__CAST_AWAY_QUALIFIER(&jnl->old_start[0], volatile, void *), __CAST_AWAY_QUALIFIER(&jnl->old_start[1], volatile, void *), sizeof(jnl->old_start)-sizeof(jnl->old_start[0]));
jnl->old_start[sizeof(jnl->old_start)/sizeof(jnl->old_start[0]) - 1] = tr->journal_start | 0x8000000000000000LL;
unlock_oldstart(jnl);
off_t filebytes;
off_t offset;
ssize_t resid;
- int eflags;
+ int eflags = 0;
int ioflag = ap->a_ioflag;
int retval = 0;
int lockflags;
{
struct vnode *file_vp;
cnid_t cnid;
- int outlen;
- char *bufptr;
int error;
int flags = 0;
+ char *bufptr;
+#ifdef VN_GETPATH_NEW
+ size_t outlen;
+#else // VN_GETPATH_NEW
+ int outlen;
+#endif // VN_GETPATH_NEW
/* Caller must be owner of file system. */
vfsp = vfs_statfs(HFSTOVFS(hfsmp));
/* We need to call hfs_vfs_vget to leverage the code that will
* fix the origin list for us if needed, as opposed to calling
- * hfs_vget, since we will need the parent for build_path call.
+ * hfs_vget, since we will need the parent for vn_getpath_ext call.
*/
if ((error = hfs_vfs_vget(HFSTOVFS(hfsmp), cnid, &file_vp, context))) {
return (error);
}
- error = build_path(file_vp, bufptr, sizeof(pathname_t), &outlen, flags, context);
+ outlen = sizeof(pathname_t);
+ error = vn_getpath_ext(file_vp, NULLVP, bufptr, &outlen, flags);
vnode_put(file_vp);
return (error);
u_int32_t growsize;
u_int32_t nextallocsave;
daddr64_t sector_a, sector_b;
- int eflags;
+ int eflags = 0;
off_t newbytes;
int retval;
int lockflags = 0;
static int hfs_flushMDB(struct hfsmount *hfsmp, int waitfor, int altflush);
#endif
-/* not static so we can re-use in hfs_readwrite.c for build_path calls */
+/* not static so we can re-use in hfs_readwrite.c for vn_getpath_ext calls */
int hfs_vfs_vget(struct mount *mp, ino64_t ino, struct vnode **vpp, vfs_context_t context);
static int hfs_changefs(struct mount *mp, struct hfs_mount_args *args);
goto error_exit;
}
+ if (phys_blksize < log_blksize) {
+ /*
+ * In the off chance that the phys_blksize is SMALLER than the logical
+ * then don't let that happen. Pretend that the PHYSICALBLOCKSIZE
+ * ioctl was not supported.
+ */
+ phys_blksize = log_blksize;
+ }
+
+
/* Switch to 512 byte sectors (temporarily) */
if (log_blksize > 512) {
u_int32_t size512 = 512;
goto error_exit;
}
}
+
/*
* At this point:
* minblksize is the minimum physical block size
*/
mdb_offset = (daddr64_t)HFS_PRI_SECTOR(log_blksize);
+
if ((retval = (int)buf_meta_bread(devvp,
HFS_PHYSBLK_ROUNDDOWN(mdb_offset, (phys_blksize/log_blksize)),
phys_blksize, cred, &bp))) {
/*
* hfs_vfs_vget is not static since it is used in hfs_readwrite.c to support
- * the build_path ioctl. We use it to leverage the code below that updates
+ * the vn_getpath_ext. We use it to leverage the code below that updates
* the origin list cache if necessary
*/
}
#endif
+ /*
+ * Some of these attributes can be expensive to query if we're
+ * backed by a disk image; hfs_freeblks() has to ask the backing
+ * store, and this might involve a trip to a network file server.
+ * Only ask for them if the caller really wants them. Preserve old
+ * behavior for file systems not backed by a disk image.
+ */
+#if HFS_SPARSE_DEV
+ const int diskimage = (hfsmp->hfs_backingvp != NULL);
+#else
+ const int diskimage = 0;
+#endif
+
VFSATTR_RETURN(fsap, f_objcount, (u_int64_t)hfsmp->vcbFilCnt + (u_int64_t)hfsmp->vcbDirCnt);
VFSATTR_RETURN(fsap, f_filecount, (u_int64_t)hfsmp->vcbFilCnt);
VFSATTR_RETURN(fsap, f_dircount, (u_int64_t)hfsmp->vcbDirCnt);
VFSATTR_RETURN(fsap, f_maxobjcount, (u_int64_t)0xFFFFFFFF);
VFSATTR_RETURN(fsap, f_iosize, (size_t)cluster_max_io_size(mp, 0));
VFSATTR_RETURN(fsap, f_blocks, (u_int64_t)hfsmp->totalBlocks);
- VFSATTR_RETURN(fsap, f_bfree, (u_int64_t)hfs_freeblks(hfsmp, 0));
- VFSATTR_RETURN(fsap, f_bavail, (u_int64_t)hfs_freeblks(hfsmp, 1));
+ if (VFSATTR_WANTED(fsap, f_bfree) || !diskimage) {
+ VFSATTR_RETURN(fsap, f_bfree, (u_int64_t)hfs_freeblks(hfsmp, 0));
+ }
+ if (VFSATTR_WANTED(fsap, f_bavail) || !diskimage) {
+ VFSATTR_RETURN(fsap, f_bavail, (u_int64_t)hfs_freeblks(hfsmp, 1));
+ }
VFSATTR_RETURN(fsap, f_bsize, (u_int32_t)vcb->blockSize);
/* XXX needs clarification */
- VFSATTR_RETURN(fsap, f_bused, hfsmp->totalBlocks - hfs_freeblks(hfsmp, 1));
+ if (VFSATTR_WANTED(fsap, f_bused) || !diskimage) {
+ VFSATTR_RETURN(fsap, f_bused, hfsmp->totalBlocks - hfs_freeblks(hfsmp, 1));
+ }
VFSATTR_RETURN(fsap, f_files, (u_int64_t)HFS_MAX_FILES);
VFSATTR_RETURN(fsap, f_ffree, (u_int64_t)hfs_free_cnids(hfsmp));
// -- Zone allocator-related structures and routines --
hfs_zone_entry_t hfs_zone_entries[HFS_NUM_ZONES] = {
- { HFS_CNODE_ZONE, sizeof(struct cnode), "HFS node", true },
- { HFS_FILEFORK_ZONE, sizeof(struct filefork), "HFS fork", true },
- { HFS_DIRHINT_ZONE, sizeof(struct directoryhint), "HFS dirhint", true }
+ { HFS_CNODE_ZONE, sizeof(struct cnode), "HFS node" },
+ { HFS_FILEFORK_ZONE, sizeof(struct filefork), "HFS fork" },
+ { HFS_DIRHINT_ZONE, sizeof(struct directoryhint), "HFS dirhint" }
};
hfs_zone_t hfs_zones[HFS_NUM_ZONES];
void hfs_init_zones(void) {
for (int i = 0; i < HFS_NUM_ZONES; i++) {
- hfs_zones[i].hz_zone = zinit(hfs_zone_entries[i].hze_elem_size, 1024 * 1024, PAGE_SIZE, hfs_zone_entries[i].hze_name);
- hfs_zones[i].hz_elem_size = hfs_zone_entries[i].hze_elem_size;
-
- zone_change(hfs_zones[i].hz_zone, Z_CALLERACCT, false);
- if (hfs_zone_entries[i].hze_noencrypt)
- zone_change(hfs_zones[i].hz_zone, Z_NOENCRYPT, true);
+ hfs_zones[i].hz_zone = zone_create(hfs_zone_entries[i].hze_name,
+ hfs_zone_entries[i].hze_elem_size, ZC_NOENCRYPT);
}
}
tdcp = VTOC(tdvp);
tcp = tvp ? VTOC(tvp) : NULL;
-
- /*
- * If caller requested an exclusive rename (VFS_RENAME_EXCL) and 'tcp' exists
- * then we must fail the operation.
- */
- if (tcp && rename_exclusive) {
- error = EEXIST;
- goto out;
- }
-
//
// if the item is tracked but doesn't have a document_id, assign one and generate an fsevent for it
//
struct FndrExtendedDirInfo *tfip = (struct FndrExtendedDirInfo *)((char *)&tcp->c_attr.ca_finderinfo + 16);
if (ffip->document_id && tfip->document_id) {
- // both documents are tracked. only save a tombstone from tcp and do nothing else.
- doc_tombstone_save(tdvp, tvp, tcnp, hfs_get_document_id(tcp),
- tcp->c_fileid);
+ // Both documents are tracked. `tvp` is deleted and `fvp` is
+ // renamed on top of it. Send FSE_DOCID_CHANGED for both inodes,
+ // clear tombstone of `old_doc_vp` and save tombstone of `fvp`.
+ add_fsevent(FSE_DOCID_CHANGED, vfs_context_current(),
+ FSE_ARG_DEV, hfsmp->hfs_raw_dev,
+ FSE_ARG_INO, (ino64_t)tcp->c_fileid, // src inode #
+ FSE_ARG_INO, (ino64_t)0ULL, // dst inode #
+ FSE_ARG_INT32, (uint32_t)tfip->document_id,
+ FSE_ARG_DONE);
+ add_fsevent(FSE_DOCID_CHANGED, vfs_context_current(),
+ FSE_ARG_DEV, hfsmp->hfs_raw_dev,
+ FSE_ARG_INO, (ino64_t)fcp->c_fileid, // src inode #
+ FSE_ARG_INO, (ino64_t)tcp->c_fileid, // dst inode #
+ FSE_ARG_INT32, (uint32_t)ffip->document_id,
+ FSE_ARG_DONE);
+ doc_tombstone_clear(doc_tombstone_get(), &old_doc_vp);
+ doc_tombstone_save(tdvp, fvp, tcnp, hfs_get_document_id(fcp),
+ fcp->c_fileid);
} else {
struct doc_tombstone *ut;
ut = doc_tombstone_get();
/*
* When fvp matches tvp they could be case variants
* or matching hard links.
+ * If the caller requested an exclusive rename (VFS_RENAME_EXCL),
+ * we allow rename when the target already exists when the following
+ * conditions are met:
+ * 1. the volume is case insensitive
+ * 2. source and target directories are the same
+ * 3. source and target files are the same
+ * 4. name only differs in case
*/
if (fvp == tvp) {
- if (!(fcp->c_flag & C_HARDLINK)) {
+ if (!rename_exclusive && !(fcp->c_flag & C_HARDLINK)) {
/*
* If they're not hardlinks, then fvp == tvp must mean we
* are using case-insensitive HFS because case-sensitive would
* op was dir1/fred -> dir1/bob
* That would fail/do nothing.
*/
+
goto skip_rm; /* case-variant hardlink in the same dir */
- } else {
+ } else if (rename_exclusive) {
+ error = EEXIST;
+ goto out;
+ } else {
goto out; /* matching hardlink, nothing to do */
}
}
if (__builtin_expect(kdebug_enable & KDEBUG_TRACE, 0)) {
long dbg_parms[NUMPARMS];
- int dbg_namelen;
+ int err;
+#ifdef VN_GETPATH_NEW
+ size_t dbg_namelen;
+#else // VN_GETPATH_NEW
+ int dbg_namelen;
+#endif // VN_GETPATH_NEW
dbg_namelen = NUMPARMS * sizeof(long);
- vn_getpath(vp, (char *)dbg_parms, &dbg_namelen);
+ err = vn_getpath_ext(vp, NULLVP, (char *)dbg_parms, &dbg_namelen, 0);
- if (dbg_namelen < (int)sizeof(dbg_parms))
+ if (!err && (dbg_namelen < (int)sizeof(dbg_parms)))
memset((char *)dbg_parms + dbg_namelen, 0, sizeof(dbg_parms) - dbg_namelen);
kdebug_lookup_gen_events(dbg_parms, dbg_namelen, (void *)vp, TRUE);
/*
- * Copyright (c) 2004-2017 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2020 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
/* If it won't fit inline then use extent-based attributes. */
if (attrsize > hfsmp->hfs_max_inline_attrsize) {
+#if (TARGET_OS_OSX && TARGET_CPU_ARM64)
+ printf("hfs_setxattr: non-inline attributes are not supported\n");
+ //NOTE: ENOTSUP will fool XNU into thinking we need AppleDouble files...
+ result = EPERM;
+ goto exit;
+#else
int blkcnt;
int extentblks;
u_int32_t *keystartblk;
extentblks = count_extent_blocks(blkcnt, recp->overflowExtents.extents);
blkcnt -= extentblks;
}
+#endif //(TARGET_OS_OSX && TARGET_CPU_ARM64)
} else { /* Inline data */
if (exists) {
result = remove_attribute_records(hfsmp, iterator);
/*
* Write an extent based attribute.
*/
-static int
+__unused static int
write_attr_data(struct hfsmount *hfsmp, uio_t uio, size_t datasize, HFSPlusExtentDescriptor *extents)
{
vnode_t evp = hfsmp->hfs_attrdata_vp;
/*
* Allocate blocks for an extent based attribute.
*/
-static int
+__unused static int
alloc_attr_blks(struct hfsmount *hfsmp, size_t attrsize, size_t extentbufsize, HFSPlusExtentDescriptor *extents, int *blocks)
{
int blkcnt;
}
*calcBlockSize = blockSize;
- *calcTotalBlocks = cacheSize / blockSize;
+ *calcTotalBlocks = (uint32_t)(cacheSize / blockSize);
out:
return;
//////////////////// Calc New Total Number Of Nodes /////////////////////////
- newTotalNodes = filePtr->fcbLogicalSize / nodeSize; //¥¥ hack!
+ newTotalNodes = (UInt32)(filePtr->fcbLogicalSize / nodeSize); //¥¥ hack!
//¥¥ do we wish to perform any verification of newTotalNodes at this point?
btreePtr->totalNodes = newTotalNodes; //¥¥ do we need to update freeNodes here too?
{
UInt32 mapBits;
- mapBits = M_HeaderMapRecordSize (btreePtr->nodeSize) << 3;
+ mapBits = (UInt32)(M_HeaderMapRecordSize (btreePtr->nodeSize) << 3);
while (mapBits < btreePtr->totalNodes)
mapBits += M_MapRecordSize (btreePtr->nodeSize) << 3;
flags = rec.hfsPlusFolder.flags;
li = hash_search(inodeID, slots, slotsUsed, linkInfo);
} else {
+ long ref_num;
+
inodeID = rec.hfsPlusFile.fileID;
- link_ref_num = atol((char*)&filename[prefixlen]);
+ ref_num = atol((char*)&filename[prefixlen]);
+ if (ref_num < 0 || ref_num > UINT32_MAX) {
+ result = EINVAL;
+ if (fsckGetVerbosity(gp->context) >= kDebugLog) {
+ plog ("\tLink reference num=%ld is invalid for inode=%u result=%d\n", ref_num, inodeID, result);
+ }
+ break;
+ }
+ link_ref_num = (UInt32)ref_num;
flags = rec.hfsPlusFile.flags;
li = hash_search(link_ref_num, slots, slotsUsed, linkInfo);
}
if ( filePtr->fcbFileID == kHFSRepairCatalogFileID)
flags |= kEFNoExtOvflwMask;
- result = ExtendFileC ( vcb, filePtr, (bytesToAdd+511)>>9, flags, &actualSectorsAdded );
+ result = ExtendFileC ( vcb, filePtr, (UInt32)((bytesToAdd+511)>>9), flags, &actualSectorsAdded );
ReturnIfError(result);
filePtr->fcbLogicalSize = filePtr->fcbPhysicalSize; // new B-tree looks at fcbEOF
// Zero newly allocated portion of HFS+ private file.
if ( result == noErr )
- result = ZeroFileBlocks( vcb, filePtr, fileSize - actualSectorsAdded, actualSectorsAdded );
+ result = ZeroFileBlocks( vcb, filePtr, (UInt32)(fileSize - actualSectorsAdded), actualSectorsAdded );
}
}
else if ( vcb->vcbSignature == kHFSSigWord )
MarkVCBDirty( vcb );
result = FlushAlternateVolumeControlBlock( vcb, false );
if ( result == noErr )
- result = ZeroFileBlocks( vcb, filePtr, fileSize - actualSectorsAdded, actualSectorsAdded );
+ result = ZeroFileBlocks( vcb, filePtr, (UInt32)(fileSize - actualSectorsAdded), actualSectorsAdded );
}
else if ( filePtr->fcbFileID == kHFSCatalogFileID || filePtr->fcbFileID == kHFSRepairCatalogFileID )
{
MarkVCBDirty( vcb );
result = FlushAlternateVolumeControlBlock( vcb, false );
if ( result == noErr )
- result = ZeroFileBlocks( vcb, filePtr, fileSize - actualSectorsAdded, actualSectorsAdded );
+ result = ZeroFileBlocks( vcb, filePtr, (UInt32)(fileSize - actualSectorsAdded), actualSectorsAdded );
}
}
return (5);
}
- *actBytes = nbytes;
+ *actBytes = (UInt32)nbytes;
return (0);
#else
return (5);
}
- *actBytes = nbytes;
+ *actBytes = (UInt32)nbytes;
return (0);
#else
OSErr err;
if (temp > numberOfBytes)
*availableBytes = numberOfBytes; // more there than they asked for, so pin the output
else
- *availableBytes = temp;
+ *availableBytes = (UInt32)temp;
// LogEndTime(kTraceMapFileBlock, noErr);
//
// Determine the physical EOF in allocation blocks
//
- eofBlocks = fcb->fcbPhysicalSize / vcb->vcbBlockSize;
+ eofBlocks = (UInt32)(fcb->fcbPhysicalSize / vcb->vcbBlockSize);
//
// Make sure the request won't make the file too big (>=2GB).
UInt32 filePositionBlock;
Boolean noMoreExtents = true;
- filePositionBlock = sectorOffset / (vcb->vcbBlockSize >> kSectorShift);
+ filePositionBlock = (UInt32)(sectorOffset / (vcb->vcbBlockSize >> kSectorShift));
// Search the resident FCB first.
err = GetFCBExtentRecord(vcb, fcb, foundExtentData);
UInt32 index;
UInt32 offsetBlocks;
- offsetBlocks = sectorOffset / (vcb->vcbBlockSize >> kSectorShift);
+ offsetBlocks = (UInt32)(sectorOffset / (vcb->vcbBlockSize >> kSectorShift));
if (vcb->vcbSignature == kHFSSigWord) {
const HFSExtentDescriptor *extent;
SFCB * myFCBPtr, * oldFCBPtr;
UInt32 myBytesUsed = 0;
UInt32 myMapNodeCount;
- UInt64 myNumBlocks;
+ UInt32 myNumBlocks;
FSSize myNewEOF;
BTHeaderRec myHeaderRec;
myErr = BlockFindAll( myBTreeCBPtr->fcbPtr, myNumBlocks);
ReturnIfError( myErr );
myBTreeCBPtr->fcbPtr->fcbPhysicalSize = myNewEOF;
- myErr = ZeroFileBlocks( myVCBPtr, myBTreeCBPtr->fcbPtr, 0, myNewEOF >> kSectorShift );
+ myErr = ZeroFileBlocks( myVCBPtr, myBTreeCBPtr->fcbPtr, 0, (UInt32)(myNewEOF >> kSectorShift) );
ReturnIfError( myErr );
/* now set real values in our BTree Control Block */
else if (FileID == kHFSExtentsFileID)
myFCBPtr->fcbClumpSize = myVCBPtr->vcbExtentsFile->fcbClumpSize;
- myBTreeCBPtr->totalNodes = ( myFCBPtr->fcbPhysicalSize / myBTreeCBPtr->nodeSize );
+ myBTreeCBPtr->totalNodes = (UInt32)( myFCBPtr->fcbPhysicalSize / myBTreeCBPtr->nodeSize );
myBTreeCBPtr->freeNodes = myBTreeCBPtr->totalNodes;
// Initialize our new BTree (write out header node and an empty leaf node)
(void)snprintf((char*)&attrRec->attrData[0],
sizeof(attrdata) - offsetof(HFSPlusAttrData, attrData),
"%lu", (unsigned long)(p->correct));
- attrRec->attrSize = 1 + strlen((char*)&attrRec->attrData[0]);
+ attrRec->attrSize = (u_int32_t)(1 + strlen((char*)&attrRec->attrData[0]));
bt_data.bufferAddress = attrRec;
recsize = sizeof(HFSPlusAttrData) - 2 + attrRec->attrSize + ((attrRec->attrSize & 1) ? 1 : 0);
bt_data.itemSize = recsize;
if (rec.recordType != kHFSPlusFileRecord) {
retval = IntError(GPtr, R_IntErr);
} else {
- rec.hfsPlusFile.createDate = p->correct;
+ rec.hfsPlusFile.createDate = (u_int32_t)p->correct;
retval = ReplaceBTreeRecord(GPtr->calculatedCatalogFCB, &key, kNoHint, &rec, recsize, &hint);
}
}
}
#endif
- record.hfsPlusFolder.folderCount = p->correct;
+ record.hfsPlusFolder.folderCount = (u_int32_t)p->correct;
result = ReplaceBTreeRecord( GPtr->calculatedCatalogFCB, &foundKey, hint,
&record, recSize, &hint);
if (result) {
Boolean didRepair;
fileID = p->parid;
- badExtentIndex = p->correct;
+ badExtentIndex = (UInt32)p->correct;
extentStartBlock = p->hint;
forkType = p->forkType;
int cmpLongs ( const void *a, const void *b )
{
- return( *(long*)a - *(long*)b );
+ return (int)( *(long*)a - *(long*)b );
}
/* Function: FixOverlappingExtents
break;
};
filename[len] = '\0';
- *filenamelen = strlen (filename);
+ *filenamelen = (unsigned int)strlen (filename);
}
return err;
}
}
/* Do not NULL terminate the string */
- curPtr->namelen = namelen;
+ curPtr->namelen = (unsigned int)namelen;
curPtr->name = malloc(namelen);
if (!curPtr->name) {
err = memFullErr;
// no way to find the original name and this should make it unique within our
// lost+found directory.
sprintf( myString, "%ld", (long)theObjID );
- nameLen = strlen( myString );
+ nameLen = (int)strlen( myString );
if ( isHFSPlus )
{
isHFSPlus = VolumeObjectIsHFSPlus( );
fcbPtr = GPtr->calculatedCatalogFCB;
- nameLen = strlen( (char *)dirName );
+ nameLen = (int)strlen( (char *)dirName );
if ( isHFSPlus )
{
(void) gettimeofday(&time, &zone);
- return time.tv_sec + MAC_GMT_FACTOR;
+ // Value will be bigger than UIN32_MAX in 2040
+ return (UInt32)(time.tv_sec + MAC_GMT_FACTOR);
}
/*
if (*tmp)
allzeroes = 0;
}
- for (i = gap; i >= 0; i--) {
+ for (i = (int)gap; i >= 0; i--) {
fprintf(stderr, " ");
if (i % 2 == 1)
fprintf(stderr, " ");
fcb = vcb->vcbExtentsFile;
CopyMemory( fcb->fcbExtents32, volumeHeader->extentsFile.extents, sizeof(HFSPlusExtentRecord) );
volumeHeader->extentsFile.logicalSize = fcb->fcbLogicalSize;
- volumeHeader->extentsFile.totalBlocks = fcb->fcbPhysicalSize / vcb->vcbBlockSize;
+ volumeHeader->extentsFile.totalBlocks = (u_int32_t)(fcb->fcbPhysicalSize / vcb->vcbBlockSize);
fcb = vcb->vcbCatalogFile;
CopyMemory( fcb->fcbExtents32, volumeHeader->catalogFile.extents, sizeof(HFSPlusExtentRecord) );
volumeHeader->catalogFile.logicalSize = fcb->fcbLogicalSize;
- volumeHeader->catalogFile.totalBlocks = fcb->fcbPhysicalSize / vcb->vcbBlockSize;
+ volumeHeader->catalogFile.totalBlocks = (u_int32_t)(fcb->fcbPhysicalSize / vcb->vcbBlockSize);
fcb = vcb->vcbAllocationFile;
CopyMemory( fcb->fcbExtents32, volumeHeader->allocationFile.extents, sizeof(HFSPlusExtentRecord) );
volumeHeader->allocationFile.logicalSize = fcb->fcbLogicalSize;
- volumeHeader->allocationFile.totalBlocks = fcb->fcbPhysicalSize / vcb->vcbBlockSize;
+ volumeHeader->allocationFile.totalBlocks = (u_int32_t)(fcb->fcbPhysicalSize / vcb->vcbBlockSize);
if (vcb->vcbAttributesFile != NULL) // Only update fields if an attributes file existed and was open
{
CopyMemory( fcb->fcbExtents32, volumeHeader->attributesFile.extents, sizeof(HFSPlusExtentRecord) );
volumeHeader->attributesFile.logicalSize = fcb->fcbLogicalSize;
volumeHeader->attributesFile.clumpSize = fcb->fcbClumpSize;
- volumeHeader->attributesFile.totalBlocks = fcb->fcbPhysicalSize / vcb->vcbBlockSize;
+ volumeHeader->attributesFile.totalBlocks = (u_int32_t)(fcb->fcbPhysicalSize / vcb->vcbBlockSize);
}
}
else
if (jibp)
memcpy(jibp, block, sizeof(JournalInfoBlock));
if (bsizep)
- *bsizep = blockSize;
+ *bsizep = (UInt32)blockSize;
result = 0;
} else {
if (debug) {
OSErr err;
HFSMasterDirectoryBlock * myMDBPtr;
HFSPlusVolumeHeader * myVHBPtr;
+ UInt64 numBlk;
UInt32 numABlks;
UInt32 minABlkSz;
UInt32 maxNumberOfAllocationBlocks;
// catch the case where the volume allocation block count is greater than
// maximum number of device allocation blocks. - bug 2916021
- numABlks = myVOPtr->totalDeviceSectors / ( myVHBPtr->blockSize / Blk_Size );
+ numABlks = (UInt32)(myVOPtr->totalDeviceSectors / ( myVHBPtr->blockSize / Blk_Size ));
if ( myVHBPtr->totalBlocks > numABlks ) {
RcdError( GPtr, E_NABlks );
err = E_NABlks;
// verify volume allocation info
// Note: i is the number of sectors per allocation block
- numABlks = totalSectors;
+ numBlk = totalSectors;
minABlkSz = Blk_Size; // init minimum ablock size
// loop while #ablocks won't fit
- for( i = 2; numABlks > maxNumberOfAllocationBlocks; i++ ) {
+ for( i = 2; numBlk > maxNumberOfAllocationBlocks; i++ ) {
minABlkSz = i * Blk_Size; // jack up minimum
- numABlks = totalSectors / i; // recompute #ablocks, assuming this size
+ numBlk = totalSectors / i; // recompute #ablocks, assuming this size
}
+ numABlks = (UInt32)numBlk;
vcb->vcbBlockSize = realAllocationBlockSize;
- numABlks = totalSectors / ( realAllocationBlockSize / Blk_Size );
+ numABlks = (UInt32)(totalSectors / ( realAllocationBlockSize / Blk_Size ));
if ( VolumeObjectIsHFSPlus( ) ) {
// HFS Plus allocation block size must be power of 2
if ( (realAllocationBlockSize < minABlkSz) ||
bitMapSizeInSectors = ( numABlks + kBitsPerSector - 1 ) / kBitsPerSector; // VBM size in blocks
//¥¥ Calculate the validaty of HFS Allocation blocks, I think realTotalBlocks == numABlks
- numABlks = (totalSectors - 3 - bitMapSizeInSectors) / (realAllocationBlockSize / Blk_Size); // actual # of alloc blks
+ numABlks = (UInt32)((totalSectors - 3 - bitMapSizeInSectors) / (realAllocationBlockSize / Blk_Size)); // actual # of alloc blks
if ( realTotalBlocks > numABlks ) {
RcdError( GPtr, E_NABlks );
btcb->lastLeafNode = header.lastLeafNode;
btcb->nodeSize = header.nodeSize;
- btcb->totalNodes = ( GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)( GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
// Make sure the header nodes size field is correct by looking at the 1st record offset
if ( (err != noErr) && (btcb->nodeSize != 1024) ) // default HFS+ Extents node size is 1024
{
btcb->nodeSize = 1024;
- btcb->totalNodes = ( GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)( GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
err = CheckNodesFirstOffset( GPtr, btcb );
btcb->lastLeafNode = header.lastLeafNode;
btcb->nodeSize = header.nodeSize;
- btcb->totalNodes = (GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)(GPtr->calculatedExtentsFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
// Make sure the header nodes size field is correct by looking at the 1st record offset
btcb->keyCompareType = header.keyCompareType;
btcb->leafRecords = header.leafRecords;
btcb->nodeSize = header.nodeSize;
- btcb->totalNodes = ( GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)( GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
btcb->attributes |=(kBTBigKeysMask + kBTVariableIndexKeysMask); // HFS+ Catalog files have large, variable-sized keys
if ( (err != noErr) && (btcb->nodeSize != 4096) ) // default HFS+ Catalog node size is 4096
{
btcb->nodeSize = 4096;
- btcb->totalNodes = ( GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)( GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
err = CheckNodesFirstOffset( GPtr, btcb );
btcb->keyCompareProc = (void *) CompareCatalogKeys;
btcb->leafRecords = header.leafRecords;
btcb->nodeSize = header.nodeSize;
- btcb->totalNodes = (GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)(GPtr->calculatedCatalogFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
btcb->treeDepth = header.treeDepth;
btcb->keyCompareProc = (void *)CompareAttributeKeys;
btcb->leafRecords = header.leafRecords;
btcb->nodeSize = header.nodeSize;
- btcb->totalNodes = ( GPtr->calculatedAttributesFCB->fcbPhysicalSize / btcb->nodeSize );
+ btcb->totalNodes = (UInt32)( GPtr->calculatedAttributesFCB->fcbPhysicalSize / btcb->nodeSize );
btcb->freeNodes = btcb->totalNodes; // start with everything free
btcb->attributes |=(kBTBigKeysMask + kBTVariableIndexKeysMask); // HFS+ Attributes files have large, variable-sized keys
* them against the on-disk bitmap.
*/
for (bit = 0; bit < gTotalBits; bit += kBitsPerSegment) {
- (void) GetSegmentBitmap(bit, &buffer, kTestingBits);
+ (void) GetSegmentBitmap((UInt32)bit, &buffer, kTestingBits);
/*
* When we cross file block boundries read a new block from disk.
retval = BTSearchRecord(gptr->calculatedAttributesFCB, &iterator, kNoHint,
&bt_data, NULL, NULL);
if (retval == 0) {
+ unsigned long link_id;
+
/* Attribute should be an inline attribute */
if (rec->recordType != kHFSPlusAttrInlineData) {
if (fsckGetVerbosity(gptr->context) >= kDebugLog) {
}
}
- *first_link_id = strtoul((char *)&rec->attrData[0], NULL, 10);
+ link_id = strtoul((char *)&rec->attrData[0], NULL, 10);
+ if (link_id > UINT32_MAX) {
+ if (fsckGetVerbosity(gptr->context) >= kDebugLog) {
+ plog ("\tfirst link ID=%lu is > UINT32_MAX for dirinode=%u\n", link_id, inode_id);
+ }
+ *first_link_id = 0;
+ retval = ENOENT;
+ goto out;
+ }
+ *first_link_id = (uint32_t)link_id;
if (*first_link_id < kHFSFirstUserCatalogNodeID) {
if (fsckGetVerbosity(gptr->context) >= kDebugLog) {
plog ("\tfirst link ID=%u is < 16 for dirinode=%u\n", *first_link_id, inode_id);
linkCount = rec->hfsPlusFolder.bsdInfo.special.linkCount;
parentid = gptr->dirlink_priv_dir_id;
} else {
+ unsigned long ref_num;
+
inode_id = rec->hfsPlusFile.fileID;
flags = rec->hfsPlusFile.flags;
linkCount = rec->hfsPlusFile.bsdInfo.special.linkCount;
parentid = gptr->filelink_priv_dir_id;
- link_ref_num = strtoul(&found_name[strlen(HFS_INODE_PREFIX)], NULL, 10);
+ ref_num = strtoul(&found_name[strlen(HFS_INODE_PREFIX)], NULL, 10);
+ if (ref_num > UINT32_MAX) {
+ if (fsckGetVerbosity(gptr->context) >= kDebugLog) {
+ plog ("\tlink reference num=%lu is > UINT32_MAX for inode=%u\n", ref_num, inode_id);
+ }
+ retval = 1;
+ goto out;
+ }
+ link_ref_num = (uint32_t)ref_num;
}
/* inode should only reside in its corresponding private directory */
uint32_t jBlkSize = 0;
if (ioctl(jfd, DKIOCGETBLOCKSIZE, &jBlkSize) == -1) {
- jBlkSize = min_fs_blksize;
+ jBlkSize = (uint32_t)min_fs_blksize;
} else {
if (jBlkSize < min_fs_blksize) {
fplog(stderr, "%s: journal block size %u < min block size %zu for %s\n", __FUNCTION__, jBlkSize, min_fs_blksize, jdev_name);
srcKey->nodeName.length*sizeof(srcKey->nodeName.unicode[0]));
if (cur_debug_level & d_dump_record) {
plog("Record %u (offset 0x%04X):\n", recordIndex, keyOffset);
- HexDump(srcKey, recordSize, FALSE);
+ HexDump(srcKey, (unsigned)recordSize, FALSE);
}
}
WriteError(fcb->fcbVolume->vcbGPtr, E_KeyLen, fcb->fcbFileID, src->blockNum);
extern int optind;
extern char *optarg;
char * lastChar;
+ long mode;
if ((progname = strrchr(*argv, '/')))
++progname;
case 'm':
modeSetting++;
- lostAndFoundMode = strtol( optarg, NULL, 8 );
- if ( lostAndFoundMode == 0 )
+ mode = strtol( optarg, NULL, 8 );
+ lostAndFoundMode = (int)mode;
+ if ( lostAndFoundMode == 0 || mode < INT_MIN || mode > INT_MAX)
{
- (void) fplog(stderr, "%s: invalid mode argument \n", progname);
+ (void) fplog(stderr, "%s: %ld is invalid mode argument\n", progname, mode);
usage();
}
break;
err(1, "fsck_hfs: fstat %s", dev);
}
- error = lseek(fswritefd, 0, SEEK_SET);
+ error = (int)lseek(fswritefd, 0, SEEK_SET);
if (error == -1)
{
err(1, "fsck_hfs: Could not seek %d for dev: %s, errorno %d", fswritefd, dev, errno);
}
}
- copy_amt = (cur_in_mem_log - in_mem_log);
+ copy_amt = (int)(cur_in_mem_log - in_mem_log);
if (copy_amt == 0) {
pthread_mutex_unlock(&mem_buf_lock);
continue;
}
}
- copy_amt = (cur_in_mem_out - in_mem_out);
+ copy_amt = (int)(cur_in_mem_out - in_mem_out);
if (copy_amt == 0) {
pthread_mutex_unlock(&mem_buf_lock);
continue;
buildPhases = (
);
dependencies = (
- FBA540011B7BF2DF00899E5B /* PBXTargetDependency */,
FBC234C41B4EC6AE0002D849 /* PBXTargetDependency */,
4DBD523F1548A499007AA736 /* PBXTargetDependency */,
4DBD52411548A49A007AA736 /* PBXTargetDependency */,
buildPhases = (
);
dependencies = (
+ A6873BA1234287A00045680B /* PBXTargetDependency */,
+ A6873B9A234280440045680B /* PBXTargetDependency */,
9430FE98211658E7009CC8AF /* PBXTargetDependency */,
);
name = hfs_livefiles;
900BDEFD1FF9246F002F7EC0 /* lf_hfs_logger.h in Headers */ = {isa = PBXBuildFile; fileRef = 900BDEFB1FF9246F002F7EC0 /* lf_hfs_logger.h */; };
900BDEFE1FF9246F002F7EC0 /* lf_hfs_logger.c in Sources */ = {isa = PBXBuildFile; fileRef = 900BDEFC1FF9246F002F7EC0 /* lf_hfs_logger.c */; };
9022D170205EC16900D9A2AE /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9022D16F205EC16900D9A2AE /* CoreFoundation.framework */; };
- 9022D171205EC18500D9A2AE /* livefiles_hfs.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 900BDED41FF919C2002F7EC0 /* livefiles_hfs.dylib */; };
9022D174205FE5FA00D9A2AE /* lf_hfs_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 9022D172205FE5FA00D9A2AE /* lf_hfs_utils.h */; };
9022D175205FE5FA00D9A2AE /* lf_hfs_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 9022D173205FE5FA00D9A2AE /* lf_hfs_utils.c */; };
9022D18120600D9E00D9A2AE /* lf_hfs_rangelist.h in Headers */ = {isa = PBXBuildFile; fileRef = 9022D17F20600D9E00D9A2AE /* lf_hfs_rangelist.h */; };
90F5EBBB2063CC3A004397B2 /* lf_hfs_btree_node_ops.c in Sources */ = {isa = PBXBuildFile; fileRef = 90F5EBBA2063CC3A004397B2 /* lf_hfs_btree_node_ops.c */; };
90F5EBBF2063CCE0004397B2 /* lf_hfs_btree_misc_ops.c in Sources */ = {isa = PBXBuildFile; fileRef = 90F5EBBD2063CCE0004397B2 /* lf_hfs_btree_misc_ops.c */; };
90F5EBC12063CE12004397B2 /* lf_hfs_btree_allocate.c in Sources */ = {isa = PBXBuildFile; fileRef = 90F5EBC02063CE12004397B2 /* lf_hfs_btree_allocate.c */; };
+ A64B3BE822E8D388009A2B10 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9022D16F205EC16900D9A2AE /* CoreFoundation.framework */; };
+ A64B3BF522E8D4D6009A2B10 /* lf_cs_logging.h in Headers */ = {isa = PBXBuildFile; fileRef = A64B3BF322E8D4D6009A2B10 /* lf_cs_logging.h */; };
+ A64B3BF722E8D4D6009A2B10 /* lf_cs_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3BF422E8D4D6009A2B10 /* lf_cs_logging.c */; };
+ A64B3BFB22E8D538009A2B10 /* lf_cs_checksum.h in Headers */ = {isa = PBXBuildFile; fileRef = A64B3BF922E8D538009A2B10 /* lf_cs_checksum.h */; };
+ A64B3BFC22E8D538009A2B10 /* lf_cs_checksum.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3BFA22E8D538009A2B10 /* lf_cs_checksum.c */; };
+ A64B3C0122E8D6A7009A2B10 /* livefiles_cs_tester.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3C0022E8D6A7009A2B10 /* livefiles_cs_tester.c */; };
+ A64B3C0622E8D71B009A2B10 /* lf_cs_vfsops.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3C0422E8D71B009A2B10 /* lf_cs_vfsops.c */; };
+ A64B3C0922E8D9D0009A2B10 /* livefiles_hfs.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 900BDED41FF919C2002F7EC0 /* livefiles_hfs.dylib */; };
+ A64B3C0A22E8D9D0009A2B10 /* livefiles_hfs.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = 900BDED41FF919C2002F7EC0 /* livefiles_hfs.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
+ A64B3C1522E91B50009A2B10 /* test-lf-cs-plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3C1322E91AF6009A2B10 /* test-lf-cs-plugin.c */; };
+ A64B3C1722EA2C4F009A2B10 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64B3C1622EA2C4E009A2B10 /* CoreFoundation.framework */; };
+ A64B3C1922EA2C5E009A2B10 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A64B3C1822EA2C5E009A2B10 /* IOKit.framework */; };
+ A6873B9B234286730045680B /* lf_cs_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3BF422E8D4D6009A2B10 /* lf_cs_logging.c */; };
+ A6873B9C234286780045680B /* lf_cs_checksum.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3BFA22E8D538009A2B10 /* lf_cs_checksum.c */; };
+ A6873B9D2342868D0045680B /* lf_cs_vfsops.c in Sources */ = {isa = PBXBuildFile; fileRef = A64B3C0422E8D71B009A2B10 /* lf_cs_vfsops.c */; };
+ A6873B9F234287200045680B /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A6873B9E234287200045680B /* IOKit.framework */; };
A6E6D74020909C72002125B0 /* test-get-volume-create-time.c in Sources */ = {isa = PBXBuildFile; fileRef = A6E6D73F20909C72002125B0 /* test-get-volume-create-time.c */; };
C1B6FA0810CC0A0A00778D48 /* hfsutil_jnl.c in Sources */ = {isa = PBXBuildFile; fileRef = C1B6FA0610CC0A0A00778D48 /* hfsutil_jnl.c */; };
C1B6FA0910CC0A0A00778D48 /* hfsutil_main.c in Sources */ = {isa = PBXBuildFile; fileRef = C1B6FA0710CC0A0A00778D48 /* hfsutil_main.c */; };
FB48E5121BB3853500523121 /* hfs_fsctl.h in Headers */ = {isa = PBXBuildFile; fileRef = FB20E10C1AE9529400CEBE7B /* hfs_fsctl.h */; settings = {ATTRIBUTES = (Private, ); }; };
FB55AE541B7C271000701D03 /* test-doc-tombstone.c in Sources */ = {isa = PBXBuildFile; fileRef = FB55AE521B7C271000701D03 /* test-doc-tombstone.c */; };
FB55AE591B7CEB0600701D03 /* test-quotas.c in Sources */ = {isa = PBXBuildFile; fileRef = FB55AE581B7CEB0600701D03 /* test-quotas.c */; };
- FB6A57E51B5554DE008AB046 /* hfs_fsctl.h in Headers */ = {isa = PBXBuildFile; fileRef = FB20E10C1AE9529400CEBE7B /* hfs_fsctl.h */; settings = {ATTRIBUTES = (Private, ); }; };
FB75A4061B4AEA20004B5A74 /* hfs_encodings.c in Sources */ = {isa = PBXBuildFile; fileRef = FB20E1051AE9529400CEBE7B /* hfs_encodings.c */; };
FB75A40B1B4AF025004B5A74 /* hfs_encodings.h in Headers */ = {isa = PBXBuildFile; fileRef = FB20E1061AE9529400CEBE7B /* hfs_encodings.h */; settings = {ATTRIBUTES = (Private, ); }; };
FB75A40E1B4AF0BE004B5A74 /* hfs_encodings_kext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FB75A40C1B4AF0BA004B5A74 /* hfs_encodings_kext.cpp */; };
remoteGlobalIDString = 4DFD94BC15373C2C0039B6BA;
remoteInfo = fsck_makestrings;
};
- 900BDEE51FF919E7002F7EC0 /* PBXContainerItemProxy */ = {
+ 9430FE97211658E7009CC8AF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 900BDED31FF919C2002F7EC0;
remoteInfo = livefiles_hfs;
};
- 9430FE97211658E7009CC8AF /* PBXContainerItemProxy */ = {
+ A64B3C0B22E8D9D0009A2B10 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 900BDED31FF919C2002F7EC0;
remoteInfo = livefiles_hfs;
};
+ A6873B99234280440045680B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A64B3BE122E8D388009A2B10;
+ remoteInfo = livefiles_cs_tester;
+ };
+ A6873BA0234287A00045680B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = A64B3B9022E8D36F009A2B10;
+ remoteInfo = livefiles_cs;
+ };
FB48E4BB1BB30CC400523121 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
remoteGlobalIDString = 4DE6C75A153504C100C11066;
remoteInfo = newfs_hfs;
};
- FBA540001B7BF2DF00899E5B /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = FB6A57DD1B55544D008AB046;
- remoteInfo = "System Framework Headers";
- };
FBA95AAE1B5045D400887E82 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
);
runOnlyForDeploymentPostprocessing = 1;
};
+ A64B3BE922E8D388009A2B10 /* CopyFiles */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = /usr/share/man/man1/;
+ dstSubfolderSpec = 0;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 1;
+ };
+ A64B3C0D22E8D9D0009A2B10 /* Embed Libraries */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ A64B3C0A22E8D9D0009A2B10 /* livefiles_hfs.dylib in Embed Libraries */,
+ );
+ name = "Embed Libraries";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
FB76B3D01B7A4BE600FA9F2B /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
9D7AAC861B44874E0001F573 /* mount_hfs.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = mount_hfs.osx.entitlements; sourceTree = "<group>"; };
9D7AAC871B44880B0001F573 /* hfs_util.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = hfs_util.osx.entitlements; sourceTree = "<group>"; };
9D9067881B44633C003D2117 /* fsck_hfs.osx.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = fsck_hfs.osx.entitlements; sourceTree = "<group>"; };
+ A601423723205BB00030E611 /* gen-custom-dmg.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "gen-custom-dmg.sh"; sourceTree = "<group>"; };
+ A601423823205D9D0030E611 /* generate-compressed-image.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "generate-compressed-image.c"; sourceTree = "<group>"; };
+ A64B3BE022E8D36F009A2B10 /* livefiles_cs.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = livefiles_cs.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+ A64B3BEE22E8D388009A2B10 /* livefiles_cs_tester */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = livefiles_cs_tester; sourceTree = BUILT_PRODUCTS_DIR; };
+ A64B3BF322E8D4D6009A2B10 /* lf_cs_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lf_cs_logging.h; sourceTree = "<group>"; };
+ A64B3BF422E8D4D6009A2B10 /* lf_cs_logging.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lf_cs_logging.c; sourceTree = "<group>"; };
+ A64B3BF922E8D538009A2B10 /* lf_cs_checksum.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lf_cs_checksum.h; sourceTree = "<group>"; };
+ A64B3BFA22E8D538009A2B10 /* lf_cs_checksum.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lf_cs_checksum.c; sourceTree = "<group>"; };
+ A64B3BFE22E8D584009A2B10 /* livefiles_cs_tester.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = livefiles_cs_tester.entitlements; sourceTree = "<group>"; };
+ A64B3C0022E8D6A7009A2B10 /* livefiles_cs_tester.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = livefiles_cs_tester.c; sourceTree = "<group>"; };
+ A64B3C0222E8D6D9009A2B10 /* lf_cs_disk_format.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lf_cs_disk_format.h; sourceTree = "<group>"; };
+ A64B3C0422E8D71B009A2B10 /* lf_cs_vfsops.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lf_cs_vfsops.c; sourceTree = "<group>"; };
+ A64B3C0822E8D741009A2B10 /* lf_cs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = lf_cs.h; sourceTree = "<group>"; };
+ A64B3C1322E91AF6009A2B10 /* test-lf-cs-plugin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "test-lf-cs-plugin.c"; sourceTree = "<group>"; };
+ A64B3C1622EA2C4E009A2B10 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/System/Library/Frameworks/CoreFoundation.framework; sourceTree = DEVELOPER_DIR; };
+ A64B3C1822EA2C5E009A2B10 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.Internal.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; };
+ A6873B9E234287200045680B /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.Internal.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; };
A6E6D73F20909C72002125B0 /* test-get-volume-create-time.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "test-get-volume-create-time.c"; sourceTree = "<group>"; };
C1B6FA0610CC0A0A00778D48 /* hfsutil_jnl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfsutil_jnl.c; sourceTree = "<group>"; };
C1B6FA0710CC0A0A00778D48 /* hfsutil_main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hfsutil_main.c; sourceTree = "<group>"; };
FB55AE521B7C271000701D03 /* test-doc-tombstone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "test-doc-tombstone.c"; sourceTree = "<group>"; };
FB55AE581B7CEB0600701D03 /* test-quotas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = "test-quotas.c"; sourceTree = "<group>"; };
FB55AE5D1B7D219700701D03 /* gen-test-plist.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "gen-test-plist.sh"; sourceTree = "<group>"; };
- FB6A57DE1B55544D008AB046 /* hfs-System.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "hfs-System.framework"; sourceTree = BUILT_PRODUCTS_DIR; };
FB75A4021B4AE765004B5A74 /* HFSEncodings.kext */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HFSEncodings.kext; sourceTree = BUILT_PRODUCTS_DIR; };
FB75A4031B4AE765004B5A74 /* HFSEncodings-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HFSEncodings-Info.plist"; sourceTree = "<group>"; };
FB75A40C1B4AF0BA004B5A74 /* hfs_encodings_kext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hfs_encodings_kext.cpp; sourceTree = "<group>"; };
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- D7B2DC81233A3F5B00F12230 /* livefiles_hfs.dylib in Frameworks */,
+ A64B3C0922E8D9D0009A2B10 /* livefiles_hfs.dylib in Frameworks */,
9022D170205EC16900D9A2AE /* CoreFoundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A64B3BB422E8D36F009A2B10 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A64B3C1722EA2C4F009A2B10 /* CoreFoundation.framework in Frameworks */,
+ A64B3C1922EA2C5E009A2B10 /* IOKit.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A64B3BE622E8D388009A2B10 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A6873B9F234287200045680B /* IOKit.framework in Frameworks */,
+ A64B3BE822E8D388009A2B10 /* CoreFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
FB20E0DC1AE950C200CEBE7B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
08FB7794FE84155DC02AAC07 /* hfs */ = {
isa = PBXGroup;
children = (
+ A64B3B8822E8D2A6009A2B10 /* livefiles_cs_plugin */,
900BDECD1FF91960002F7EC0 /* livefiles_hfs_plugin */,
4DFD953D15377C7D0039B6BA /* hfs.xcconfig */,
FDD9FA4614A1343D0043D4A9 /* CopyHFSMeta */,
path = livefiles_hfs_plugin;
sourceTree = "<group>";
};
+ A64B3B8822E8D2A6009A2B10 /* livefiles_cs_plugin */ = {
+ isa = PBXGroup;
+ children = (
+ A64B3BF322E8D4D6009A2B10 /* lf_cs_logging.h */,
+ A64B3BF422E8D4D6009A2B10 /* lf_cs_logging.c */,
+ A64B3BF922E8D538009A2B10 /* lf_cs_checksum.h */,
+ A64B3BFA22E8D538009A2B10 /* lf_cs_checksum.c */,
+ A64B3BFE22E8D584009A2B10 /* livefiles_cs_tester.entitlements */,
+ A64B3C0022E8D6A7009A2B10 /* livefiles_cs_tester.c */,
+ A64B3C0222E8D6D9009A2B10 /* lf_cs_disk_format.h */,
+ A64B3C0422E8D71B009A2B10 /* lf_cs_vfsops.c */,
+ A64B3C0822E8D741009A2B10 /* lf_cs.h */,
+ );
+ path = livefiles_cs_plugin;
+ sourceTree = "<group>";
+ };
C1B6FD2C10CC0DB200778D48 /* Products */ = {
isa = PBXGroup;
children = (
86CBF37F183186C300A64A93 /* libhfs_metadata.a */,
FB20E0E01AE950C200CEBE7B /* HFS.kext */,
FB75A4021B4AE765004B5A74 /* HFSEncodings.kext */,
- FB6A57DE1B55544D008AB046 /* hfs-System.framework */,
FBAA82451B56F24100EE6863 /* hfs_alloc_test */,
FBAA82511B56F26A00EE6863 /* hfs_extents_test */,
FBAA825D1B56F28C00EE6863 /* rangelist_test */,
FB48E5041BB3798500523121 /* Sim_Headers */,
900BDED41FF919C2002F7EC0 /* livefiles_hfs.dylib */,
900BDEDD1FF919DE002F7EC0 /* livefiles_hfs_tester */,
+ A64B3BE022E8D36F009A2B10 /* livefiles_cs.dylib */,
+ A64B3BEE22E8D388009A2B10 /* livefiles_cs_tester */,
);
name = Products;
sourceTree = "<group>";
FBD69AF81B91309C0022ECAD /* test-dateadded.c */,
09D6B7D61E317ED2003C20DC /* test_disklevel.c */,
A6E6D73F20909C72002125B0 /* test-get-volume-create-time.c */,
+ A64B3C1322E91AF6009A2B10 /* test-lf-cs-plugin.c */,
);
path = cases;
sourceTree = "<group>";
FB76B3EF1B7BE67400FA9F2B /* systemx.c */,
FB76B3F01B7BE67400FA9F2B /* systemx.h */,
FBAA826F1B56F32900EE6863 /* test-utils.h */,
+ A601423723205BB00030E611 /* gen-custom-dmg.sh */,
+ A601423823205D9D0030E611 /* generate-compressed-image.c */,
);
path = tests;
sourceTree = "<group>";
FDD9FA4014A133A50043D4A9 /* Frameworks */ = {
isa = PBXGroup;
children = (
+ A64B3C1822EA2C5E009A2B10 /* IOKit.framework */,
+ A6873B9E234287200045680B /* IOKit.framework */,
C1B6FA2210CC0AF400778D48 /* CoreFoundation.framework */,
9022D16F205EC16900D9A2AE /* CoreFoundation.framework */,
+ A64B3C1622EA2C4E009A2B10 /* CoreFoundation.framework */,
4DE6C7461535012200C11066 /* IOKit.framework */,
FDD9FA5B14A135840043D4A9 /* libz.dylib */,
4DE6C74A1535018100C11066 /* libutil.dylib */,
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A64B3BB522E8D36F009A2B10 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A64B3BF522E8D4D6009A2B10 /* lf_cs_logging.h in Headers */,
+ A64B3BFB22E8D538009A2B10 /* lf_cs_checksum.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
FB20E0DD1AE950C200CEBE7B /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
- FB6A57E41B5554D5008AB046 /* Headers */ = {
- isa = PBXHeadersBuildPhase;
- buildActionMask = 2147483647;
- files = (
- FB6A57E51B5554DE008AB046 /* hfs_fsctl.h in Headers */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
FB75A3DF1B4AE765004B5A74 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
900BDED91FF919DE002F7EC0 /* Sources */,
900BDEDA1FF919DE002F7EC0 /* Frameworks */,
900BDEDB1FF919DE002F7EC0 /* CopyFiles */,
+ A64B3C0D22E8D9D0009A2B10 /* Embed Libraries */,
);
buildRules = (
);
dependencies = (
- 900BDEE61FF919E7002F7EC0 /* PBXTargetDependency */,
+ A64B3C0C22E8D9D0009A2B10 /* PBXTargetDependency */,
);
name = livefiles_hfs_tester;
productName = livefiles_hfs_tester;
productReference = 900BDEDD1FF919DE002F7EC0 /* livefiles_hfs_tester */;
productType = "com.apple.product-type.tool";
};
+ A64B3B9022E8D36F009A2B10 /* livefiles_cs */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A64B3BDC22E8D36F009A2B10 /* Build configuration list for PBXNativeTarget "livefiles_cs" */;
+ buildPhases = (
+ A64B3B9122E8D36F009A2B10 /* Sources */,
+ A64B3BB422E8D36F009A2B10 /* Frameworks */,
+ A64B3BB522E8D36F009A2B10 /* Headers */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = livefiles_cs;
+ productName = livefiles_hfs;
+ productReference = A64B3BE022E8D36F009A2B10 /* livefiles_cs.dylib */;
+ productType = "com.apple.product-type.library.dynamic";
+ };
+ A64B3BE122E8D388009A2B10 /* livefiles_cs_tester */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = A64B3BEA22E8D388009A2B10 /* Build configuration list for PBXNativeTarget "livefiles_cs_tester" */;
+ buildPhases = (
+ A64B3BE422E8D388009A2B10 /* Sources */,
+ A64B3BE622E8D388009A2B10 /* Frameworks */,
+ A64B3BE922E8D388009A2B10 /* CopyFiles */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = livefiles_cs_tester;
+ productName = livefiles_cs_tester;
+ productReference = A64B3BEE22E8D388009A2B10 /* livefiles_cs_tester */;
+ productType = "com.apple.product-type.tool";
+ };
FB20E0DF1AE950C200CEBE7B /* kext */ = {
isa = PBXNativeTarget;
buildConfigurationList = FB20E0E61AE950C200CEBE7B /* Build configuration list for PBXNativeTarget "kext" */;
productReference = FB48E5041BB3798500523121 /* Sim_Headers */;
productType = "com.apple.product-type.tool";
};
- FB6A57DD1B55544D008AB046 /* System Framework Headers */ = {
- isa = PBXNativeTarget;
- buildConfigurationList = FB6A57E11B55544D008AB046 /* Build configuration list for PBXNativeTarget "System Framework Headers" */;
- buildPhases = (
- FB6A57E41B5554D5008AB046 /* Headers */,
- FB5695F81C0F5ED0004C52F2 /* ShellScript */,
- );
- buildRules = (
- );
- dependencies = (
- );
- name = "System Framework Headers";
- productName = test;
- productReference = FB6A57DE1B55544D008AB046 /* hfs-System.framework */;
- productType = "com.apple.product-type.bundle";
- };
FB75A3B11B4AE765004B5A74 /* encodings-kext */ = {
isa = PBXNativeTarget;
buildConfigurationList = FB75A3FF1B4AE765004B5A74 /* Build configuration list for PBXNativeTarget "encodings-kext" */;
CreatedOnToolsVersion = 10.0;
ProvisioningStyle = Automatic;
};
+ A64B3B9022E8D36F009A2B10 = {
+ ProvisioningStyle = Automatic;
+ };
+ A64B3BE122E8D388009A2B10 = {
+ ProvisioningStyle = Automatic;
+ };
DB1AAB7C20472D140036167F = {
CreatedOnToolsVersion = 9.3;
ProvisioningStyle = Automatic;
FB48E5031BB3798500523121 = {
CreatedOnToolsVersion = 7.0;
};
- FB6A57DD1B55544D008AB046 = {
- CreatedOnToolsVersion = 7.0;
- };
FB76B3D11B7A4BE600FA9F2B = {
CreatedOnToolsVersion = 7.0;
};
FBE3F7821AF67748005BB768 /* osx-root */,
FBC234B91B4D87A20002D849 /* ios-root */,
FBA95AA91B5025E700887E82 /* mk-xnu */,
- FB6A57DD1B55544D008AB046 /* System Framework Headers */,
FB48E49B1BB3070400523121 /* OSX Kernel Framework Headers */,
FBAA82441B56F24100EE6863 /* hfs_alloc_test */,
FBAA82501B56F26A00EE6863 /* hfs_extents_test */,
900BDED31FF919C2002F7EC0 /* livefiles_hfs */,
900BDEDC1FF919DE002F7EC0 /* livefiles_hfs_tester */,
9430FE92211658C1009CC8AF /* hfs_livefiles */,
+ A64B3B9022E8D36F009A2B10 /* livefiles_cs */,
+ A64B3BE122E8D388009A2B10 /* livefiles_cs_tester */,
);
};
/* End PBXProject section */
shellScript = "\"$SCRIPT_INPUT_FILE_0\" \"$SCRIPT_OUTPUT_FILE_0\"\n";
showEnvVarsInLog = 0;
};
- FB5695F81C0F5ED0004C52F2 /* ShellScript */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 8;
- files = (
- );
- inputPaths = (
- );
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 1;
- shellPath = /bin/sh;
- shellScript = "ditto \"$BUILT_PRODUCTS_DIR/$FULL_PRODUCT_NAME\" \"$DSTROOT\"/System/Library/Frameworks/System.framework\n";
- };
FB5695FC1C0F98F2004C52F2 /* Create DMG */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
);
inputPaths = (
"$(SRCROOT)/tests/gen-dmg.sh",
+ "$(SRCROOT)/tests/gen-custom-dmg.sh",
);
name = "Create DMG";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "set -e\n\nif [ $PLATFORM_NAME != macosx ] ; then\n \"$SCRIPT_INPUT_FILE_0\" \"$DERIVED_SOURCES_DIR/dmg.dat\"\nfi\ntouch \"$SCRIPT_OUTPUT_FILE_0\"\n";
+ shellScript = "set -e\n\nif [ $PLATFORM_NAME != macosx ] ; then\n \"$SCRIPT_INPUT_FILE_0\" \"$DERIVED_SOURCES_DIR/dmg.dat\"\nfi\ntouch \"$SCRIPT_OUTPUT_FILE_0\"\n\nif [ $PLATFORM_NAME != macosx ] ; then\nfor FS in JHFS+ APFS FAT32 EXFAT; do\n \"$SCRIPT_INPUT_FILE_1\" \"$FS\" \"$DERIVED_SOURCES_DIR/$FS-dmg.dat\"\n done\nfi\n\n";
showEnvVarsInLog = 0;
};
FB7C14111C2368F4004F8B2C /* ShellScript */ = {
);
runOnlyForDeploymentPostprocessing = 0;
};
+ A64B3B9122E8D36F009A2B10 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A64B3C0622E8D71B009A2B10 /* lf_cs_vfsops.c in Sources */,
+ A64B3BFC22E8D538009A2B10 /* lf_cs_checksum.c in Sources */,
+ A64B3BF722E8D4D6009A2B10 /* lf_cs_logging.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A64B3BE422E8D388009A2B10 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ A64B3C0122E8D6A7009A2B10 /* livefiles_cs_tester.c in Sources */,
+ A6873B9B234286730045680B /* lf_cs_logging.c in Sources */,
+ A6873B9D2342868D0045680B /* lf_cs_vfsops.c in Sources */,
+ A6873B9C234286780045680B /* lf_cs_checksum.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
FB20E0DB1AE950C200CEBE7B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
2A9399C11BE15F6800FB075B /* test-msync-16k.c in Sources */,
2A9399C21BE15F6800FB075B /* test-readdir.c in Sources */,
2A9399C31BE15F6800FB075B /* test-set-create-time.c in Sources */,
+ A64B3C1522E91B50009A2B10 /* test-lf-cs-plugin.c in Sources */,
2A9399C41BE15F6800FB075B /* test-set-protection-class.c in Sources */,
2A9399B81BE14AAD00FB075B /* test-scan-range-size.c in Sources */,
2A9399B61BE131A400FB075B /* test-resize.m in Sources */,
target = 4DFD94BC15373C2C0039B6BA /* fsck_makestrings */;
targetProxy = 4DBD52521548A4D4007AA736 /* PBXContainerItemProxy */;
};
- 900BDEE61FF919E7002F7EC0 /* PBXTargetDependency */ = {
+ 9430FE98211658E7009CC8AF /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 900BDED31FF919C2002F7EC0 /* livefiles_hfs */;
- targetProxy = 900BDEE51FF919E7002F7EC0 /* PBXContainerItemProxy */;
+ targetProxy = 9430FE97211658E7009CC8AF /* PBXContainerItemProxy */;
};
- 9430FE98211658E7009CC8AF /* PBXTargetDependency */ = {
+ A64B3C0C22E8D9D0009A2B10 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 900BDED31FF919C2002F7EC0 /* livefiles_hfs */;
- targetProxy = 9430FE97211658E7009CC8AF /* PBXContainerItemProxy */;
+ targetProxy = A64B3C0B22E8D9D0009A2B10 /* PBXContainerItemProxy */;
+ };
+ A6873B9A234280440045680B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A64B3BE122E8D388009A2B10 /* livefiles_cs_tester */;
+ targetProxy = A6873B99234280440045680B /* PBXContainerItemProxy */;
+ };
+ A6873BA1234287A00045680B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = A64B3B9022E8D36F009A2B10 /* livefiles_cs */;
+ targetProxy = A6873BA0234287A00045680B /* PBXContainerItemProxy */;
};
FB48E4BC1BB30CC400523121 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4DE6C75A153504C100C11066 /* newfs_hfs */;
targetProxy = FB81AFB91B83E2B8004E8F76 /* PBXContainerItemProxy */;
};
- FBA540011B7BF2DF00899E5B /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = FB6A57DD1B55544D008AB046 /* System Framework Headers */;
- targetProxy = FBA540001B7BF2DF00899E5B /* PBXContainerItemProxy */;
- };
FBA95AAF1B5045D400887E82 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = FBA95AA91B5025E700887E82 /* mk-xnu */;
};
name = Coverage;
};
- DB1AAB7D20472D140036167F /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Release;
- };
- DB1AAB7E20472D140036167F /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Debug;
- };
- DB1AAB7F20472D140036167F /* Coverage */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- CODE_SIGN_STYLE = Automatic;
- PRODUCT_NAME = "$(TARGET_NAME)";
- };
- name = Coverage;
- };
- FB20E0E71AE950C200CEBE7B /* Release */ = {
- isa = XCBuildConfiguration;
- baseConfigurationReference = FB20E1781AE968BD00CEBE7B /* kext.xcconfig */;
- buildSettings = {
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_ASSIGN_ENUM = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CODE_SIGN_IDENTITY = "-";
- COMBINE_HIDPI_IMAGES = YES;
- COPY_HEADERS_RUN_UNIFDEF = YES;
- COPY_HEADERS_UNIFDEF_FLAGS = "-UKERNEL";
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_SYMBOLS_PRIVATE_EXTERN = YES;
- GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
- GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
- GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
- GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
- GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES;
- GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
- GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
- GCC_WARN_SHADOW = YES;
- GCC_WARN_SIGN_COMPARE = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES;
- GCC_WARN_UNKNOWN_PRAGMAS = YES;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_LABEL = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INFOPLIST_FILE = "$(PROJECT_DERIVED_FILE_DIR)/kext-Info.plist";
- INSTALL_MODE_FLAG = "a+rX";
- LLVM_LTO = YES;
- MODULE_NAME = "com.apple.file-systems.hfs.kext";
- MODULE_VERSION = 1.0.0;
- PRODUCT_BUNDLE_IDENTIFIER = com.apple.filesystems.hfs.kext;
- PRODUCT_NAME = HFS;
- SDKROOT = macosx.internal;
- WARNING_CFLAGS = (
- "$(inherited)",
- "-Wno-unused-parameter",
- "-Wno-shorten-64-to-32",
- );
- WRAPPER_EXTENSION = kext;
- };
- name = Release;
- };
- FB48E4A31BB3070500523121 /* Release */ = {
+ A64B3BDD22E8D36F009A2B10 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ANALYZER_OBJC_UNUSED_IVARS = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_HEADERS_RUN_UNIFDEF = YES;
- COPY_HEADERS_UNIFDEF_FLAGS = "-DKERNEL";
- COPY_PHASE_STRIP = NO;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ DEAD_CODE_STRIPPING = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
+ EXECUTABLE_PREFIX = "";
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = "LF_CS_USE_OSLOG=1";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_FUNCTION = NO;
+ GCC_WARN_UNUSED_LABEL = NO;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ GCC_WARN_UNUSED_VALUE = NO;
GCC_WARN_UNUSED_VARIABLE = YES;
- INSTALL_PATH = /System/Library/Frameworks;
- MACOSX_DEPLOYMENT_TARGET = 10.11;
+ HEADER_SEARCH_PATHS = "livefiles_cs_plugin/**";
+ INSTALL_PATH = /System/Library/PrivateFrameworks/UserFS.framework/PlugIns;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
MTL_ENABLE_DEBUG_INFO = NO;
- PRODUCT_NAME = Kernel;
- PUBLIC_HEADERS_FOLDER_PATH = Kernel.framework/Versions/A/Headers/hfs;
- WRAPPER_EXTENSION = framework;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
};
name = Release;
};
- FB48E4A41BB3070500523121 /* Debug */ = {
+ A64B3BDE22E8D36F009A2B10 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ANALYZER_OBJC_UNUSED_IVARS = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ DEAD_CODE_STRIPPING = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ EXECUTABLE_PREFIX = "";
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "LF_CS_USE_OSLOG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = NO;
+ GCC_WARN_UNUSED_LABEL = NO;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ GCC_WARN_UNUSED_VALUE = NO;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "livefiles_cs_plugin/**";
+ INSTALL_PATH = /System/Library/PrivateFrameworks/UserFS.framework/PlugIns;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
+ };
+ name = Debug;
+ };
+ A64B3BDF22E8D36F009A2B10 /* Coverage */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_ANALYZER_OBJC_UNUSED_IVARS = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ DEAD_CODE_STRIPPING = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 1;
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ EXECUTABLE_PREFIX = "";
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_PREPROCESSOR_DEFINITIONS = "LF_CS_USE_OSLOG=1";
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = NO;
+ GCC_WARN_UNUSED_LABEL = NO;
+ GCC_WARN_UNUSED_PARAMETER = NO;
+ GCC_WARN_UNUSED_VALUE = NO;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = "livefiles_cs_plugin/**";
+ INSTALL_PATH = /System/Library/PrivateFrameworks/UserFS.framework/PlugIns;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
+ };
+ name = Coverage;
+ };
+ A64B3BEB22E8D388009A2B10 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = livefiles_cs_plugin/livefiles_cs_tester.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = livefiles_cs_plugin/;
+ INSTALL_PATH = /AppleInternal/CoreOS/tests/hfs;
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
+ };
+ name = Release;
+ };
+ A64B3BEC22E8D388009A2B10 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = livefiles_cs_plugin/livefiles_cs_tester.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = livefiles_cs_plugin/;
+ INSTALL_PATH = /AppleInternal/CoreOS/tests/hfs;
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
+ };
+ name = Debug;
+ };
+ A64B3BED22E8D388009A2B10 /* Coverage */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = NO;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_ENTITLEMENTS = livefiles_cs_plugin/livefiles_cs_tester.entitlements;
+ CODE_SIGN_IDENTITY = "-";
+ CODE_SIGN_STYLE = Automatic;
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ FRAMEWORK_SEARCH_PATHS = "$(SDKROOT)$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks";
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ HEADER_SEARCH_PATHS = livefiles_cs_plugin/;
+ INSTALL_PATH = /AppleInternal/CoreOS/tests/hfs;
+ MACOSX_DEPLOYMENT_TARGET = 10.12;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SDKROOT = macosx.internal;
+ SUPPORTS_TEXT_BASED_API = NO;
+ };
+ name = Coverage;
+ };
+ DB1AAB7D20472D140036167F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+ DB1AAB7E20472D140036167F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ DB1AAB7F20472D140036167F /* Coverage */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CODE_SIGN_STYLE = Automatic;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Coverage;
+ };
+ FB20E0E71AE950C200CEBE7B /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = FB20E1781AE968BD00CEBE7B /* kext.xcconfig */;
+ buildSettings = {
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_ASSIGN_ENUM = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_HEADERS_RUN_UNIFDEF = YES;
+ COPY_HEADERS_UNIFDEF_FLAGS = "-UKERNEL";
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_SYMBOLS_PRIVATE_EXTERN = YES;
+ GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+ GCC_TREAT_INCOMPATIBLE_POINTER_TYPE_WARNINGS_AS_ERRORS = YES;
+ GCC_WARN_ABOUT_MISSING_FIELD_INITIALIZERS = YES;
+ GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
+ GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES;
+ GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
+ GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
+ GCC_WARN_SHADOW = YES;
+ GCC_WARN_SIGN_COMPARE = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES;
+ GCC_WARN_UNKNOWN_PRAGMAS = YES;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_LABEL = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INFOPLIST_FILE = "$(PROJECT_DERIVED_FILE_DIR)/kext-Info.plist";
+ INSTALL_MODE_FLAG = "a+rX";
+ LLVM_LTO = YES;
+ MODULE_NAME = "com.apple.file-systems.hfs.kext";
+ MODULE_VERSION = 1.0.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.apple.filesystems.hfs.kext;
+ PRODUCT_NAME = HFS;
+ SDKROOT = macosx.internal;
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-unused-parameter",
+ "-Wno-shorten-64-to-32",
+ );
+ WRAPPER_EXTENSION = kext;
+ };
+ name = Release;
+ };
+ FB48E4A31BB3070500523121 /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ COMBINE_HIDPI_IMAGES = YES;
+ COPY_HEADERS_RUN_UNIFDEF = YES;
+ COPY_HEADERS_UNIFDEF_FLAGS = "-DKERNEL";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ INSTALL_PATH = /System/Library/Frameworks;
+ MACOSX_DEPLOYMENT_TARGET = 10.11;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ PRODUCT_NAME = Kernel;
+ PUBLIC_HEADERS_FOLDER_PATH = Kernel.framework/Versions/A/Headers/hfs;
+ WRAPPER_EXTENSION = framework;
+ };
+ name = Release;
+ };
+ FB48E4A41BB3070500523121 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
};
name = Debug;
};
- FB6A57E21B55544D008AB046 /* Release */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_HEADERS_RUN_UNIFDEF = YES;
- COPY_HEADERS_UNIFDEF_FLAGS = "-UKERNEL";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
- ENABLE_NS_ASSERTIONS = NO;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.11;
- MTL_ENABLE_DEBUG_INFO = NO;
- PRIVATE_HEADERS_FOLDER_PATH = "hfs-System.framework/Versions/B/PrivateHeaders/hfs";
- PRODUCT_NAME = "hfs-System";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- WRAPPER_EXTENSION = framework;
- };
- name = Release;
- };
- FB6A57E31B55544D008AB046 /* Debug */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_HEADERS_RUN_UNIFDEF = YES;
- COPY_HEADERS_UNIFDEF_FLAGS = "-UKERNEL";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.11;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- PRIVATE_HEADERS_FOLDER_PATH = "hfs-System.framework/Versions/B/PrivateHeaders/hfs";
- PRODUCT_NAME = "hfs-System";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- WRAPPER_EXTENSION = framework;
- };
- name = Debug;
- };
FB75A4001B4AE765004B5A74 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FB20E1781AE968BD00CEBE7B /* kext.xcconfig */;
};
name = Coverage;
};
- FBD69B291B94E9990022ECAD /* Coverage */ = {
- isa = XCBuildConfiguration;
- buildSettings = {
- ALWAYS_SEARCH_USER_PATHS = NO;
- CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
- CLANG_CXX_LIBRARY = "libc++";
- CLANG_ENABLE_MODULES = YES;
- CLANG_ENABLE_OBJC_ARC = YES;
- CLANG_WARN_BOOL_CONVERSION = YES;
- CLANG_WARN_CONSTANT_CONVERSION = YES;
- CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
- CLANG_WARN_EMPTY_BODY = YES;
- CLANG_WARN_ENUM_CONVERSION = YES;
- CLANG_WARN_INT_CONVERSION = YES;
- CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
- CLANG_WARN_UNREACHABLE_CODE = YES;
- CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
- COMBINE_HIDPI_IMAGES = YES;
- COPY_HEADERS_RUN_UNIFDEF = YES;
- COPY_HEADERS_UNIFDEF_FLAGS = "-UKERNEL";
- COPY_PHASE_STRIP = NO;
- DEBUG_INFORMATION_FORMAT = dwarf;
- ENABLE_STRICT_OBJC_MSGSEND = YES;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_NO_COMMON_BLOCKS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_PREPROCESSOR_DEFINITIONS = (
- "DEBUG=1",
- "$(inherited)",
- );
- GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
- GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
- GCC_WARN_UNDECLARED_SELECTOR = YES;
- GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
- GCC_WARN_UNUSED_FUNCTION = YES;
- GCC_WARN_UNUSED_VARIABLE = YES;
- MACOSX_DEPLOYMENT_TARGET = 10.11;
- MTL_ENABLE_DEBUG_INFO = YES;
- ONLY_ACTIVE_ARCH = YES;
- PRIVATE_HEADERS_FOLDER_PATH = "hfs-System.framework/Versions/B/PrivateHeaders/hfs";
- PRODUCT_NAME = "hfs-System";
- SDKROOT = macosx;
- SKIP_INSTALL = YES;
- WRAPPER_EXTENSION = framework;
- };
- name = Coverage;
- };
FBD69B2A1B94E9990022ECAD /* Coverage */ = {
isa = XCBuildConfiguration;
buildSettings = {
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ A64B3BDC22E8D36F009A2B10 /* Build configuration list for PBXNativeTarget "livefiles_cs" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A64B3BDD22E8D36F009A2B10 /* Release */,
+ A64B3BDE22E8D36F009A2B10 /* Debug */,
+ A64B3BDF22E8D36F009A2B10 /* Coverage */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ A64B3BEA22E8D388009A2B10 /* Build configuration list for PBXNativeTarget "livefiles_cs_tester" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ A64B3BEB22E8D388009A2B10 /* Release */,
+ A64B3BEC22E8D388009A2B10 /* Debug */,
+ A64B3BED22E8D388009A2B10 /* Coverage */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
DB1AAB8020472D140036167F /* Build configuration list for PBXAggregateTarget "Swift_iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- FB6A57E11B55544D008AB046 /* Build configuration list for PBXNativeTarget "System Framework Headers" */ = {
- isa = XCConfigurationList;
- buildConfigurations = (
- FB6A57E21B55544D008AB046 /* Release */,
- FB6A57E31B55544D008AB046 /* Debug */,
- FBD69B291B94E9990022ECAD /* Coverage */,
- );
- defaultConfigurationIsVisible = 0;
- defaultConfigurationName = Release;
- };
FB75A3FF1B4AE765004B5A74 /* Build configuration list for PBXNativeTarget "encodings-kext" */ = {
isa = XCConfigurationList;
buildConfigurations = (
buf = (char *)calloc(block_size, 1);
if (buf) {
for(i=0; i < journal_size/block_size; i++) {
- ret = write(fd, buf, block_size);
+ ret = (int)write(fd, buf, block_size);
if (ret != block_size) {
break;
}
free(buf);
return 20;
}
- jstart_block = (start_block / block_size) - (embedded_offset / block_size);
+ jstart_block = (int32_t)((start_block / block_size) - (embedded_offset / block_size));
memset(&jib, 'Z', sizeof(jib));
jib.flags = kJIJournalInFSMask;
free(buf);
return 20;
}
- jinfo_block = (start_block / block_size) - (embedded_offset / block_size);
+ jinfo_block = (int32_t)((start_block / block_size) - (embedded_offset / block_size));
//
disksize = (u_int64_t)mdbp->drEmbedExtent.blockCount *
(u_int64_t)mdbp->drAlBlkSiz;
- mdb_offset = (embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize);
+ mdb_offset = (daddr_t)((embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize));
if (pread(fd, buff, blksize, mdb_offset * blksize) != blksize) {
printf("failed to read the embedded vhp @ offset %d\n", mdb_offset * blksize);
ret = -1;
disksize = (u_int64_t)SWAP_BE16(mdbp->drEmbedExtent.blockCount) * (u_int64_t)SWAP_BE32(mdbp->drAlBlkSiz);
- mdb_offset = (embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize);
+ mdb_offset = (daddr_t)((embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize));
hdr_offset = mdb_offset * blksize;
if (pread(fd, buff, blksize, hdr_offset) != blksize) {
fprintf(stderr, "failed to read the embedded vhp @ offset %d\n", mdb_offset * blksize);
tmp &= ~kHFSVolumeJournaledMask;
vhp->attributes = SWAP_BE32(tmp);
- if ((tmp = pwrite(fd, buff, blksize, hdr_offset)) != blksize) {
+ if ((tmp = (unsigned int)pwrite(fd, buff, blksize, hdr_offset)) != blksize) {
fprintf(stderr, "Update of super-block on %s failed! (%d != %d, %s)\n",
devname, tmp, blksize, strerror(errno));
} else {
blksize = 512;
}
- mdb_offset = (embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize);
+ mdb_offset = (daddr_t)((embeddedOffset / blksize) + HFS_PRI_SECTOR(blksize));
if (pread(fd, buff, blksize, mdb_offset * blksize) != blksize) {
printf("failed to read the embedded vhp @ offset %d\n", mdb_offset * blksize);
ret = -1;
#include <hfs/hfs_format.h>
#include <hfs/hfs_mount.h>
#include <err.h>
+#include <assert.h>
#include <ctype.h>
#include <errno.h>
if ((fd = open(buffer, O_RDONLY, 0)) > 0) {
ssize_t readSize;
+ long encoding;
readSize = read(fd, buffer, MAXPATHLEN);
buffer[(readSize < 0 ? 0 : readSize)] = '\0';
close(fd);
- return strtol(buffer, NULL, 0);
+
+ encoding = strtol(buffer, NULL, 0);
+ assert(encoding > -1 && encoding <= UINT_MAX);
+ return (unsigned int)encoding;
}
}
return 0; // Fallback to smRoman
/*
* Read the HFS Master Directory Block from sector 2
*/
- result = readAt(fd, bufPtr, (off_t)(2 * HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
+ result = (int)readAt(fd, bufPtr, (off_t)(2 * HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
if (FSUR_IO_FAIL == result)
goto Return;
const char ** mountPointPtr, boolean_t * isEjectablePtr,
boolean_t * isLockedPtr, boolean_t * isSetuidPtr, boolean_t * isDevPtr)
{
+ size_t deviceLength;
int result = FSUR_INVAL;
- int deviceLength, doLengthCheck = 1;
+ int doLengthCheck = 1;
int index;
int mounting = 0;
doLengthCheck = 0;
if (isdigit(argv[2][0])) {
char *ptr;
- gJournalSize = strtoul(argv[2], &ptr, 0);
+ unsigned long size = strtoul(argv[2], &ptr, 0);
+
+ assert(size < INT_MAX);
+ gJournalSize = (int)size;
if (ptr) {
gJournalSize *= get_multiplier(*ptr);
}
* Read the HFS Master Directory Block or Volume Header from sector 2
*/
*startOffset = 0;
- result = readAt(fd, bufPtr, (off_t)(2 * HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
+ result = (int)readAt(fd, bufPtr, (off_t)(2 * HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
if (result != FSUR_IO_SUCCESS)
goto Err_Exit;
result = GetEmbeddedHFSPlusVol(mdbPtr, startOffset);
if (result != FSUR_IO_SUCCESS)
goto Err_Exit;
- result = readAt(fd, bufPtr, *startOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
+ result = (int)readAt(fd, bufPtr, *startOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
if (result != FSUR_IO_SUCCESS)
goto Err_Exit;
}
/*
* Write the modified MDB or VHB back to disk
*/
- result = writeAt(fd, bufPtr, startOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
+ result = (int)writeAt(fd, bufPtr, startOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE);
Err_Exit:
if (fd > 0) close(fd);
* Read the Volume Header
* (This is a little redundant for a pure, unwrapped HFS+ volume)
*/
- result = readAt( fd, volHdrPtr, hfsPlusVolumeOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE );
+ result = (int)readAt( fd, volHdrPtr, hfsPlusVolumeOffset + (off_t)(2*HFS_BLOCK_SIZE), HFS_BLOCK_SIZE );
if (result == FSUR_IO_FAIL) {
#if TRACE_HFS_UTIL
fprintf(stderr, "hfs.util: GetNameFromHFSPlusVolumeStartingAt: readAt failed\n");
u_int32_t blockCount = 0;
/* Determine allocation block containing logicalOffset */
- logicalBlock = offset / blockSize; /* This can't overflow for valid volumes */
+ logicalBlock = (u_int32_t)(offset / blockSize); /* This can't overflow for valid volumes */
offset %= blockSize; /* Offset from start of allocation block */
/* Find the extent containing logicalBlock */
if (result != FSUR_IO_SUCCESS)
break;
- result = readAt(fd, buffer, volOffset+physOffset, physLength);
+ result = (int)readAt(fd, buffer, volOffset+physOffset, physLength);
if (result != FSUR_IO_SUCCESS)
break;
* converted it then do nothing.
*/
lseek(dbstateptr->dbfile, 0, SEEK_SET);
- result = read(dbstateptr->dbfile, &entry64, sizeof(entry64));
+ result = (int)read(dbstateptr->dbfile, &entry64, sizeof(entry64));
if ((result != sizeof(entry64)) ||
(entry64.keySeparator != DBKEYSEPARATOR) ||
(entry64.space != DBBLANKSPACE) ||
result = 0;
goto ErrExit;
} else {
+ off_t buf_size = dbinfo.st_size;
+
/* Read in a giant buffer */
if ((result = stat(gVSDBPath, &dbinfo)) != 0) goto ErrExit;
- iobuffersize = dbinfo.st_size;
+ if (buf_size > UINT32_MAX) {
+ result = EINVAL;
+ goto ErrExit;
+ }
+ iobuffersize = (u_int32_t)buf_size;
iobuffer = malloc(iobuffersize);
if (iobuffer == NULL) {
result = ENOMEM;
};
lseek(dbstateptr->dbfile, 0, SEEK_SET);
- result = read(dbstateptr->dbfile, iobuffer, iobuffersize);
+ result = (int)read(dbstateptr->dbfile, iobuffer, iobuffersize);
if (result != iobuffersize) {
result = errno;
goto ErrExit;
}
ConvertHFSUUIDToUUID(entry64.key.uuid, &volumeID);
- VolumeStatus = ConvertHexStringToULong(entry64.record.statusFlags, sizeof(entry64.record.statusFlags));
+ VolumeStatus = (u_int32_t)ConvertHexStringToULong(entry64.record.statusFlags, sizeof(entry64.record.statusFlags));
FormatDBEntry(&volumeID, VolumeStatus, &dbentry);
if ((result = AddVolumeRecord(dbstateptr, &dbentry)) != sizeof(dbentry)) {
static int AddVolumeRecord(VSDBStatePtr dbstateptr, VSDBEntryUUID_t *dbentry) {
lseek(dbstateptr->dbfile, 0, SEEK_END);
- return write(dbstateptr->dbfile, dbentry, sizeof(struct VSDBEntryUUID));
+ return (int)write(dbstateptr->dbfile, dbentry, sizeof(struct VSDBEntryUUID));
}
static int UpdateVolumeRecord(VSDBStatePtr dbstateptr, VSDBEntryUUID_t *dbentry) {
lseek(dbstateptr->dbfile, dbstateptr->recordPosition, SEEK_SET);
- return write(dbstateptr->dbfile, dbentry, sizeof(*dbentry));
+ return (int)write(dbstateptr->dbfile, dbentry, sizeof(*dbentry));
}
static int GetVSDBEntry(VSDBStatePtr dbstateptr, VSDBEntryUUID_t *dbentry) {
int result;
dbstateptr->recordPosition = lseek(dbstateptr->dbfile, 0, SEEK_CUR);
- result = read(dbstateptr->dbfile, &entry, sizeof(entry));
+ result = (int)read(dbstateptr->dbfile, &entry, sizeof(entry));
if ((result != sizeof(entry)) ||
(entry.keySeparator != DBKEYSEPARATOR) ||
(entry.space != DBBLANKSPACE) ||
--- /dev/null
+//
+// Copyright (c) 2019-2019 Apple Inc. All rights reserved.
+//
+// lf_cs.h - Defines macros for livefiles Apple_CoreStorage plugin.
+//
+
+#ifndef _LF_CS_H
+#define _LF_CS_H
+
+#include <UserFS/UserVFS.h>
+
+//
+// Device/Block alignment and rounding.
+//
+#define CS_HOWMANY(_n, _b) howmany(_n, _b)
+#define CS_ALIGN(_n, _b, _up)\
+ (((_up) ? CS_HOWMANY(_n, _b) : ((_n) / (_b))) * (_b))
+
+#define CS_STATUS(_s) ((_s) & 0x000FFFFF)
+#define CS_STATUS_OK 0x00000000 // No error.
+#define CS_STATUS_NOTCS 0x00000001 // Not a current CS volume.
+#define CS_STATUS_CKSUM 0x00000002 // Cksum mismatch.
+#define CS_STATUS_BLKTYPE 0x00000004 // Incorrect block type.
+#define CS_STATUS_INVALID 0x00000008 // Invalid field value.
+#define CS_STATUS_ADDRESS 0x00000010 // Invalid laddr/vaddr.
+#define CS_STATUS_TXG 0x00000020 // Invalid transaction.
+#define CS_STATUS_UUID 0x00000040 // Inconsistent UUID.
+
+
+#define CS_INFO(_s) ((_s) & 0xFFF00000)
+#define CS_INFO_VERSIONITIS 0x00100000 // Incompatible CS volume format
+#define CS_INFO_ZERO_VH 0x02000000 // In-progress CS volume forma
+
+#endif /* _LF_CS_H */
--- /dev/null
+//
+// Copyright (c) 2009-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_checksum.h - Implements checksum handling for livefiles
+// Apple_CoreStorage plugin.
+//
+// This implementation is copied from CoreStorage project.
+//
+
+#include "lf_cs_checksum.h"
+
+//
+// CRC32-C using polynomial 0x1EDC6F41
+//
+static const uint32_t crc32_table[256] = {
+ 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4,
+ 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb,
+ 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
+ 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24,
+ 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b,
+ 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
+ 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54,
+ 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b,
+ 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
+ 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35,
+ 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5,
+ 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
+ 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45,
+ 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a,
+ 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
+ 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595,
+ 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48,
+ 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
+ 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687,
+ 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198,
+ 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
+ 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38,
+ 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8,
+ 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
+ 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096,
+ 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789,
+ 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
+ 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46,
+ 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9,
+ 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
+ 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36,
+ 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829,
+ 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
+ 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93,
+ 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043,
+ 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
+ 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3,
+ 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc,
+ 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
+ 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033,
+ 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652,
+ 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
+ 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d,
+ 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982,
+ 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
+ 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622,
+ 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2,
+ 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
+ 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530,
+ 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f,
+ 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
+ 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0,
+ 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f,
+ 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
+ 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90,
+ 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f,
+ 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
+ 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1,
+ 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321,
+ 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
+ 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81,
+ 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e,
+ 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
+ 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351
+};
+
+//
+// Initialize 'cksum' buffer for the cksum function for a given
+// algorithm 'alg'. Doubles as alg verification for probe/boot.
+//
+bool
+cksum_init(cksum_alg_t alg, uint8_t cksum[MAX_CKSUM_NBYTES])
+{
+ switch (alg) {
+
+ case CKSUM_NONE:
+ memset(cksum, 0, MAX_CKSUM_NBYTES);
+ break;
+
+ case CKSUM_ALG_CRC_32:
+ memset(cksum, ~0, MAX_CKSUM_NBYTES);
+ break;
+
+ default:
+ return false;
+
+ }
+
+ return true;
+}
+
+//
+// cksum - Apply passed checksum algorithm.
+//
+// Apply checksum algorithm 'alg' to data block 'p' for 'len' bytes and insert
+// the result (to max MAX_CKSUM_NBYTES) into 'cksum'. To support incremental
+// cksum calculation the caller is responsible for first initialising the
+// 'cksum' buffer (using cksum_init).
+//
+void
+cksum(cksum_alg_t alg, const void *p, size_t len,
+ uint8_t cksum[MAX_CKSUM_NBYTES])
+{
+ const uint8_t *data = (const uint8_t *)p;
+ uint32_t c32;
+
+ switch (alg) {
+
+ case CKSUM_NONE:
+ break;
+
+ case CKSUM_ALG_CRC_32:
+
+ c32 = *(uint32_t *)cksum;
+
+ while (len-- > 0) {
+ c32 = crc32_table[(c32 ^ *data++) & 0xff] ^
+ (c32 >> 8);
+ }
+
+ *(uint32_t *)cksum = c32;
+ break;
+ }
+}
--- /dev/null
+//
+// Copyright (c) 2009-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_checksum.h - Defines for checksum handling for livefiles
+// Apple_CoreStorage plugin.
+//
+// This header is copied from CoreStorage project.
+//
+
+#ifndef _LF_CS_CHECKSUM_H
+#define _LF_CS_CHECKSUM_H
+
+#include <stdint.h>
+#include <string.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+//
+// Checksum Algorithm
+//
+// Every metadata block has a checksum to check the data integrity. Different
+// checksum algorithms can be used by CoreStorage, and [[lvg_checksum_alg]] in
+// [[lvg_info_t]] records what checksum algorithm to use. For the first
+// prototype, I am copying the CRC algorithm from the UDF project.
+//
+// The fletcher 2 algorithm used by ZFS has fundamental flaws. And a variation
+// of the fletcher 8 algorithm could be used, which is 2 times faster than
+// CRC32 and 4 times faster than fletcher.
+//
+// <cksum definitions>=
+//
+#define MAX_CKSUM_NBYTES 8
+
+enum cksum_alg {
+ CKSUM_NONE,
+ CKSUM_ALG_CRC_32, // CRC-32 algorithm copied from CRC32-C polynomial
+};
+typedef enum cksum_alg cksum_alg_t;
+
+
+#define BITS_PER_BYTE 8L
+#define META_CKSUM_BITS (MAX_CKSUM_NBYTES * BITS_PER_BYTE)
+
+//
+// Initialize checksum for a certain algorithm
+//
+bool cksum_init(cksum_alg_t alg, uint8_t cksum[MAX_CKSUM_NBYTES]);
+
+//
+// cksum - Calculate checksum of data for len bytes
+//
+// Existing value of cksum is also used to calculate the checksum. In order to
+// calculate cksums of different memory chunks, this function can be called
+// several times:
+//
+// cksum(alg, data1, len1, cksum);
+// cksum(alg, data2, len2, cksum);
+//
+// and the resultant cksum is calculated on two chunks
+//
+void cksum(cksum_alg_t alg, const void *data, size_t len,
+ uint8_t cksum[MAX_CKSUM_NBYTES]);
+
+#endif /* _LF_CS_CHECKSUM_H */
--- /dev/null
+//
+// Copyright (c) 2009-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_disk_format.h - Defines on disk format for Apple_CoreStorage physical
+// volumes for livefiles Apple_CoreStorage plugin.
+//
+// This header is copied from CoreStorage project.
+//
+
+#ifndef _LF_CS_DISK_FORMAT_H
+#define _LF_CS_DISK_FORMAT_H
+
+#define MAX_CKSUM_NBYTES 8
+#define CORESTORAGE_FORMAT_VERSION 1
+
+//
+// The 'dl_lvg.lvg_signature' in a DiskLabel (mimics 'CORESTOR')
+//
+#define CORE_STORAGE_SIGNATURE 0xC07E5707
+
+//
+// The 'mh_endianness' used to check endianness (non-palindromic 'CS')
+//
+#define BYTE_ORDER_MARK 0x5343
+
+//
+// Metadata block header.
+//
+struct metadata_header {
+
+ //
+ // Block cksum.
+ //
+ uint8_t mh_cksum[MAX_CKSUM_NBYTES];
+
+ //
+ // The on-disk format version of CoreStorage.
+ //
+ uint16_t mh_format_version;
+
+ //
+ // Enum metadata_blk_type (BLK_TYPE_*).
+ //
+ uint8_t mh_blk_type;
+
+ //
+ // Enum metadata_blk_subtype (BLK_SUBTYPE_*), for b-tree/fsck.
+ //
+ uint8_t mh_blk_subtype;
+
+ //
+ // The version of CoreStorage software that wrote this block.
+ //
+ uint32_t mh_bundle_version;
+
+ //
+ // Transaction identification.
+ //
+ uint64_t mh_txg_id;
+ uint64_t mh_vaddr;
+ uint64_t mh_laddr;
+
+ //
+ // Records the owner of the block. The owner of any blocks in a B-Tree
+ // is the root of the tree. The owner of any blocks in a list like
+ // structure (DSD list, attribute blocks) is the first block in the
+ // list. This field can be used for crash recovery by fsck_cs. For
+ // example, if this field has the B-Tree root vaddr that this block
+ // belongs, fsck_cs could reconstruct the B-Tree based on all leaf
+ // nodes.
+ //
+ uint64_t mh_blk_owner;
+
+ //
+ // Block size (LVG MLV blksz).
+ //
+ uint32_t mh_blk_size;
+
+ //
+ // Flags (BLK_FLAG_*).
+ //
+ uint8_t mh_blk_flags;
+
+ //
+ // Reserved for future extensions
+ // make blk header 64 bytes (crypto alignment)
+ //
+ uint8_t mh_reserved1;
+ uint16_t mh_reserved2;
+ uint64_t mh_reserved8;
+};
+typedef struct metadata_header metadata_header_t;
+
+int check_dk_metadata_header_size[sizeof(metadata_header_t) == 64 ? 1 : -1];
+
+
+#define NUM_VOL_HEADERS 2
+#define VOL_HEADER_NBYTES 512
+#define MAX_DISK_LABELS 4
+#define MAX_WIPEKEY_NBYTES 64
+
+//
+// This structure is padded such that it is of correct size.
+//
+struct dk_vol_header {
+ union {
+ struct {
+ metadata_header_t vh_header;
+
+ //
+ // PV size in bytes, rounded down to VOL_HEADER_NBYTES
+ // boundary.
+ //
+ uint64_t vh_pv_nbytes;
+
+ //
+ // If this is not 0, it records a PV resize operation
+ //
+ uint64_t vh_pv_resize;
+
+ //
+ // If this is not 0, it records the old Volume Header
+ // location before the PV resize started; it is again 0
+ // after completion.
+ //
+ uint64_t vh_old_pv_nbytes;
+
+ //
+ // The cpu-platform endian that formatted this LVG.
+ //
+ uint16_t vh_endianness;
+
+ //
+ // Checksum algorithm of VolHdr metadata header.
+ //
+ uint16_t vh_cksum_alg;
+
+ //
+ // Reserved.
+ //
+ uint16_t vh_reserved2;
+
+ //
+ // Number of disk labels.
+ //
+ uint16_t vh_num_labels;
+
+ //
+ // Label address uses this block size.
+ //
+ uint32_t vh_blksz;
+
+ //
+ // Maximum disk label size.
+ //
+ uint32_t vh_label_max_nbytes;
+
+ //
+ // (Physical) Location of the new/old disk labels.
+ //
+ uint64_t vh_label_addr[MAX_DISK_LABELS];
+ uint64_t vh_move_label_addr[MAX_DISK_LABELS];
+
+ //
+ // PV MLV/plist wipe keys ([0] is active, [1] future
+ // re-key).
+ //
+ uint16_t vh_wipe_key_nbytes[2];
+ uint16_t vh_wipe_key_alg[2];
+ uint8_t vh_wipe_key[2][MAX_WIPEKEY_NBYTES];
+
+ //
+ // UUID of this PV and its LVG (for bootstrap/multi-PV)
+ //
+ uint8_t vh_pv_uuid[16];
+ uint8_t vh_lvg_uuid[16];
+ };
+ uint8_t vh_padding[VOL_HEADER_NBYTES];
+ };
+};
+typedef struct dk_vol_header dk_vol_header_t;
+int check_dk_vol_header_size[sizeof(dk_vol_header_t) == VOL_HEADER_NBYTES ? 1 : -1];
+
+//
+// Existing block types cannot be changed!
+//
+enum metadata_blk_type {
+
+ //
+ // The values of the B-Tree types are important. They are the results
+ // of the bit operations of BTREE_ROOT, BTREE_NODE, and BTREE_LEAF in
+ // B-Tree code.
+ //
+ BLK_TYPE_BTREE_NODE = 2, // A B-Tree node that is not a leaf.
+ BLK_TYPE_BTREE_ROOT_NODE = 3, // A non-leaf B-Tree node that is also root.
+ BLK_TYPE_BTREE_LEAF = 4, // A B-Tree leaf node that is not a root.
+ BLK_TYPE_BTREE_ROOT_LEAF = 5, // A B-Tree leaf node that is also root.
+
+ BLK_TYPE_VOL_HEADER = 16,
+
+ //
+ // Fixed part of disk label (first MLV block size).
+ //
+ BLK_TYPE_DISK_LABEL = 17,
+
+ BLK_TYPE_DISK_LABEL_CONT = 18, // Variable part of disk label.
+
+ //
+ // LFS related blocks
+ //
+
+ //
+ // MLV Partial Segment (PS) header block, first block of the first
+ // PS in a Group of Partial Segments (GPS).
+ //
+ BLK_TYPE_PS_HEADER = 19,
+
+ //
+ // MLV Continuation Partial Segment block, first block of a Partial
+ // Segment (PS) in a Group of Partial Segments (GPS), where the PS
+ // is not the first PS in the GPS.
+ //
+ BLK_TYPE_PS_CONT_HDR = 20,
+
+ //
+ // MLV Partial Segment (PS) Overflow header block, which holds
+ // information about added or deleted virtual blocks.
+ //
+ BLK_TYPE_PS_OVERFLOW_HDR = 21,
+
+ //
+ // MLV Virtual Address Table (VAT) blocks, which holds VAT information.
+ //
+ BLK_TYPE_VAT = 22,
+
+ //
+ // MLV Segment Usage Table (SUT) blocks, which holds SUT information.
+ //
+ BLK_TYPE_SUT = 23,
+
+ //
+ // Metadata in MLV.
+ //
+ // MLV super block, the starting point of all MLV metadata.
+ //
+ BLK_TYPE_MLV_SUPERBLOCK = 24,
+
+ //
+ // Logical Volume Family (LVF) super block.
+ //
+ BLK_TYPE_LV_FAMILY_SUPERBLOCK = 25,
+
+ //
+ // Logical Volume (LV) super block.
+ //
+ BLK_TYPE_LV_SUPERBLOCK = 26,
+
+ //
+ // Hold more LV attributes when they don't fit in the LV superblock.
+ //
+ BLK_TYPE_LV_XATTR = 27,
+
+ //
+ // Holds the Physical Volume (PV) information.
+ //
+ BLK_TYPE_PV_TABLE = 28,
+
+ //
+ // Holds the Physical Volume (PV) Freespace Log (FLOG) table
+ // information.
+ //
+ BLK_TYPE_PV_FLOG_TABLE = 29,
+
+ BLK_TYPE_UNUSED_1 = 30,
+ BLK_TYPE_UNUSED_2 = 31,
+ BLK_TYPE_UNUSED_3 = 32,
+
+ //
+ // Used for space sharing, records the amount of free space not used by
+ // the file system inside the Logical Volume.
+ //
+ BLK_TYPE_LV_FREE_SPACE_SUMMARY_DEPRECATED = 33,
+
+ //
+ // Used for Physical Volume (PV) free space management, records the
+ // amount of free space in each chunk of the PV and has pointers to
+ // the Freespace Log (FLOG).
+ //
+ BLK_TYPE_PV_SUMMARY_TABLE = 34,
+
+ BLK_TYPE_UNUSED_4 = 35,
+
+ //
+ // Hold more LV Family attributes when they don't fit in the
+ // LVF superblock.
+ //
+ BLK_TYPE_LV_FAMILY_XATTR = 36,
+
+ //
+ // Hold more Delayed Secure Deletion (DSD) list entries when
+ // they cannot fit in the LVF superblock.
+ //
+ BLK_TYPE_DSD_LIST = 37,
+
+ //
+ // This block type is used to record information about bad sectors
+ // encountered during background encryption/decryption.
+ //
+ BLK_TYPE_BAD_SECTOR_LIST = 38,
+
+ //
+ // For debugging: block is in dummy tree.
+ //
+ BLK_TYPE_DUMMY = 39,
+
+ //
+ // New types are added here to preserve compatible on-disk format.
+ //
+
+ NUM_BLK_TYPES,
+
+ BLK_TYPE_UNKNOWN = 255, // Not used for on-disk blocks.
+};
+
+//
+// Existing block subtypes cannot be changed!
+//
+enum metadata_blk_subtype {
+
+ //
+ // Metadata in MLV.
+ //
+ BLK_SUBTYPE_NO_SUBTYPE = 0,
+
+ BLK_SUBTYPE_LV_FAMILY_TREE,
+ BLK_SUBTYPE_LV_SNAPSHOT_TREE,
+ BLK_SUBTYPE_LV_ADDR_MAP_TREE,
+ BLK_SUBTYPE_PV_REFCOUNT_TREE,
+ BLK_SUBTYPE_LV_UNUSED_SPACE_TREE,
+ BLK_SUBTYPE_LVF_REFCOUNT_TREE,
+
+ //
+ // The b-tree that holds blocks to populate MLV for testing.
+ //
+ BLK_SUBTYPE_DUMMY_TREE,
+
+ //
+ // New types are added here to preserve compatible on-disk format.
+ //
+
+ NUM_BLK_SUBTYPES,
+
+ BLK_SUBTYPE_UNKNOWN = 255, // Not used for on-disk blocks.
+};
+typedef enum metadata_blk_subtype metadata_blk_subtype_t;
+
+
+//
+// This block should be in the DSD List. It is not in the DSD list when it
+// is first created. But when it is modified or killed, it will be included
+// in the DSD list.
+//
+#define BLK_FLAG_IN_DSD_LIST 0x02
+
+//
+// On-disk information of LVG.
+//
+struct lvg_info {
+ uint32_t lvg_signature; // A signature that CoreStorage recognizes.
+
+ //
+ // Version numbers can help diagnose problems.
+ //
+
+ //
+ // The version of CoreStorage that created the LVG.
+ //
+ uint32_t lvg_creator_version;
+
+ //
+ // The version of CoreStorage that modified the LVG the last time.
+ //
+ uint32_t lvg_writer_version;
+
+ //
+ // The interval to sync MLV metadata in milliseconds.
+ //
+ uint16_t lvg_sync_interval_ms;
+
+ //
+ // Checksum algorithm used for all metadata blocks and data blocks.
+ //
+ uint8_t lvg_metadata_cksum_alg;
+
+ //
+ // Do not punch hole in the LVs on trim, so that the sparse LVs can become
+ // less and less sparse over time.
+ //
+ uint8_t lvg_no_punch_hole_on_trim;
+
+ //
+ // These fields control our forwards/backwards compatibility.
+ // Features fall into three categories: compatible, read-only
+ // compatible, and incompatible. For any given version of the
+ // file system code, you can mount a file-system with any set
+ // of compatible features. If the file system encounters bits
+ // that are set in the read-only compatible features field and
+ // it does not know about those features then it must only mount
+ // the file system read-only. If the file system encounters
+ // any bits set in the incompatible features field that it does
+ // not know about, then it must not mount or modify the file
+ // system in any way.
+ //
+ // The idea for these compatibility fields is rather shamelessly
+ // stolen from rocky and ext2.
+ //
+ //
+ uint64_t lvg_compatible_features;
+ uint64_t lvg_read_only_compatible_features;
+ uint64_t lvg_incompatible_features;
+
+ //
+ // When Soft Snapshot is enabled, this is the minimum granularity the
+ // extents will be updated with new timestamp. This is OK to be 0, so a
+ // predefined constant will be used.
+ //
+ uint64_t lvg_soft_snapshot_granularity_nbytes;
+
+ //
+ // When LV checksum is enabled, this is the minimum granularity of data
+ // being checksummed. This is OK to be 0, so a predefined constant will
+ // be used.
+ //
+ uint64_t lvg_checksum_granularity_nbytes;
+
+ //
+ // The min/max versions of CoreStorage that ever wrote to the LVG.
+ //
+ uint32_t lvg_min_writer_version;
+ uint32_t lvg_max_writer_version;
+
+ //
+ // The following unused fields are reserved so we don't need to break
+ // format compatibility too often if we need more per-LVG fields.
+ //
+ uint64_t lvg_unused1;
+ uint64_t lvg_unused2;
+ uint64_t lvg_unused3;
+};
+typedef struct lvg_info lvg_info_t;
+
+#endif /* _LF_CS_DISK_FORMAT_H */
--- /dev/null
+//
+// Copyright (c) 2019-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_logging.c - Implemenents routines for logging info, erros, warnings
+// and debug for livefiles Apple_CoreStorage plugin.
+//
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "lf_cs_logging.h"
+
+#if !LF_CS_USE_OSLOG
+
+#define VPRINTF(fmt, val) vfprintf(stderr, fmt, val)
+
+void
+log_debug(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ VPRINTF(fmt, va);
+ va_end(va);
+}
+
+void
+log_info(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ VPRINTF(fmt, va);
+ va_end(va);
+}
+
+void
+log_warn(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ VPRINTF(fmt, va);
+ va_end(va);
+}
+
+void
+log_err(const char *fmt, ...)
+{
+ va_list va;
+
+ va_start(va, fmt);
+ VPRINTF(fmt, va);
+ va_end(va);
+}
+
+#endif /* !LF_CS_USE_OSLOG */
--- /dev/null
+//
+// Copyright (c) 2009-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_logging.h - Defines for helper methods for logging info, error,
+// warning and debug messages for livefiles Apple_CoreStorage
+// plugin.
+//
+#ifndef _LF_CS_LOGGING_H
+#define _LF_CS_LOGGING_H
+
+#if LF_CS_USE_OSLOG
+#include <os/log.h>
+
+#define debugmsg(fmt, ...) \
+ os_log_debug(OS_LOG_DEFAULT, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define infomsg(fmt, ...) \
+ os_log_info(OS_LOG_DEFAULT, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define warnmsg(fmt, ...) \
+ os_log(OS_LOG_DEFAULT, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define errmsg(fmt, ...) \
+ os_log_error(OS_LOG_DEFAULT, "%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#else /* !LF_CS_USE_OSLOG */
+
+void log_debug(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+void log_info(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+void log_warn(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+void log_err(const char *fmt, ...) __attribute__((format (printf, 1, 2)));
+
+#define debugmsg(fmt, ...) \
+ log_debug("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define infomsg(fmt, ...) \
+ log_info("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define warnmsg(fmt, ...) \
+ log_warn("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+#define errmsg(fmt, ...) \
+ log_err("%s:%d: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#endif /* LF_CS_USE_OSLOG */
+#endif /* _LF_CS_LOGGING_H */
--- /dev/null
+//
+// Copyright (c) 2019-2019 Apple Inc. All rights reserved.
+//
+// lf_cs_vfsops.c - Implemenents routines for handling VFS operations for
+// livefiles Apple_CoreStorage plugin.
+//
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/disk.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/storage/IOMedia.h>
+#include <MediaKit/GPTTypes.h>
+#include <IOKit/IOBSD.h>
+#include <IOKit/IOTypes.h>
+
+#include "lf_cs_checksum.h"
+#include "lf_cs_disk_format.h"
+#include "lf_cs_logging.h"
+#include "lf_cs.h"
+
+#define VALUE_UNSPECIFIED ((uint64_t)-1)
+
+//
+// Verify the given data checksum. If no explicit 'chk' area the cksum
+// value to match against is assumed to reside at the beginning of the
+// provided buffer (typically a 'metadata_header_t') and is excluded from
+// the cksum calculation itself.
+//
+static unsigned
+cs_verify_cksum(cksum_alg_t alg, const void *ptr, size_t len,
+ uint8_t *chk)
+{
+ uint8_t c[MAX_CKSUM_NBYTES];
+
+ if (!(alg == CKSUM_NONE) && !(alg == CKSUM_ALG_CRC_32)) {
+ return CS_STATUS_INVALID;
+ }
+
+ cksum_init(alg, c);
+ if (chk == NULL) {
+ cksum(alg, (chk = (uint8_t *)ptr) + MAX_CKSUM_NBYTES,
+ len - MAX_CKSUM_NBYTES, c);
+ } else {
+ cksum(alg, ptr, len, c);
+ }
+
+ if (memcmp(c, chk, MAX_CKSUM_NBYTES)) {
+ return CS_STATUS_CKSUM;
+ }
+
+ return CS_STATUS_OK;
+}
+
+//
+// These block types must belong to the current transaction; all
+// other types can be referenced from older transactions.
+//
+#define CS_CHKPOINT_BLK(_b) \
+ ((_b)->mh_blk_type >= BLK_TYPE_VOL_HEADER &&\
+ (_b)->mh_blk_type <= BLK_TYPE_SUT)
+
+
+//
+// These block types are the only ones with Secure Deletion content (LVF).
+//
+#define CS_DSDLIST_BLK(_b) \
+ ((_b)->mh_blk_type == BLK_TYPE_LV_FAMILY_SUPERBLOCK ||\
+ (_b)->mh_blk_type == BLK_TYPE_LV_FAMILY_XATTR)
+
+//
+// cs_verify_blkhdr - Verify standard metadata header fields.
+//
+// Each block begins with a 'metadata_header_t', which often has known/expected
+// values.
+//
+static unsigned
+cs_verify_blkhdr(const metadata_header_t *hdr, uint16_t alg,
+ uint8_t type, uint8_t subtype, uint64_t vaddr,
+ uint64_t laddr, uint64_t txg, uint32_t blksz)
+{
+ unsigned status;
+
+ if (alg != CKSUM_NONE && (status = cs_verify_cksum((cksum_alg_t)alg,
+ hdr, blksz, NULL)) != CS_STATUS_OK) {
+ return status;
+ }
+
+ if (type != BLK_TYPE_UNKNOWN && hdr->mh_blk_type != type) {
+ return CS_STATUS_BLKTYPE;
+ }
+
+ if (subtype != BLK_SUBTYPE_UNKNOWN && hdr->mh_blk_subtype != subtype) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (vaddr != VALUE_UNSPECIFIED && hdr->mh_vaddr != vaddr) {
+ return CS_STATUS_ADDRESS;
+ }
+
+ if (laddr != VALUE_UNSPECIFIED && hdr->mh_laddr != laddr) {
+ return CS_STATUS_ADDRESS;
+ }
+
+ if (txg != VALUE_UNSPECIFIED) {
+ if (CS_CHKPOINT_BLK(hdr) && hdr->mh_txg_id != txg)
+ return CS_STATUS_TXG;
+ else if (hdr->mh_txg_id > txg)
+ return CS_STATUS_TXG;
+ }
+
+ if (blksz != 0 && hdr->mh_blk_size != blksz) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (!CS_DSDLIST_BLK(hdr) &&
+ (hdr->mh_blk_flags & BLK_FLAG_IN_DSD_LIST)) {
+ return CS_STATUS_INVALID;
+ }
+
+ return CS_STATUS_OK;
+}
+
+//
+// cs_verify_versions - Verify volume header version.
+//
+static unsigned
+cs_verify_versions(const metadata_header_t *hdr)
+{
+ if (hdr != NULL && hdr->mh_format_version !=
+ CORESTORAGE_FORMAT_VERSION) {
+ return CS_INFO_VERSIONITIS | CS_STATUS_NOTCS;
+ }
+
+ if (hdr != NULL &&
+ hdr->mh_blk_type == BLK_TYPE_VOL_HEADER &&
+ ((dk_vol_header_t *)hdr)->vh_endianness !=
+ BYTE_ORDER_MARK) {
+ return CS_INFO_VERSIONITIS | CS_STATUS_NOTCS;
+ }
+
+ return CS_STATUS_OK;
+}
+
+//
+// cs_verify_vh - Read and verify the Volume Headers (first/last 512-bytes of
+// the PV).
+//
+static unsigned
+cs_verify_vh(dk_vol_header_t *hdr, uint32_t blksz)
+{
+ unsigned status;
+
+ status = cs_verify_blkhdr(&hdr->vh_header, hdr->vh_cksum_alg,
+ BLK_TYPE_VOL_HEADER,
+ BLK_SUBTYPE_NO_SUBTYPE, 0, 0,
+ VALUE_UNSPECIFIED, VOL_HEADER_NBYTES);
+ if (status != CS_STATUS_OK) {
+ return status;
+ }
+
+ status = cs_verify_versions(&hdr->vh_header);
+ if (status != CS_STATUS_OK) {
+ return status;
+ }
+
+ if (!hdr->vh_num_labels || hdr->vh_num_labels > MAX_DISK_LABELS) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (hdr->vh_label_max_nbytes % blksz != 0) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (hdr->vh_blksz == 0 || hdr->vh_blksz % blksz != 0) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (hdr->vh_pv_nbytes % blksz != 0 ||
+ hdr->vh_pv_nbytes < CS_ALIGN(VOL_HEADER_NBYTES,
+ blksz, true) * NUM_VOL_HEADERS) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (hdr->vh_pv_resize != 0 && (hdr->vh_pv_resize % blksz != 0 ||
+ hdr->vh_pv_resize < CS_ALIGN(VOL_HEADER_NBYTES,
+ blksz, true) * NUM_VOL_HEADERS)) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (hdr->vh_old_pv_nbytes != 0 &&
+ (hdr->vh_old_pv_nbytes % blksz != 0 ||
+ hdr->vh_old_pv_nbytes < CS_ALIGN(VOL_HEADER_NBYTES,
+ blksz, true) * NUM_VOL_HEADERS)) {
+ return CS_STATUS_INVALID;
+ }
+
+ return CS_STATUS_OK;
+}
+
+//
+// cs_get_content_hint_for_pv - get content hint of the disk from IOReg. We
+// read the IOReg to check if the passed disk has
+// a Apple_CoreStorage content hint.
+//
+static bool
+cs_get_content_hint_for_pv(struct stat *st)
+{
+ bool has_cs_hint;
+ int dev_major, dev_minor;
+ CFMutableDictionaryRef matching;
+
+ has_cs_hint = false;
+ if ((matching = IOServiceMatching(kIOMediaClass))) {
+ CFTypeRef str;
+ io_service_t service;
+
+ if ((matching = IOServiceMatching(kIOMediaClass))) {
+ CFNumberRef num_ref;
+
+ dev_major = major(st->st_rdev);
+ dev_minor = minor(st->st_rdev);
+
+ num_ref = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberIntType, &dev_major);
+ if (num_ref) {
+ CFDictionarySetValue(matching,
+ CFSTR(kIOBSDMajorKey),
+ num_ref);
+ CFRelease(num_ref);
+ }
+
+ num_ref = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberIntType, &dev_minor);
+ if (num_ref) {
+ CFDictionarySetValue(matching,
+ CFSTR(kIOBSDMinorKey),
+ num_ref);
+ CFRelease(num_ref);
+ }
+
+ service = IOServiceGetMatchingService(
+ kIOMasterPortDefault, matching);
+ if (!service) {
+ goto out;
+ }
+
+ if ((str = IORegistryEntryCreateCFProperty( service,
+ CFSTR(kIOMediaContentHintKey),
+ kCFAllocatorDefault, 0)) !=
+ NULL) {
+
+ has_cs_hint = CFStringCompare((CFStringRef)str,
+ CFSTR(APPLE_CORESTORAGE_UUID), 0) ==
+ kCFCompareEqualTo;
+
+ CFRelease(str);
+ IOObjectRelease(service);
+ }
+ }
+ }
+out:
+ return has_cs_hint;
+}
+
+static unsigned
+cs_verify_hdrfields(void *block, uint16_t alg, uint8_t type,
+ uint8_t subtype, uint64_t vaddr, uint64_t laddr,
+ uint32_t blksz)
+{
+ unsigned status;
+
+ if (alg != CKSUM_NONE && (status = cs_verify_cksum((cksum_alg_t)alg,
+ block, blksz, NULL)) !=
+ CS_STATUS_OK) {
+ return status;
+ }
+
+ if (type != BLK_TYPE_VOL_HEADER) {
+ return CS_STATUS_BLKTYPE;
+ }
+
+ if (subtype != BLK_SUBTYPE_NO_SUBTYPE) {
+ return CS_STATUS_INVALID;
+ }
+
+ if (vaddr != 0) {
+ return CS_STATUS_ADDRESS;
+ }
+
+ if (laddr != 0) {
+ return CS_STATUS_ADDRESS;
+ }
+
+ if (blksz != VOL_HEADER_NBYTES) {
+ return CS_STATUS_INVALID;
+ }
+
+ return CS_STATUS_OK;
+}
+
+//
+// Verify if a Volume Header error might actually be due to a stale format.
+// Some historic block layouts were such that they spuriously fail recent
+// validity checks (there was a relocation of some key identifying fields in
+// the v9->v10->v11 switch). Thus we follow-up a failure by some rudimentary
+// probing (incl cksum) and override error.
+//
+static unsigned
+cs_older_cs_version(dk_vol_header_t *hdr, unsigned status)
+{
+ uint16_t cksum_alg;
+
+ struct {
+ uint8_t zeroes[VOL_HEADER_NBYTES];
+ } inprogress = {0};
+
+ struct v11_volhdr {
+ uint8_t mh_cksum[MAX_CKSUM_NBYTES];
+ uint16_t mh_format_version;
+ uint8_t mh_blk_type;
+ uint8_t mh_blk_subtype;
+ uint32_t mh_bundle_version;
+ uint64_t mh_txg_id;
+ uint64_t mh_vaddr;
+ uint64_t mh_laddr;
+ uint64_t mh_blk_owner;
+ uint32_t mh_blk_size;
+ uint8_t mh_blk_flags;
+ uint8_t mh_reserved1;
+ uint16_t mh_reserved2;
+ uint64_t mh_reserved8;
+ uint64_t vh_pv_nbytes;
+ uint64_t vh_pv_resize;
+ uint64_t vh_old_pv_nbytes;
+ uint16_t vh_endianness;
+ uint16_t vh_cksum_alg;
+ uint16_t vh_reserved2;
+ uint16_t vh_num_labels;
+ uint32_t vh_blksz;
+ uint32_t vh_label_max_nbytes;
+ uint64_t vh_label_addr[MAX_DISK_LABELS];
+ uint64_t vh_move_label_addr[MAX_DISK_LABELS];
+ uint16_t vh_wipe_key_nbytes[2];
+ uint16_t vh_wipe_key_alg[2];
+ uint8_t vh_wipe_key[2][MAX_WIPEKEY_NBYTES];
+ uint8_t vh_pv_uuid[16];
+ uint8_t vh_lvg_uuid[16];
+ } *v11;
+
+
+ if ((CS_STATUS(status) != CS_STATUS_OK) &&
+ (hdr->vh_header.mh_format_version !=
+ CORESTORAGE_FORMAT_VERSION)) {
+
+ //
+ // Ensure that the volume header is not totally empty before
+ // trying to check if this is indeed an older version.
+ //
+ if (!memcmp(hdr, &inprogress, VOL_HEADER_NBYTES)) {
+ return CS_INFO_ZERO_VH | CS_STATUS_NOTCS;
+ }
+
+ v11 = (struct v11_volhdr *)hdr;
+ if (v11->mh_format_version == 11) {
+
+ cksum_alg = v11->vh_cksum_alg;
+ if (cs_verify_hdrfields(v11, cksum_alg,
+ v11->mh_blk_type,
+ v11->mh_blk_subtype,
+ v11->mh_vaddr,
+ v11->mh_laddr,
+ v11->mh_blk_size) ==
+ CS_STATUS_OK) {
+
+ return CS_INFO_VERSIONITIS | CS_STATUS_NOTCS;
+ }
+ }
+ }
+
+ return status;
+}
+
+//
+// cs_fd_is_corestorage_pv - taste if the disk is Apple_CoreStorage PV.
+//
+static int
+cs_fd_is_corestorage_pv(int disk_fd, bool *is_cs_pv)
+{
+ struct stat st;
+ bool pv_has_csuuid_hint;
+ int vh_idx, error;
+ uint32_t pv_blksz;
+ uint64_t pv_nblks;
+ uint64_t offset[NUM_VOL_HEADERS + 1];
+ unsigned status[NUM_VOL_HEADERS + 1];
+
+ dk_vol_header_t hdr[NUM_VOL_HEADERS + 1];
+
+ error = 0;
+ pv_blksz = 0;
+ pv_nblks = 0;
+ *is_cs_pv = false;
+ pv_has_csuuid_hint = false;
+
+ infomsg("Tasting Apple_CoreStorage plugin, fd: %d\n", disk_fd);
+
+ //
+ // Userfs corestorage plugin only supports block device. Thus, we
+ // ensure that the passed device is block device before proceeding
+ // further.
+ //
+ fstat(disk_fd, &st);
+ if (!S_ISBLK(st.st_mode)) {
+ errmsg("Apple_CoreStorage plugin only supports block "
+ "device. Aborting taste.\n");
+ return ENOTSUP;
+ }
+
+ //
+ // Each PV has two volume headers, each has size 512 bytes, and resides
+ // on the first and last 512 bytes of the PV. Each volume header has a
+ // common block header with txg id and checksum, and only the volume
+ // header with the right checksum and largest txg id is used when
+ // mounting the LVG. Thus, to read the last volume header we need to
+ // know the block-size and the number of blocks in the block device.
+ //
+ if (ioctl(disk_fd, DKIOCGETBLOCKSIZE, &pv_blksz) == -1) {
+ error = errno;
+ }
+
+ if (!error && ioctl(disk_fd, DKIOCGETBLOCKCOUNT, &pv_nblks) == -1) {
+ error = errno;
+ }
+
+ //
+ // If we fail to determine the block size and block count, we bail out.
+ //
+ if (!error && (!pv_blksz || !pv_nblks)) {
+ error = ENOTBLK;
+ }
+
+ if (error) {
+ errmsg("Failed to get blocksize and block count "
+ "for the device. Aborting taste.\n");
+ return error;
+ }
+
+ //
+ // Check if the device is tagged as being Apple_CoreStorage (Content
+ // Hint). If not we bail-out now.
+ //
+ pv_has_csuuid_hint = cs_get_content_hint_for_pv(&st);
+ if (!pv_has_csuuid_hint) {
+ *is_cs_pv = false;
+ return 0;
+ }
+
+ //
+ // We go through the two volume headers at offset 0 and at offset
+ // (pv_nblks * pv_blksz - VOL_HEADER_NBYTES) and try to verify if
+ // the volume headers are valid core storage physical volume volume
+ // headers.
+ //
+ offset[0] = 0;
+ offset[1] = pv_nblks * pv_blksz - VOL_HEADER_NBYTES;
+
+ //
+ // Initialize status as invalid.
+ //
+ for (vh_idx = 0; vh_idx < NUM_VOL_HEADERS; ++vh_idx ) {
+ status[vh_idx] = CS_STATUS_INVALID;
+ }
+
+ for (vh_idx = 0; vh_idx < NUM_VOL_HEADERS; ++vh_idx) {
+ ssize_t bytes_read;
+
+ //
+ // Read the PV volume header and cache it inside `hdr[vh_idx]`.
+ //
+ bytes_read = pread(disk_fd, &hdr[vh_idx], VOL_HEADER_NBYTES,
+ offset[vh_idx]);
+
+ if (bytes_read == -1) {
+ error = errno;
+ }
+
+ if (!error && bytes_read != VOL_HEADER_NBYTES) {
+ error = EIO;
+ }
+
+ if (error) {
+ errmsg("Failed to read volume-hearder at offset %llu "
+ "for disk with fd %d, Aborting taste.\n",
+ offset[vh_idx], disk_fd);
+ break;
+ }
+
+ //
+ // Verify read volume-header.
+ //
+ status[vh_idx] = cs_verify_vh(&hdr[vh_idx], pv_blksz);
+ if (CS_STATUS(status[vh_idx]) != CS_STATUS_OK) {
+
+ //
+ // Check if this physical volume has an older version
+ // of header.
+ //
+ status[vh_idx] = cs_older_cs_version(&hdr[vh_idx],
+ status[vh_idx]);
+ if (CS_INFO(status[vh_idx]) & CS_INFO_VERSIONITIS) {
+
+ infomsg("Disk with fd %u has older physical "
+ "volume header format.\n",
+ disk_fd);
+ status[vh_idx] = CS_STATUS_OK;
+ }
+ }
+
+ if (status[vh_idx] != CS_STATUS_OK) {
+ break;
+ }
+ }
+
+ if (error) {
+ return error;
+ }
+
+ //
+ // If there was no error and both the volume headers passed
+ // verification that means this is a core storage physical volume.
+ //
+ for (vh_idx = 0; vh_idx < NUM_VOL_HEADERS; ++vh_idx ) {
+ if (status[vh_idx] != CS_STATUS_OK) {
+ break;
+ }
+ *is_cs_pv = true;
+ }
+
+ return 0;
+}
+
+//
+// cs_uvfsop_taste - taste if a given disk is Apple_CoreStorage PV.
+//
+// disk_fd: file descriptor of the disk to taste.
+//
+// Returns:
+//
+// i) 0 if the passed disk is indeed an Apple_CoreStorage PV.
+//
+// Or
+//
+// ii) ENOTSUP if the passed disk is not an Apple_CoreStorage PV.
+//
+// Or
+//
+// iii) errno if there was some error attempting to taste the disk.
+//
+static int
+cs_uvfsop_taste(int disk_fd)
+{
+ int error;
+ bool is_cs_pv;
+
+ //
+ // Each PV has two volume headers, each has size 512 bytes, and resides
+ // on the first and last 512 bytes of the PV. Each volume header has a
+ // common block header with transaction-id and checksum, and only the
+ // volume header with the right checksum and largest transaction-id is
+ // used when mounting the LVG(logical volume group). To verify that
+ // the disk with file descriptor is indeed a Apple_CoreStorage PV
+ // (physical volume), we:
+ //
+ // i) Read IOReg to verify that it has `APPLE_CORESTORAGE_UUID` hint.
+ //
+ // and
+ //
+ // ii) Verify the PV volume headers at the start and end of the disk.
+ //
+ // Please NOTE: This taste function is defensive (strict). We do a
+ // strict match so that we ensure that we don't falsely match some
+ // other volume format.
+ //
+ error = cs_fd_is_corestorage_pv(disk_fd, &is_cs_pv);
+ if (error) {
+ errmsg("Encountered error while tasting disk with file "
+ "descriptor %d for Apple_CoreStorage "
+ "plugin (error %d).\n", disk_fd, error);
+ return error;
+
+ }
+
+ //
+ // This is not an Apple_CoreStorage PV.
+ //
+ if (!is_cs_pv) {
+ errmsg("Disk with file descriptor %d is not an corestorage "
+ "physical volume.\n", disk_fd);
+ return ENOTSUP;
+ }
+
+ //
+ // We have found an Apple_CoreStorage PV, return success.
+ //
+ infomsg("Disk with file descriptor %d is corestorage physical "
+ "volume.\n", disk_fd);
+
+ return 0;
+}
+
+//
+// Plugin lifecycle functions.
+//
+static int
+cs_uvfsop_init(void)
+{
+ infomsg("Initializing CS UserFS plugin...\n");
+ return 0;
+}
+
+static void
+cs_uvfsop_fini(void)
+{
+ infomsg("Cleaning up CS UserFS plugin...\n");
+}
+
+//
+// Plugin function registration.
+//
+UVFSFSOps cs_fsops = {
+ .fsops_version = UVFS_FSOPS_VERSION_CURRENT,
+ .fsops_init = cs_uvfsop_init,
+ .fsops_fini = cs_uvfsop_fini,
+ .fsops_taste = cs_uvfsop_taste,
+};
+
+__attribute__((visibility("default")))
+void
+livefiles_plugin_init(UVFSFSOps **ops)
+{
+ if (ops) {
+ *ops = &cs_fsops;
+ }
+}
--- /dev/null
+//
+// Copyright (c) 2019 Apple Inc. All rights reserved.
+//
+// @APPLE_LICENSE_HEADER_START@
+//
+// This file contains Original Code and/or Modifications of Original Code
+// as defined in and that are subject to the Apple Public Source License
+// Version 2.0 (the 'License'). You may not use this file except in
+// compliance with the License. Please obtain a copy of the License at
+// http://www.opensource.apple.com/apsl/ and read it before using this
+// file.
+//
+// The Original Code and all software distributed under the License are
+// distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+// EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+// INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+// Please see the License for the specific language governing rights and
+// limitations under the License.
+//
+// @APPLE_LICENSE_HEADER_END@
+//
+// livefiles_cs_tester.c - Implements unit tests for livefiles
+// Apple_CoreStorage plugin.
+//
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <UserFS/UserVFS.h>
+
+extern UVFSFSOps cs_fsops;
+
+//
+// Enums describing file-system formats.
+//
+typedef enum {
+ JHFS = 1,
+ APFS,
+ FAT32,
+ EXFAT,
+ APPLE_CS,
+
+ INVALID_FS_TYPE = INT8_MAX,
+} lf_cspt_fstype_t;
+
+//
+// Array describing file-system name and analogous types.
+//
+const struct {
+ const char *const fs_name;
+ lf_cspt_fstype_t fs_type;
+} lf_cspt_fstype_arr_t[] = {
+
+ {"JHFS", JHFS},
+ {"APFS", APFS},
+ {"EXFAT",EXFAT},
+ {"FAT32",FAT32},
+ {"APPLE_CS", APPLE_CS},
+
+ {NULL, INVALID_FS_TYPE}
+};
+
+//
+// Validate file-system types that is supported by this program.
+//
+static bool
+is_fstype_valid(const char *fs_name, lf_cspt_fstype_t *fs_type)
+{
+ int idx;
+
+ for (idx = 0; lf_cspt_fstype_arr_t[idx].fs_name != NULL; idx++) {
+ if (strcmp(fs_name, lf_cspt_fstype_arr_t[idx].fs_name) == 0) {
+ *fs_type = lf_cspt_fstype_arr_t[idx].fs_type;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+//
+// Usage string returned to user.
+//
+static int
+usage(const char *prog_name)
+{
+ fprintf(stderr, "Usage: %s filesystem-format device-path\n",
+ prog_name);
+ return EINVAL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int fd, error;
+ lf_cspt_fstype_t fs_type;
+
+ if (argc != 3) {
+ return usage(argv[0]);
+ }
+
+ if (!is_fstype_valid(argv[1], &fs_type)) {
+ fprintf(stderr, "Unknown file-system type %s\n", argv[1]);
+ return EINVAL;
+ }
+
+ fd = open(argv[2], O_RDWR);
+ if (fd < 0) {
+ fprintf(stderr, "Failed to open device [%s]: %d\n",
+ argv[2], errno);
+ return EBADF;
+ }
+
+ error = cs_fsops.fsops_init();
+ printf("Init for fs_type %s returned [%d]\n", argv[1], error);
+ if (error) {
+ goto test_end;
+ }
+
+ error = cs_fsops.fsops_taste(fd);
+ switch(fs_type) {
+ case JHFS:
+ case APFS:
+ case EXFAT:
+ case FAT32:
+
+ //
+ // Taste with these disk-image is expected to retrun
+ // ENOTSUP. Thus supress the error here.
+ //
+ if (error == ENOTSUP) {
+ error = 0;
+ }
+ break;
+
+ case APPLE_CS:
+ break;
+
+ //
+ // Control should not come here.
+ //
+ default:
+ fprintf(stderr, "Bug in test.\n");
+ }
+ printf("Taste for fs_type %s returned [%d]\n", argv[1], error);
+ cs_fsops.fsops_fini();
+
+test_end:
+ printf("Test result [%d]\n", error);
+ close(fd);
+ return EXIT_SUCCESS;
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>com.apple.rootless.restricted-block-devices</key>
+ <true/>
+ <key>com.apple.private.security.disk-device-access</key>
+ <true/>
+</dict>
+</plist>
uuid_t hfs_full_uuid;
/* Per mount cnode hash variables: */
- pthread_mutex_t hfs_chash_mutex; /* protects access to cnode hash table */
- u_long hfs_cnodehash; /* size of cnode hash table - 1 */
+ pthread_mutex_t hfs_chash_mutex; /* protects access to cnode hash table */
+ u_long hfs_cnodehash; /* size of cnode hash table - 1 */
LIST_HEAD(cnodehashhead, cnode) *hfs_cnodehashtbl; /* base of cnode hash */
/* Per mount fileid hash variables (protected by catalog lock!) */
break;
}
if ((result = getkey(hfsmp, cnid, (CatalogKey *)keyp))) {
- LFHFS_LOG(LEVEL_ERROR, "cat_check_link_ancestry: getkey failed id=%u, vol=%s\n", cnid, hfsmp->vcbVN);
+ LFHFS_LOG(LEVEL_ERROR, "cat_check_link_ancestry: getkey failed [%d] id=%u, vol=%s\n", result, cnid, hfsmp->vcbVN);
invalid = 1; /* On errors, assume an invalid parent */
break;
}
if ((result = BTSearchRecord(fcb, ip, &btdata, NULL, NULL))) {
- LFHFS_LOG(LEVEL_ERROR, "cat_check_link_ancestry: cannot find id=%u, vol=%s\n", cnid, hfsmp->vcbVN);
+ LFHFS_LOG(LEVEL_ERROR, "cat_check_link_ancestry: cannot find id=%u, vol=%s, [%d]\n", cnid, hfsmp->vcbVN, result);
invalid = 1; /* On errors, assume an invalid parent */
break;
}
pthread_cond_wait(&cp->c_cacsh_cond, &hfsmp->hfs_chash_mutex);
}
-void
+static void
hfs_chash_broadcast_and_unlock(struct hfsmount *hfsmp, struct cnode *cp)
{
- pthread_cond_signal(&cp->c_cacsh_cond);
+ if (cp)
+ pthread_cond_signal(&cp->c_cacsh_cond);
hfs_chash_unlock(hfsmp);
}
+static void
+hfs_chash_wait_and_unlock(struct hfsmount *hfsmp, struct cnode *cp)
+{
+ SET(cp->c_hflag, H_WAITING);
+ pthread_cond_wait(&cp->c_cacsh_cond, &hfsmp->hfs_chash_mutex);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
+}
+
void
hfs_chash_raise_OpenLookupCounter(struct cnode *cp)
{
if (hfs_lock(cp, HFS_TRY_EXCLUSIVE_LOCK, HFS_LOCK_ALLOW_NOEXISTS))
{
SET(cp->c_hflag, H_WAITING);
- hfs_chash_broadcast_and_unlock(hfsmp,cp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
usleep(100);
goto loop;
}
*hflags &= ~H_ATTACH;
}
+ pthread_cond_signal(&cp->c_cacsh_cond);
vp = NULL;
cp = NULL;
if (renamed)
}
}
- if (cp) hfs_chash_raise_OpenLookupCounter(cp);
- hfs_chash_broadcast_and_unlock(hfsmp,cp);
+ if (cp) {
+ hfs_chash_raise_OpenLookupCounter(cp);
+ }
+
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
+
*vpp = vp;
return (cp);
}
if (ncp == NULL)
{
hfs_chash_unlock(hfsmp);
-
ncp = hfs_mallocz(sizeof(struct cnode));
if (ncp == NULL)
{
lf_lck_rw_init(&ncp->c_rwlock);
lf_cond_init(&ncp->c_cacsh_cond);
-
+
if (!skiplock)
{
(void) hfs_lock(ncp, HFS_EXCLUSIVE_LOCK, HFS_LOCK_DEFAULT);
if (ISSET(cp->c_hflag, H_WAITING)) {
CLR(cp->c_hflag, H_WAITING);
- pthread_cond_broadcast(&cp->c_cacsh_cond);
}
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
}
/*
if (ISSET(cp->c_hflag, H_WAITING))
{
CLR(cp->c_hflag, H_WAITING);
- pthread_cond_broadcast(&cp->c_cacsh_cond);
}
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
}
/*
/* Wait if cnode is being created or reclaimed. */
if (ISSET(cp->c_hflag, H_ALLOC | H_TRANSIT | H_ATTACH)) {
SET(cp->c_hflag, H_WAITING);
- hfs_chash_broadcast_and_unlock(hfsmp,cp);
- usleep(100);
+ hfs_chash_wait_and_unlock(hfsmp,cp);
goto loop;
}
/* Obtain the desired vnode. */
if (hfs_lock(cp, HFS_TRY_EXCLUSIVE_LOCK, HFS_LOCK_ALLOW_NOEXISTS))
{
SET(cp->c_hflag, H_WAITING);
- hfs_chash_broadcast_and_unlock(hfsmp,cp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
usleep(100);
goto loop;
}
}
hfs_chash_raise_OpenLookupCounter(cp);
- hfs_chash_broadcast_and_unlock(hfsmp,cp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
return (vp);
}
+
exit:
hfs_chash_unlock(hfsmp);
return (NULL);
retval = 1;
}
}
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
return retval;
}
/* Check if a vnode is getting attached */
if (ISSET(cp->c_hflag, H_ATTACH)) {
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
return (EBUSY);
}
if (cp->c_hash.le_next || cp->c_hash.le_prev) {
cp->c_hash.le_prev = NULL;
}
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
return (0);
}
SET(cp->c_hflag, H_TRANSIT);
- hfs_chash_unlock(hfsmp);
+ hfs_chash_broadcast_and_unlock(hfsmp, cp);
}
struct mount *mp = HFSTOVFS(hfsmp);
struct vnode *vp = NULL;
struct vnode **cvpp;
- struct vnode *tvp = NULL;
struct cnode *cp = NULL;
struct filefork *fp = NULL;
struct vnode *provided_vp = NULL;
}
cp->c_rsrcfork = fp;
cvpp = &cp->c_rsrc_vp;
- if ( (tvp = cp->c_vp) != NULL )
+ if (cp->c_vp != NULL )
{
cp->c_flag |= C_NEED_DVNODE_PUT;
}
cp->c_datafork = fp;
cvpp = &cp->c_vp;
- if ( (tvp = cp->c_rsrc_vp) != NULL)
+ if (cp->c_rsrc_vp != NULL)
{
cp->c_flag |= C_NEED_RVNODE_PUT;
}
retval = ENOMEM;
goto gnv_exit;
}
-
+ bzero(vfsp.vnfs_cnp, sizeof(struct componentname));
memcpy((void*) vfsp.vnfs_cnp, (void*)cnp, sizeof(struct componentname));
vfsp.vnfs_cnp->cn_nameptr = lf_hfs_utils_allocate_and_copy_string( (char*) cnp->cn_nameptr, cnp->cn_namelen );
if (vp->sFSParams.vnfs_cnp)
{
- if (vp->sFSParams.vnfs_cnp->cn_nameptr)
+ if (vp->sFSParams.vnfs_cnp->cn_nameptr) {
hfs_free(vp->sFSParams.vnfs_cnp->cn_nameptr);
+ vp->sFSParams.vnfs_cnp->cn_nameptr = NULL;
+ }
hfs_free(vp->sFSParams.vnfs_cnp);
+ vp->sFSParams.vnfs_cnp = NULL;
}
int
hfs_vnop_reclaim(struct vnode *vp)
{
+ if (!vp) return EINVAL;
+
struct cnode* cp = VTOC(vp);
struct hfsmount *hfsmp = VTOHFS(vp);
struct vnode *altvp = NULL;
return E2BIG;
}
// A string representing the type of file system
- strcpy(psAttrVal->fsa_string, "HFS");
- *(psAttrVal->fsa_string+3) = 0; // Must be null terminated
+ size_t n = strlcpy(psAttrVal->fsa_string, "HFS", *puRetLen);
+ if (n >= *puRetLen)
+ {
+ *(psAttrVal->fsa_string + (*puRetLen - 1)) = '\0'; // Must be null terminated
+ }
goto end;
}
return E2BIG;
}
- strcpy( psAttrVal->fsa_string, pcFSSubType );
+ strlcpy( psAttrVal->fsa_string, pcFSSubType, *puRetLen);
goto end;
}
{
return E2BIG;
}
- strcpy(psAttrVal->fsa_string, (char *)psMount->vcbVN);
+ strlcpy(psAttrVal->fsa_string, (char *)psMount->vcbVN, *puRetLen);
goto end;
}
lock_oldstart(jnl);
/*
- * Because old_start is locked above, we can cast away the volatile qualifier before passing it to memcpy.
+ * Because old_start is locked above, we can cast away the volatile qualifier before passing it to memmove.
* slide everyone else down and put our latest guy in the last
* entry in the old_start array
*/
- memcpy(__CAST_AWAY_QUALIFIER(&jnl->old_start[0], volatile, void *), __CAST_AWAY_QUALIFIER(&jnl->old_start[1], volatile, void *), sizeof(jnl->old_start)-sizeof(jnl->old_start[0]));
+ memmove(__CAST_AWAY_QUALIFIER(&jnl->old_start[0], volatile, void *), __CAST_AWAY_QUALIFIER(&jnl->old_start[1], volatile, void *), sizeof(jnl->old_start)-sizeof(jnl->old_start[0]));
jnl->old_start[sizeof(jnl->old_start)/sizeof(jnl->old_start[0]) - 1] = tr->journal_start | 0x8000000000000000LL;
unlock_oldstart(jnl);
/* Get the CNID for use */
cnid_t new_id;
- if ((error = cat_acquire_cnid(hfsmp, &new_id))) {
+ if (cat_acquire_cnid(hfsmp, &new_id)) {
hfs_systemfile_unlock (hfsmp, lockflags);
goto exit;
}
mntwrapper = 0;
minblksize = kHFSBlockSize;
+ *hfsmp = NULL;
/* Get the logical block size (treated as physical block size everywhere) */
if (ioctl(devvp->psFSRecord->iFD, DKIOCGETBLOCKSIZE, &log_blksize))
goto error_exit;
}
+ /* Don't let phys_blksize be smaller than the logical */
+ if (phys_blksize < log_blksize) {
+ /*
+ * In the off chance that the phys_blksize is SMALLER than the logical
+ * then don't let that happen. Pretend that the PHYSICALBLOCKSIZE
+ * ioctl was not supported.
+ */
+ phys_blksize = log_blksize;
+ }
+
/* Get the number of physical blocks. */
if (ioctl(devvp->psFSRecord->iFD, DKIOCGETBLOCKCOUNT, &log_blkcnt))
{
hfs_systemfile_unlock(hfsmp, flags);
}
-int
-hfs_GetInfoByID(struct hfsmount *hfsmp, cnid_t cnid, UVFSFileAttributes *file_attrs, char pcName[MAX_UTF8_NAME_LENGTH])
-{
- u_int32_t linkref = 0;
- struct vnode *psVnode = NULL;
- struct cat_desc cndesc;
- struct cat_attr cnattr;
- struct cat_fork cnfork;
- int error = 0;
-
- /* Check for cnids that should't be exported. */
- if ((cnid < kHFSFirstUserCatalogNodeID) &&
- (cnid != kHFSRootFolderID && cnid != kHFSRootParentID)) {
- return (ENOENT);
- }
- /* Don't export our private directories. */
- if (cnid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid ||
- cnid == hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) {
- return (ENOENT);
- }
- /*
- * Check the hash first
- */
- psVnode = hfs_chash_getvnode(hfsmp, cnid, 0, 0, 0);
- if (psVnode) {
- goto getAttrAndDone;
- }
-
- bzero(&cndesc, sizeof(cndesc));
- bzero(&cnattr, sizeof(cnattr));
- bzero(&cnfork, sizeof(cnfork));
-
- /*
- * Not in hash, lookup in catalog
- */
- if (cnid == kHFSRootParentID) {
- static char hfs_rootname[] = "/";
-
- cndesc.cd_nameptr = (const u_int8_t *)&hfs_rootname[0];
- cndesc.cd_namelen = 1;
- cndesc.cd_parentcnid = kHFSRootParentID;
- cndesc.cd_cnid = kHFSRootFolderID;
- cndesc.cd_flags = CD_ISDIR;
-
- cnattr.ca_fileid = kHFSRootFolderID;
- cnattr.ca_linkcount = 1;
- cnattr.ca_entries = 1;
- cnattr.ca_dircount = 1;
- cnattr.ca_mode = (S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO);
- } else {
- int lockflags;
- cnid_t pid;
- const char *nameptr;
-
- lockflags = hfs_systemfile_lock(hfsmp, SFL_CATALOG, HFS_SHARED_LOCK);
- error = cat_idlookup(hfsmp, cnid, 0, 0, &cndesc, &cnattr, &cnfork);
- hfs_systemfile_unlock(hfsmp, lockflags);
-
- if (error) {
- return (error);
- }
-
- /*
- * Check for a raw hardlink inode and save its linkref.
- */
- pid = cndesc.cd_parentcnid;
- nameptr = (const char *)cndesc.cd_nameptr;
- if ((pid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid) &&
- cndesc.cd_namelen > HFS_INODE_PREFIX_LEN &&
- (bcmp(nameptr, HFS_INODE_PREFIX, HFS_INODE_PREFIX_LEN) == 0)) {
- linkref = (uint32_t) strtoul(&nameptr[HFS_INODE_PREFIX_LEN], NULL, 10);
-
- } else if ((pid == hfsmp->hfs_private_desc[DIR_HARDLINKS].cd_cnid) &&
- cndesc.cd_namelen > HFS_DIRINODE_PREFIX_LEN &&
- (bcmp(nameptr, HFS_DIRINODE_PREFIX, HFS_DIRINODE_PREFIX_LEN) == 0)) {
- linkref = (uint32_t) strtoul(&nameptr[HFS_DIRINODE_PREFIX_LEN], NULL, 10);
-
- } else if ((pid == hfsmp->hfs_private_desc[FILE_HARDLINKS].cd_cnid) &&
- cndesc.cd_namelen > HFS_DELETE_PREFIX_LEN &&
- (bcmp(nameptr, HFS_DELETE_PREFIX, HFS_DELETE_PREFIX_LEN) == 0)) {
- cat_releasedesc(&cndesc);
- return (ENOENT); /* open unlinked file */
- }
- }
-
- /*
- * Finish initializing cnode descriptor for hardlinks.
- *
- * We need a valid name and parent for reverse lookups.
- */
- if (linkref) {
- cnid_t lastid;
- struct cat_desc linkdesc;
- int linkerr = 0;
-
- cnattr.ca_linkref = linkref;
- bzero (&linkdesc, sizeof (linkdesc));
-
- /*
- * If the caller supplied the raw inode value, then we don't know exactly
- * which hardlink they wanted. It's likely that they acquired the raw inode
- * value BEFORE the item became a hardlink, in which case, they probably
- * want the oldest link. So request the oldest link from the catalog.
- *
- * Unfortunately, this requires that we iterate through all N hardlinks. On the plus
- * side, since we know that we want the last linkID, we can also have this one
- * call give us back the name of the last ID, since it's going to have it in-hand...
- */
- linkerr = hfs_lookup_lastlink (hfsmp, linkref, &lastid, &linkdesc);
- if ((linkerr == 0) && (lastid != 0)) {
- /*
- * Release any lingering buffers attached to our local descriptor.
- * Then copy the name and other business into the cndesc
- */
- cat_releasedesc (&cndesc);
- bcopy (&linkdesc, &cndesc, sizeof(linkdesc));
- }
- /* If it failed, the linkref code will just use whatever it had in-hand below. */
-
- int newvnode_flags = 0;
- error = hfs_getnewvnode(hfsmp, NULL, NULL, &cndesc, 0, &cnattr, &cnfork, &psVnode, &newvnode_flags);
- if (error == 0) {
- VTOC(psVnode)->c_flag |= C_HARDLINK;
- }
- }
- else
- {
- int newvnode_flags = 0;
-
- void *buf = hfs_malloc(MAX_UTF8_NAME_LENGTH);
- if (buf == NULL) {
- return (ENOMEM);
- }
-
- /* Supply hfs_getnewvnode with a component name. */
- struct componentname cn = {
- .cn_nameiop = LOOKUP,
- .cn_flags = ISLASTCN,
- .cn_pnlen = MAXPATHLEN,
- .cn_namelen = cndesc.cd_namelen,
- .cn_pnbuf = buf,
- .cn_nameptr = buf
- };
-
- bcopy(cndesc.cd_nameptr, cn.cn_nameptr, cndesc.cd_namelen + 1);
- error = hfs_getnewvnode(hfsmp, NULL, &cn, &cndesc, 0, &cnattr, &cnfork, &psVnode, &newvnode_flags);
- if (error == 0 && (VTOC(psVnode)->c_flag & C_HARDLINK)) {
- hfs_savelinkorigin(VTOC(psVnode), cndesc.cd_parentcnid);
- }
-
- hfs_free(buf);
- }
- cat_releasedesc(&cndesc);
-
-getAttrAndDone:
- if (!error) vnode_GetAttrInternal (psVnode, file_attrs);
- if (psVnode != NULL) hfs_unlock(VTOC(psVnode));
-
- if (error || psVnode == NULL || psVnode->sFSParams.vnfs_cnp->cn_nameptr == NULL){
- hfs_vnop_reclaim(psVnode);
- return EFAULT;
- }
-
- if (cnid == kHFSRootFolderID)
- pcName[0] = 0;
- else {
- strlcpy(pcName, (char*) psVnode->sFSParams.vnfs_cnp->cn_nameptr, MAX_UTF8_NAME_LENGTH);
- }
-
- error = hfs_vnop_reclaim(psVnode);
-
- return (error);
-}
-
/*
* Look up an HFS object by ID.
*
return (error);
}
+int
+hfs_GetInfoByID(struct hfsmount *hfsmp, cnid_t cnid, UVFSFileAttributes *file_attrs, char pcName[MAX_UTF8_NAME_LENGTH])
+{
+ struct vnode *psVnode = NULL;
+ int error = hfs_vget(hfsmp, cnid, &psVnode, 0, 0);
+ if (error || psVnode == NULL) {
+ if (psVnode != NULL) hfs_unlock(VTOC(psVnode));
+ hfs_vnop_reclaim(psVnode);
+ return EFAULT;
+ } else {
+ vnode_GetAttrInternal (psVnode, file_attrs);
+ hfs_unlock(VTOC(psVnode));
+ }
+
+ if (cnid == kHFSRootFolderID)
+ pcName[0] = 0;
+ else {
+ //Make sure we actually have the name in the vnode
+ if (psVnode->sFSParams.vnfs_cnp && psVnode->sFSParams.vnfs_cnp->cn_nameptr)
+ strlcpy(pcName, (char*) psVnode->sFSParams.vnfs_cnp->cn_nameptr, MAX_UTF8_NAME_LENGTH);
+ else
+ return EINVAL;
+ }
+
+ error = hfs_vnop_reclaim(psVnode);
+ return (error);
+}
+
/*
* Return the root of a filesystem.
*/
LFHFS_LOG(LEVEL_ERROR, "vnode_update_identity: failed to malloc vnfs_cnp\n");
assert(0);
}
+ bzero(vp->sFSParams.vnfs_cnp, sizeof(struct componentname));
}
vp->sFSParams.vnfs_cnp->cn_namelen = name_len;
if (vp->sFSParams.vnfs_cnp->cn_nameptr) {
hfs_free(vp->sFSParams.vnfs_cnp->cn_nameptr);
+ vp->sFSParams.vnfs_cnp->cn_nameptr = NULL;
}
vp->sFSParams.vnfs_cnp->cn_nameptr = lf_hfs_utils_allocate_and_copy_string( (char*) name, name_len );
vp->sFSParams.vnfs_cnp->cn_hash = name_hashval;
BTreeIterator * iterator = NULL;
size_t attrsize = 0;
HFSPlusAttrRecord *recp = NULL;
- size_t recp_size = 0;
FSBufferDescriptor btdata;
int lockflags = 0;
u_int16_t datasize = 0;
* big enough to read in all types of attribute records. It is not big
* enough to read inline attribute data which is read in later.
*/
- recp = hfs_malloc(recp_size = sizeof(HFSPlusAttrRecord));
+ recp = hfs_malloc(sizeof(HFSPlusAttrRecord));
btdata.bufferAddress = recp;
btdata.itemSize = sizeof(HFSPlusAttrRecord);
btdata.itemCount = 1;
*/
attrsize = sizeof(HFSPlusAttrData) - 2 + recp->attrData.attrSize;
hfs_free(recp);
- recp = hfs_malloc(recp_size = attrsize);
+ recp = hfs_malloc(attrsize);
btdata.bufferAddress = recp;
btdata.itemSize = attrsize;
FSBufferDescriptor btdata;
HFSPlusAttrRecord attrdata; /* 90 bytes */
HFSPlusAttrRecord *recp = NULL;
- size_t recp_size = 0;
HFSPlusExtentDescriptor *extentptr = NULL;
size_t extentbufsize = 0;
int lockflags = 0;
}
}
/* Create attribute fork data record. */
- recp = hfs_malloc(recp_size = sizeof(HFSPlusAttrRecord));
+ recp = hfs_malloc(sizeof(HFSPlusAttrRecord));
btdata.bufferAddress = recp;
btdata.itemCount = 1;
/* Calculate size of record rounded up to multiple of 2 bytes. */
btdata.itemSize = sizeof(HFSPlusAttrData) - 2 + attrsize + ((attrsize & 1) ? 1 : 0);
- recp = hfs_malloc(recp_size = btdata.itemSize);
+ recp = hfs_malloc(btdata.itemSize);
recp->recordType = kHFSPlusAttrInlineData;
recp->attrData.reserved[0] = 0;
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
+#include <assert.h>
#include <ctype.h>
#include <err.h>
if (result) return;
gmtCreateTime = attrReturnBuffer.creationTime.tv_sec;
- gmtOffset = gmtCreateTime - (int64_t) localCreateTime + 900;
+ gmtOffset = (int32_t)(gmtCreateTime - (int64_t) localCreateTime + 900);
if (gmtOffset > 0) {
gmtOffset = 1800 * (gmtOffset / 1800);
} else {
done = 0;
rv = -1;
if (*s >= '0' && *s <= '7') {
+ long mask;
+
done = 1;
- rv = strtol(optarg, &ep, 8);
+ mask = strtol(optarg, &ep, 8);
+ if (mask >= 0 && mask <= INT_MAX)
+ rv = (int)mask;
}
if (!done || rv < 0 || *ep)
errx(1, "invalid file mode: %s", s);
if ((fd = open(buffer, O_RDONLY, 0)) > 0) {
ssize_t readSize;
+ long encoding;
readSize = read(fd, buffer, MAXPATHLEN);
buffer[(readSize < 0 ? 0 : readSize)] = '\0';
close(fd);
- return strtol(buffer, NULL, 0);
+ encoding = strtol(buffer, NULL, 0);
+ assert(encoding > -1 && encoding <= UINT_MAX);
+ return (unsigned int)encoding;
}
}
return (0); /* Fallback to smRoman */
*/
if ((blockStep * numExtents) < blocksLeft) {
// Need to adjust the first one.
- firstAdjust = blocksLeft - (blockStep * numExtents);
+ firstAdjust = (int)(blocksLeft - (blockStep * numExtents));
if ((firstAdjust % minBlocks) != 0)
firstAdjust = ROUNDUP(firstAdjust, minBlocks);
}
bzero(hp, kBytesPerSector);
blockSize = defaults->blockSize;
- blockCount = sectors / (blockSize >> kLog2SectorSize);
+ blockCount = (UInt32)(sectors / (blockSize >> kLog2SectorSize));
/*
* HFSPlusVolumeHeader is located at sector 2, so we may need
memset(buf, 0, sizeof(buf));
secNum = curBlock / (bufSize * kBitsPerByte);
blockOffset = curBlock % (bufSize * kBitsPerByte);
- numBlocks = MIN((bufSize * kBitsPerByte) - blockOffset, blocksLeft);
+ numBlocks = (uint32_t)MIN((bufSize * kBitsPerByte) - blockOffset, blocksLeft);
/*
* Okay, now we've got the block number to read,
/* try a buffer size for optimal IO, __UP TO 4MB__. if that
fails, then try with the minimum allowed buffer size, which
is equal to physSectorSize */
- tempbufSizeInPhysSectors = MIN ( (byteCount - 1 + physSectorSize) / physSectorSize,
+ tempbufSizeInPhysSectors = (UInt32)MIN ( (byteCount - 1 + physSectorSize) / physSectorSize,
driveInfo->physSectorsPerIO );
/* limit at 4MB */
tempbufSizeInPhysSectors = MIN ( tempbufSizeInPhysSectors, (4 * 1024 * 1024) / physSectorSize );
byteOffsetInPhysSector = (sector % sectorSizeRatio) * kBytesPerSector;
while (byteCount > 0) {
- numPhysSectorsToIO = MIN ( (byteCount - 1 + physSectorSize) / physSectorSize,
+ numPhysSectorsToIO = (UInt32)MIN ( (byteCount - 1 + physSectorSize) / physSectorSize,
tempbufSizeInPhysSectors );
- numBytesToIO = MIN(byteCount, (unsigned)((numPhysSectorsToIO * physSectorSize) - byteOffsetInPhysSector));
+ numBytesToIO = (UInt32)MIN(byteCount, (unsigned)((numPhysSectorsToIO * physSectorSize) - byteOffsetInPhysSector));
/* if IO does not align with physical sector boundaries */
if ((0 != byteOffsetInPhysSector) || ((numBytesToIO % physSectorSize) != 0)) {
fatal("%s: bad allocation block size (too small)", optarg);
if (tempBlockSize > HFSMAXBSIZE)
fatal("%s: bad allocation block size (too large)", optarg);
- gBlockSize = tempBlockSize;
+ gBlockSize = (uint32_t)tempBlockSize;
break;
}
char *ndarg;
char *p;
unsigned long startat = 0;
+ int pos;
+ UInt32 upos;
startat = strtoul(optlist, &strp, 0);
if (startat == ULONG_MAX && errno != 0) {
if (strp && *strp == ',')
strp++;
- gFSStartBlock = startat;
+ gFSStartBlock = (UInt32)startat;
while((ndarg = strsep(&strp, ",")) != NULL && *ndarg != '\0') {
if (p == NULL)
usage();
- startat = atoi(p+1);
-
+ pos = atoi(p+1);
+ if (pos < 0 || pos > UINT32_MAX) {
+ errx(1, "pos=%d is invalid", pos);
+ }
+ upos = (UInt32)pos;
+
switch (*ndarg) {
case 'a':
- attrExtStart = startat;
+ attrExtStart = upos;
break;
case 'b':
- blkallocExtStart = startat;
+ blkallocExtStart = upos;
break;
case 'c':
- catExtStart = startat;
+ catExtStart = upos;
break;
case 'e':
- extExtStart = startat;
+ extExtStart = upos;
break;
case 'j':
- jibStart = startat;
+ jibStart = upos;
break;
case 'J':
- jnlStart = startat;
+ jnlStart = upos;
break;
case 'N':
- allocStart = startat;
+ allocStart = upos;
break;
default:
usage();
static mode_t
a_mask(char *s)
{
- int done, rv;
+ int done;
+ long rv;
char *ep;
done = 0;
done = 1;
rv = strtol(s, &ep, 8);
}
- if (!done || rv < 0 || *ep)
+ if (!done || rv < 0 || rv > INT_MAX || *ep)
errx(1, "invalid access mask: %s", s);
- return (rv);
+ return ((int)rv);
}
/*
* value. At 2TB, we grow to the 8K block size.
*/
if ((bit_index >= 0) && (bit_index < 22)) {
- gBlockSize = alloc_blocksize[bit_index];
+ gBlockSize = (uint32_t)alloc_blocksize[bit_index];
}
if (bit_index >= 22) {
if (gFSStartBlock) {
u_int64_t fs_size = sectorCount * sectorSize;
- u_int32_t totalBlocks = fs_size/gBlockSize;
+ u_int32_t totalBlocks = (u_int32_t)(fs_size/gBlockSize);
if (gFSStartBlock >= totalBlocks) {
warnx("Warning: %u is invalid file system start allocation block number, must be less than total allocation blocks (%u)", (unsigned int)gFSStartBlock, (unsigned int)totalBlocks);
defaults->blockSize = gBlockSize;
defaults->fsStartBlock = gFSStartBlock;
defaults->nextFreeFileID = gNextCNID;
- defaults->createDate = createtime + MAC_GMT_FACTOR; /* Mac OS GMT time */
+ // Value will be bigger than UIN32_MAX in 2040
+ defaults->createDate = (uint32_t)(createtime + MAC_GMT_FACTOR); /* Mac OS GMT time */
defaults->hfsAlignment = 0;
defaults->journaledHFS = gJournaled;
defaults->journalDevice = gJournalDevice;
}
/* defaults->journalSize will get reset below if it is 0 */
- defaults->journalSize = gJournalSize;
+ defaults->journalSize = (uint32_t)gJournalSize;
}
if ((gJournalSize == 0) || (defaults->journalSize == 0)) {
* Note: this minimum value may be too large when it counts the
* space used by the wrapper
*/
- totalBlocks = sectorCount / (gBlockSize / sectorSize);
+ totalBlocks = (uint32_t)(sectorCount / (gBlockSize / sectorSize));
minClumpSize = totalBlocks >> 3; /* convert bits to bytes by dividing by 8 */
if (totalBlocks & 7)
* it must also be a multiple of the node and block size.
*/
if (sectors < 0x200000) {
- clumpSize = sectors << 2; /* 0.8 % */
+ clumpSize = (UInt32)(sectors << 2); /* 0.8 % */
if (clumpSize < (8 * nodeSize))
clumpSize = 8 * nodeSize;
} else {
#include "../core/hfs_format.h"
#include "test-utils.h"
-#define DISK_IMAGE_1 "/tmp/external-jnl1.sparseimage"
-#define DISK_IMAGE_2 "/tmp/external-jnl2.sparseimage"
+#define HOST_IMAGE "/tmp/external-jnl1.sparseimage"
+#define EXTERNAL_IMAGE "/tmp/external-jnl2.sparseimage"
TEST(external_jnl)
int run_external_jnl(__unused test_ctx_t *ctx)
{
- unlink(DISK_IMAGE_1);
- unlink(DISK_IMAGE_2);
-
- disk_image_t *di1 = disk_image_create(DISK_IMAGE_1,
- &(disk_image_opts_t){
- .size = 64 * 1024 * 1024
- });
- disk_image_t *di2
- = disk_image_create(DISK_IMAGE_2,
+ unlink(HOST_IMAGE);
+ unlink(EXTERNAL_IMAGE);
+
+ /* Since disk image cleanup occurs on a stack, create the external
+ * journal partition first so that the cleanup of the host image
+ * prevents a resource busy error during the journal partition ejection.
+ */
+ disk_image_t *di_ext = disk_image_create(EXTERNAL_IMAGE,
&(disk_image_opts_t){
.partition_type = EXTJNL_CONTENT_TYPE_UUID,
.size = 8 * 1024 * 1024
});
- unmount(di1->mount_point, 0);
+ disk_image_t *di_host = disk_image_create(HOST_IMAGE,
+ &(disk_image_opts_t){
+ .size = 64 * 1024 * 1024
+ });
+
+ unmount(di_host->mount_point, 0);
- assert(!systemx("/sbin/newfs_hfs", SYSTEMX_QUIET, "-J", "-D", di2->disk, di1->disk, NULL));
+ assert(!systemx("/sbin/newfs_hfs", SYSTEMX_QUIET, "-J", "-D", di_ext->disk, di_host->disk, NULL));
- assert(!systemx("/usr/sbin/diskutil", SYSTEMX_QUIET, "mount", di1->disk, NULL));
+ assert(!systemx("/usr/sbin/diskutil", SYSTEMX_QUIET, "mount", di_host->disk, NULL));
- free((char *)di1->mount_point);
- di1->mount_point = NULL;
+ free((char *)di_host->mount_point);
+ di_host->mount_point = NULL;
struct statfs *mntbuf;
int i, n = getmntinfo(&mntbuf, 0);
for (i = 0; i < n; ++i) {
- if (!strcmp(mntbuf[i].f_mntfromname, di1->disk)) {
- di1->mount_point = strdup(mntbuf[i].f_mntonname);
+ if (!strcmp(mntbuf[i].f_mntfromname, di_host->disk)) {
+ di_host->mount_point = strdup(mntbuf[i].f_mntonname);
break;
}
}
assert(i < n);
char *path;
- asprintf(&path, "%s/test", di1->mount_point);
+ asprintf(&path, "%s/test", di_host->mount_point);
int fd = open(path, O_RDWR | O_CREAT, 0666);
assert_with_errno(fd >= 0);
assert_no_err(close(fd));
assert_no_err(msync(p + total - round, todo + round,
MS_ASYNC | MS_INVALIDATE));
- CC_MD5_Update(&md5_ctx, buf1, todo);
+ CC_MD5_Update(&md5_ctx, buf1, (CC_LONG)todo);
total += todo;
}
struct statfs sfs;
assert_no_err(fstatfs(*fd, &sfs));
- uint32_t blocks = sfs.f_bfree;
+ uint64_t blocks = sfs.f_bfree;
for (;;) {
- uint64_t size = (uint64_t)blocks * sfs.f_bsize;
+ uint64_t size = blocks * sfs.f_bsize;
if (!fcntl(*fd, F_SETSIZE, &size))
break;
}
// Now increase the size until we hit no space
- uint32_t upper = sfs.f_bfree + 128;
+ uint64_t upper = sfs.f_bfree + 128;
for (;;) {
- uint32_t try = (upper + blocks) / 2;
+ uint64_t try = (upper + blocks) / 2;
if (try <= blocks)
try = blocks + 1;
- uint64_t size = (uint64_t)try * sfs.f_bsize;
+ uint64_t size = try * sfs.f_bsize;
if (!fcntl(*fd, F_SETSIZE, &size)) {
blocks = try;
if (try >= upper) {
}
}
- *size = (uint64_t)blocks * sfs.f_bsize;
+ *size = blocks * sfs.f_bsize;
}
volatile int32_t threads_running;
--- /dev/null
+//
+// Copyright (c) 2019-2019 Apple Inc. All rights reserved.
+//
+// test-lf-cs-plugin.c - Implements unit test for livefiles Apple_CoreStorage
+// plugin.
+//
+
+#include "hfs-tests.h"
+#include "test-utils.h"
+#include "systemx.h"
+
+#include <fcntl.h>
+#include <spawn.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <zlib.h>
+#include <TargetConditionals.h>
+
+//
+// Enable this test on iOS and no other iOS-style platforms.
+//
+#if TARGET_OS_IOS
+
+//
+// Headers generated at build time. Containes compressed disk images for the
+// corresponding file-system formats.
+//
+#include "JHFS+-dmg.dat"
+#include "APFS-dmg.dat"
+#include "EXFAT-dmg.dat"
+#include "FAT32-dmg.dat"
+
+TEST(lf_cs_plugin, .run_as_root = true)
+
+#define LF_CS_PLUGIN_TEST_DMG "/tmp/lf_cs_plugin_test.sparseimage"
+#define LF_CS_PLUGIN_PATH_TO_HDIK "/usr/sbin/hdik"
+#define LF_CS_PLUGIN_INSTALL_PATH "/AppleInternal/CoreOS/tests/hfs/"
+
+//
+// The output of hdik gets truncated, so just search for the leading part of
+// the UUID and partition scheme names.
+//
+#define LF_CSP_HFS_UUID "48465300-0000-11AA-AA11"
+#define LF_CSP_APFS_UUID "7C3457EF-0000-11AA-AA11"
+#define LF_CSP_EXFAT_PART_SCHEME "Windows_NTFS"
+#define LF_CSP_FAT32_PART_SCHEME "DOS_FAT_32"
+
+//
+// Enums describing file-system formats.
+//
+typedef enum {
+ JHFS = 1,
+ APFS,
+ FAT32,
+ EXFAT,
+} lf_csp_fstype_t;
+
+//
+// Local struct describing the disk image on disk.
+//
+typedef struct {
+ char *path; // Path to disk-image on disk.
+ char *disk; // Path to dev node after disk-image is attached.
+ char *slice; // Path to dev node slice after disk-image is attached.
+} lf_csp_disk_image_t;
+
+//
+// lf_csp_disk_image_cleanup - disattach disk image from the DiskImages driver
+// and unlink the disk image file on disk.
+//
+static bool
+lf_csp_disk_image_cleanup(lf_csp_disk_image_t *di)
+{
+ pid_t pid;
+ posix_spawn_file_actions_t facts;
+
+ struct stat sb;
+ int ret, status;
+ bool result;
+ char *detach_args[] = { "hdik", "-e", (char *)di->disk, NULL };
+
+ result = false;
+ ret = posix_spawn_file_actions_init(&facts);
+
+ if (!ret) {
+ (void)posix_spawn_file_actions_addopen(&facts, STDOUT_FILENO,
+ "/dev/null", O_APPEND, 0);
+ (void)posix_spawn_file_actions_addopen(&facts, STDERR_FILENO,
+ "/dev/null", O_APPEND, 0);
+ }
+
+ assert_no_err(posix_spawn(&pid, LF_CS_PLUGIN_PATH_TO_HDIK, &facts,
+ NULL, detach_args, NULL));
+
+ if (ret) {
+ posix_spawn_file_actions_destroy(&facts);
+ }
+
+ assert_with_errno(ignore_eintr(waitpid(pid, &status, 0), -1) == pid);
+ errno = 0;
+ if (WIFEXITED(status) &&
+ !WEXITSTATUS(status) &&
+ (stat(di->disk, &sb) == -1) &&
+ (errno == ENOENT)) {
+
+ unlink(di->path);
+ free(di->path);
+ free(di->disk);
+ free(di->slice);
+ free(di);
+ result = true;
+ }
+
+ return result;
+}
+
+//
+// lf_csp_disk_image_create - create a new disk image file on disk and attach
+// disk images directly to the DiskImages driver.
+//
+// This routine reads the compressed file system image (generated during build)
+// based on the passed file-system type parameter. The compressed image is
+// decompressd and written to disk and then attached to directly to the
+// DiskImages driver.
+//
+// Please NOTE: The created image is hooked up to the test cleanup list thus
+// gets cleaned up automatically after the test, even on failures. Explicit
+// cleanup is not needed.
+//
+static lf_csp_disk_image_t *
+lf_csp_disk_image_create(const char *path, lf_csp_fstype_t fs_type)
+{
+ pid_t pid;
+ uid_t uid_old;
+ lf_csp_disk_image_t *di;
+ z_stream u_stream;
+ posix_spawn_file_actions_t actions;
+
+ FILE *fp;
+ size_t lnsz;
+ int ret, fd, fds[2], status;
+ void *uncompressed_out_buf;
+ const size_t chunk_size = (1ULL << 20);
+ char *attach_args[4], *line, *part_scheme, *uuid_or_partid_str;
+
+ //
+ // We need to ensure that we are root.
+ //
+ if ((uid_old = geteuid()) != 0) {
+ assert_no_err(seteuid(0));
+ }
+
+ di = calloc(1, sizeof(lf_csp_disk_image_t));
+ assert(di);
+
+ //
+ // We need to extract the compressed image into the passed image
+ // file path, thus we open it for writing.
+ //
+ fd = open(path, O_RDWR | O_TRUNC | O_CREAT, 0666);
+ assert_with_errno(fd != -1);
+
+ u_stream = (z_stream) {
+ .zalloc = Z_NULL,
+ .zfree = Z_NULL,
+ .opaque = Z_NULL,
+ };
+
+ ret = inflateInit(&u_stream);
+ if (ret != Z_OK) {
+ assert_fail("inflateInit failed\n");
+ }
+
+ uncompressed_out_buf = malloc(chunk_size);
+ assert(uncompressed_out_buf);
+
+ uuid_or_partid_str = NULL;
+ part_scheme = NULL;
+ switch(fs_type) {
+ case JHFS:
+ u_stream.next_in = JHFS_data;
+ u_stream.avail_in = sizeof(JHFS_data);
+ uuid_or_partid_str = LF_CSP_HFS_UUID;
+ part_scheme = "GUID";
+ break;
+
+ case APFS:
+ u_stream.next_in = APFS_data;
+ u_stream.avail_in = sizeof(APFS_data);
+ uuid_or_partid_str = LF_CSP_APFS_UUID;
+ part_scheme = "GUID";
+ break;
+
+ case FAT32:
+ u_stream.next_in = FAT32_data;
+ u_stream.avail_in = sizeof(FAT32_data);
+ uuid_or_partid_str = LF_CSP_FAT32_PART_SCHEME;
+ part_scheme = "FDisk";
+ break;
+
+ case EXFAT:
+ u_stream.next_in = EXFAT_data;
+ u_stream.avail_in = sizeof(EXFAT_data);
+ uuid_or_partid_str = LF_CSP_EXFAT_PART_SCHEME;
+ part_scheme = "FDisk";
+ break;
+
+ default:
+ assert_fail("passed unkown file-system type\n");
+ }
+
+ do {
+ ssize_t bytes_to_write;
+
+ u_stream.next_out = uncompressed_out_buf;
+ u_stream.avail_out = chunk_size;
+
+ ret = inflate(&u_stream, Z_NO_FLUSH);
+ assert(ret != Z_STREAM_ERROR);
+
+ bytes_to_write = chunk_size - u_stream.avail_out;
+ assert(write(fd, uncompressed_out_buf, bytes_to_write) ==
+ (ssize_t)bytes_to_write);
+ } while (ret == Z_OK);
+ assert(ret == Z_STREAM_END);
+ (void)inflateEnd(&u_stream);
+
+ //
+ // Update the disk image path.
+ //
+ di->path = strdup(path);
+
+ //
+ // Attach the created disk image directly to the DiskImage driver.
+ //
+ attach_args[0] = "hdik";
+ attach_args[1] = "-nomount";
+ attach_args[2] = (char *)di->path;
+ attach_args[3] = NULL;
+
+ assert_no_err(pipe(fds));
+ ret = posix_spawn_file_actions_init(&actions);
+ if (ret) {
+ assert_fail("Failed to init file actions, error %d\n", ret);
+ }
+
+ ret = posix_spawn_file_actions_adddup2(&actions, fds[1],
+ STDOUT_FILENO);
+ if (ret) {
+ assert_fail("Failed to adddup file action, error %d\n",
+ ret);
+ }
+
+ assert_no_err(posix_spawn(&pid, LF_CS_PLUGIN_PATH_TO_HDIK, &actions,
+ NULL, attach_args, NULL));
+
+ (void)posix_spawn_file_actions_destroy(&actions);
+ (void)close(fds[1]);
+
+ //
+ // Read the output from `hdik` and populate the disk image's dev node
+ // after it is attached to DiskImage driver.
+ //
+ di->slice = NULL;
+ di->disk = NULL;
+ line = NULL;
+ lnsz = 64;
+ line = malloc(lnsz);
+ assert(line);
+ fp = fdopen(fds[0], "r");
+ while (getline(&line, &lnsz, fp) != -1) {
+ char *disk_path, *uuid_or_partid;
+
+ disk_path = strtok(line, " ");
+ assert(disk_path);
+
+ uuid_or_partid = strtok(NULL, " ");
+ assert(uuid_or_partid);
+
+ if (strstr(uuid_or_partid, part_scheme))
+ di->disk = strdup(disk_path);
+ else if (strstr(uuid_or_partid, uuid_or_partid_str))
+ di->slice = strdup(disk_path);
+ }
+
+ assert_with_errno(ignore_eintr(waitpid(pid, &status, 0), -1) == pid);
+ assert(WIFEXITED(status) && !WEXITSTATUS(status));
+
+ assert(di->disk && di->slice);
+ free(line);
+ fclose(fp);
+
+ //
+ // Place this attached image in the cleanup list so that it can be
+ // disattached after the test is run.
+ //
+ test_cleanup(^ bool { return lf_csp_disk_image_cleanup(di); });
+
+ //
+ // Restore back the old uid.
+ //
+ assert_no_err(seteuid(uid_old));
+ return di;
+}
+
+int
+run_lf_cs_plugin(__unused test_ctx_t *ctx)
+{
+ lf_csp_disk_image_t *di;
+ char *tester_path;
+
+ assert(asprintf(&tester_path, "%s/livefiles_cs_tester",
+ LF_CS_PLUGIN_INSTALL_PATH) > 0);
+
+ //
+ // Call livefiles Apple_CoreStorage plugin with all our file-system
+ // disk-images.
+ //
+ // Kindly NOTE: We don't explicitly free the disk-images after use
+ // because preparing the disk image with lf_csp_disk_image_create() we
+ // place the image in a cleanup list and they get cleaned up after
+ // test, regardless of the test failures.
+ //
+ // Test livefiles Apple_CoreStorage plugin with AFPS disk image.
+ //
+ di = lf_csp_disk_image_create(LF_CS_PLUGIN_TEST_DMG, APFS);
+ assert(!systemx(tester_path, "APFS", di->slice, NULL));
+
+ //
+ // Test livefiles Apple_CoreStorage plugin with HFS+ disk image.
+ //
+ di = lf_csp_disk_image_create(LF_CS_PLUGIN_TEST_DMG, JHFS);
+ assert(!systemx(tester_path, "JHFS", di->slice, NULL));
+
+ //
+ // Test livefiles Apple_CoreStorage plugin with EXFAT disk image.
+ //
+ di = lf_csp_disk_image_create(LF_CS_PLUGIN_TEST_DMG, EXFAT);
+ assert(!systemx(tester_path, "EXFAT", di->slice, NULL));
+
+ //
+ // Test livefiles Apple_CoreStorage plugin with FAT32 disk image.
+ //
+ di = lf_csp_disk_image_create(LF_CS_PLUGIN_TEST_DMG, FAT32);
+ assert(!systemx(tester_path, "FAT32", di->slice, NULL));
+
+ free(tester_path);
+ return 0;
+}
+#endif /* TARGET_OS_IOS */
#include "test-utils.h"
#include "systemx.h"
+#define RETRY_MAX 3
+
#if (TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR)
#include "dmg.dat"
{
pid_t pid;
bool result = false;
+ int eject_retry;
+ int status;
// We need to be root
assert(seteuid(0) == 0);
assert_no_err(posix_spawn(&pid, "/sbin/umount", NULL, NULL, umount_args, NULL));
- int status;
waitpid(pid, &status, 0);
char *detach_args[]
= { "hdik", "-e", (char *)di->disk, NULL };
-
+
posix_spawn_file_actions_t facts;
posix_spawn_file_actions_init(&facts);
posix_spawn_file_actions_addopen(&facts, STDOUT_FILENO, "/dev/null", O_APPEND, 0);
posix_spawn_file_actions_addopen(&facts, STDERR_FILENO, "/dev/null", O_APPEND, 0);
- assert_no_err(posix_spawn(&pid, "/usr/sbin/hdik", &facts, NULL, detach_args, NULL));
+ for (eject_retry = 0; eject_retry < RETRY_MAX; ++eject_retry) {
+ if (!posix_spawn(&pid, "/usr/sbin/hdik", &facts, NULL, detach_args, NULL)) {
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status) && !WEXITSTATUS(status))
+ break;
+ }
+ sleep(1);
+ }
posix_spawn_file_actions_destroy(&facts);
- waitpid(pid, &status, 0);
+ assert(eject_retry != RETRY_MAX);
struct stat sb;
- if (WIFEXITED(status) && !WEXITSTATUS(status)
- && stat(di->disk, &sb) == -1 && errno == ENOENT) {
+ if (stat(di->disk, &sb) == -1 && errno == ENOENT) {
unlink(di->path);
result = true;
// We are the last user of di, so free it.
do {
zs.next_out = out_buf;
- zs.avail_out = buf_size;
+ zs.avail_out = (uInt)buf_size;
ret = inflate(&zs, 0);
pid_t pid;
bool result = false;
+ int eject_retry;
+ int status;
posix_spawn_file_actions_t facts;
posix_spawn_file_actions_init(&facts);
posix_spawn_file_actions_addopen(&facts, STDOUT_FILENO, "/dev/null", O_APPEND, 0);
posix_spawn_file_actions_addopen(&facts, STDERR_FILENO, "/dev/null", O_APPEND, 0);
- assert_no_err(posix_spawn(&pid, "/usr/bin/hdiutil", &facts, NULL, detach_args, NULL));
+ for (eject_retry = 0; eject_retry < RETRY_MAX; ++eject_retry) {
+ if (!posix_spawn(&pid, "/usr/bin/hdiutil", &facts, NULL, detach_args, NULL)) {
+ waitpid(pid, &status, 0);
+ if (WIFEXITED(status) && !WEXITSTATUS(status)) {
+ break;
+ }
+ }
+ sleep(1);
+ }
posix_spawn_file_actions_destroy(&facts);
- int status;
- waitpid(pid, &status, 0);
+ assert(eject_retry != RETRY_MAX);
struct stat sb;
- if (WIFEXITED(status) && !WEXITSTATUS(status)
- && stat(di->disk, &sb) == -1 && errno == ENOENT) {
+ if (stat(di->disk, &sb) == -1 && errno == ENOENT) {
if (unlink(di->path) && errno == EACCES && !seteuid(0))
unlink(di->path);
result = true;
--- /dev/null
+#!/bin/sh
+set -e
+
+mkdir -p "$DERIVED_FILE_DIR"
+env -i xcrun -sdk macosx.internal clang "$SRCROOT"/tests/generate-compressed-image.c -lz -o "$DERIVED_FILE_DIR"/generate-compressed-image
+
+"$DERIVED_FILE_DIR"/generate-compressed-image -size 1g -type SPARSE -fs "$1" -uid 501 -gid 501 >"$2"
+
+echo "Created $2 of type $1"
set -e
set -o pipefail
+for FS in JHFS+ APFS FAT32 EXFAT; do
+ touch "$DERIVED_SOURCES_DIR/$FS-dmg.dat"
+done
+
# The following change is taken directly from the XCBuild changes made for APFS in
# the commit cf61eef74b8
if [ "$CURRENT_ARCH" = undefined_arch ]; then
# filter out any that aren't applicable to the targeted
# platform). Finally grep for the TEST macro again
grep -l -E '^TEST\(' *.[cm] | xargs xcrun clang -E -D TEST=TEST \
- -arch "$CURRENT_ARCH" -I.. -F"$SDKROOT""$SYSTEM_LIBRARY_DIR"/PrivateFrameworks | \
+ -arch "$CURRENT_ARCH" -I"$DERIVED_SOURCES_DIR" -I.. -F"$SDKROOT""$SYSTEM_LIBRARY_DIR"/PrivateFrameworks | \
grep -h -E 'TEST\(' >>"$DERIVED_FILE_DIR"/list-tests.c
# Build an executable for the host platform
--- /dev/null
+//
+// Copyright (c) 2019-2019 Apple Inc. All rights reserved.
+//
+// generate-compressed-image.c - Generates compressed disk images for
+// file-system type passed as argument.
+//
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <spawn.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <sysexits.h>
+#include <err.h>
+#include <errno.h>
+#include <unistd.h>
+#include <zlib.h>
+
+//
+// Rationale: We don't have `hdiutil` in iOS runtime and thus cannot generate
+// disk-images for test inside iOS. We assume that the build enviornment has
+// `hdiutil` and thus generate custom file-system images (passed as argument)
+// during build, compress it using deflate and finally use the compressed byte
+// stream to generate files which can then be be used from iOS runtime.
+//
+
+//
+// Name template for the temporary directory where we create the file-system
+// image before we can compress it.
+//
+#define GEN_COM_IMAGE_TMP_DIR "/tmp/generate_compressed_image.XXXXXXXX"
+
+//
+// Name of the temporary file-system image.
+//
+#define GEN_COM_IMAGE_TMP_FILENAME "img.sparseimage"
+
+//
+// Path to hdiutil utility inside build enviornment.
+//
+#define GEN_COM_IMAGE_HDIUTIL_PATH "/usr/bin/hdiutil"
+
+enum {
+
+ //
+ // Count of fixed number of argumets needed to call hdiutil, additional
+ // options are passed by the caller.
+ //
+ FIXED_NR_ARGUMENTS = 4,
+ ADDITIONAL_NR_ARGUMENTS = 10,
+ BYTES_PER_LINE_MASK = 0xF,
+};
+
+//
+// Valid file-system types that is supported by this program.
+//
+static bool
+is_fstype_valid(const char *fs_type)
+{
+ int idx;
+
+ const char *const VALID_FSTYPES[] = {
+ "JHFS+",
+ "APFS",
+ "EXFAT",
+ "FAT32",
+
+ NULL
+ };
+
+ for (idx = 0; VALID_FSTYPES[idx] != NULL; idx++) {
+ if (strcmp(fs_type, VALID_FSTYPES[idx]) == 0) {
+ return true;
+ }
+ }
+ return false;
+}
+
+int
+main(int argc, char *argv[])
+{
+ pid_t pid, child_state_changed;
+ z_stream c_stream;
+ int fd, idx, ret, status, flush, offset;
+ char *tmp_dir, *tmp_disk_image_path, *fs_type;
+ unsigned char *compressed_out_buf, *uncompressed_in_buf;
+ const size_t chunk_size = (1ULL << 20);
+ char *args[argc + FIXED_NR_ARGUMENTS];
+ char tmp_dir_name_template[] = GEN_COM_IMAGE_TMP_DIR;
+ const char *progname = (progname = strrchr(argv[0], '/')) ?
+ progname+=1 : (progname = argv[0]);
+
+ //
+ // Disable stdout buffering.
+ //
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ //
+ // Validate that we have correct number of arguments passed (minimal,
+ // this is only called from inside build internally).
+ //
+ if (argc != (ADDITIONAL_NR_ARGUMENTS + 1)) {
+
+err_usage:
+ fprintf(stderr, "Usage: %s -size [size-arg] -type "
+ "[type-arg] -fs [APFS|JHFS+|EXFAT|FAT32] "
+ "-uid [uid-arg] -gid [gid-arg]\n", progname);
+ return EXIT_FAILURE;
+ }
+
+ //
+ // Just to simplify this program and to avoid parsing input aruments
+ // we assume that the arguments are passed in order and 7th argument
+ // has the file-system type. We confirm this now.
+ //
+ if (!is_fstype_valid(argv[6])) {
+ fprintf(stderr, "Unknown file-system type %s\n", argv[6]);
+ goto err_usage;
+ }
+ fs_type = argv[6];
+ if (!strcmp(argv[6], "JHFS+")) {
+ fs_type = "JHFS";
+ }
+
+ //
+ // First we create a temporary directory to host our newly created
+ // disk image in the build environment.
+ //
+ tmp_dir = mkdtemp(tmp_dir_name_template);
+ if (!tmp_dir)
+ err(EX_NOINPUT, "mkdtemp failed");
+
+ //
+ // Path where we want to keep our temporary disk image.
+ //
+ asprintf(&tmp_disk_image_path, "%s/"GEN_COM_IMAGE_TMP_FILENAME,
+ tmp_dir);
+
+ //
+ // Set up the fixed command line parameters to be passed to the hdiutil
+ // child process.
+ //
+ // - program name.
+ // - create a new disk-image.
+ // - path of disk-image file to create.
+ // - silent mode.
+ //
+ args[0] = "hdiutil";
+ args[1] = "create";
+ args[2] = tmp_disk_image_path;
+ args[3] = "-quiet";
+
+ //
+ // Copy the additional arguments passed by the caller needed for
+ // hdiutil.
+ //
+ for (idx = 1; idx < argc; ++idx) {
+ args[idx + FIXED_NR_ARGUMENTS - 1] = argv[idx];
+ }
+ args[idx + FIXED_NR_ARGUMENTS - 1] = NULL;
+
+ //
+ // Spawn the hdiutil as a child process and wait for its completion.
+ //
+ ret = posix_spawn(&pid, GEN_COM_IMAGE_HDIUTIL_PATH, NULL, NULL,
+ args, NULL);
+ if (ret) {
+ errno = ret;
+ err(EX_OSERR, "posix_spawn failed");
+ }
+
+ //
+ // Wait for the child process to finish.
+ //
+ do {
+ errno = 0;
+ child_state_changed = waitpid(pid, &status, 0);
+ } while (child_state_changed == -1 && errno == EINTR);
+
+ if (child_state_changed == -1) {
+ err(EX_OSERR, "waitpid failed");
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ fprintf(stderr, "hdiutil failed, status %d", status);
+ exit(EXIT_FAILURE);
+ }
+
+ //
+ // We have successfully create the disk image, now we have to
+ // open this disk image, read and finally write out a compess
+ // stream of this disk image to a data file.
+ //
+ fd = open(tmp_disk_image_path, O_RDONLY);
+ if (fd == -1) {
+ err(EX_NOINPUT, "open failed for file %s",
+ tmp_disk_image_path);
+ }
+
+ //
+ // Initialize the compressed stream of bytes we will write out.
+ //
+ c_stream = (z_stream) {
+ .zalloc = Z_NULL,
+ .zfree = Z_NULL,
+ .opaque = Z_NULL,
+ };
+
+ ret = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+ if (ret != Z_OK) {
+ err(EX_SOFTWARE, "deflateInit faile, ret %d", ret);
+ }
+
+ compressed_out_buf = malloc(chunk_size);
+ if (!compressed_out_buf) {
+ err(EX_OSERR, "malloc faliled for compressed_out_buf");
+ }
+
+ uncompressed_in_buf = malloc(chunk_size);
+ if (!uncompressed_in_buf) {
+ err(EX_OSERR, "malloc faliled for uncompressed_in_buf");
+ }
+
+ fprintf(stdout, "unsigned char %s_data[] = {", fs_type);
+
+ offset = 0;
+ flush = Z_NO_FLUSH;
+ do {
+ ssize_t bytes_read;
+
+ bytes_read = read(fd, uncompressed_in_buf, chunk_size);
+ if (bytes_read == -1) {
+ (void)deflateEnd(&c_stream);
+ err(EX_OSERR, "read failed for file %s\n",
+ tmp_disk_image_path);
+ }
+
+ //
+ // Set the stream's input buffer and number of input bytes
+ // available to be compressed.
+ //
+ c_stream.next_in = uncompressed_in_buf;
+ c_stream.avail_in = bytes_read;
+
+ //
+ // If we have reached the end of the file, we have to flush the
+ // compressed stream.
+ //
+ if (!bytes_read) {
+ flush = Z_FINISH;
+ }
+
+ //
+ // Run deflate() on input until output buffer is not full,
+ // finish compression if all of source has been read in.
+ //
+ do {
+ unsigned written;
+
+ c_stream.avail_out = chunk_size;
+ c_stream.next_out = compressed_out_buf;
+
+ ret = deflate(&c_stream, flush);
+ assert(ret != Z_STREAM_ERROR);
+
+ written = chunk_size - c_stream.avail_out;
+ for (idx = 0; idx < written; ++idx) {
+ if (!(offset & BYTES_PER_LINE_MASK))
+ fprintf(stdout, "\n ");
+ fprintf(stdout, "0x%02x, ",
+ compressed_out_buf[idx]);
+ ++offset;
+ }
+
+ } while (c_stream.avail_out == 0);
+
+ //
+ // All input should be used.
+ //
+ assert(c_stream.avail_in == 0);
+
+ } while (flush != Z_FINISH);
+
+ //
+ // Stream will be complete.
+ //
+ assert(ret == Z_STREAM_END);
+ (void)close(fd);
+
+ //
+ // stdout is line buffered by default and this should flush it.
+ //
+ fprintf(stdout, "\n};\n");
+
+ //
+ // Clean up
+ //
+ (void)deflateEnd(&c_stream);
+ unlink(tmp_disk_image_path);
+ free(tmp_disk_image_path);
+ rmdir(tmp_dir);
+}
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
+ <key>com.apple.private.vfs.setsize</key>
+ <true/>
<key>com.apple.rootless.internal-installer-equivalent</key>
<true/>
<key>com.apple.private.security.disk-device-access</key>