Ejemplo n.º 1
0
static long GetCatalogEntry(long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid)
{
	long              extentSize, nodeSize, curNode, index;
	void              *extent;
	char              *nodeBuf, *testKey, *entry;
	BTNodeDescriptor  *node;

	if (gIsHFSPlus)
	{
		extent     = &gHFSPlus->catalogFile.extents;
		extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
	}
	else
	{
		extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
		extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
	}

	nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
	nodeBuf  = (char *)malloc(nodeSize);
	node     = (BTNodeDescriptor *)nodeBuf;

	index   = (long) (*dirIndex % nodeSize);
	curNode = (long) (*dirIndex / nodeSize);

	// Read the BTree node and get the record for index.
	ReadExtent(extent, extentSize, kHFSCatalogFileID, (long long) curNode * nodeSize, nodeSize, nodeBuf, 1);
	GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);

	GetCatalogEntryInfo(entry, flags, time, finderInfo, infoValid);

	// Get the file name.
	if (gIsHFSPlus)
	{
		utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
                      SWAP_BE16(((HFSPlusCatalogKey *)testKey)->nodeName.length),
                      (u_int8_t *)gTempStr, 256, OSBigEndian);
	}
	else
	{
		strncpy(gTempStr, (const char *)&((HFSCatalogKey *)testKey)->nodeName[1], ((HFSCatalogKey *)testKey)->nodeName[0]);

		gTempStr[((HFSCatalogKey *)testKey)->nodeName[0]] = '\0';
	}
	*name = gTempStr;

	// Update dirIndex.
	index++;

	if (index == SWAP_BE16(node->numRecords))
	{
		index = 0;
		curNode = SWAP_BE32(node->fLink);
	}
	*dirIndex = (long long) curNode * nodeSize + index;

	free(nodeBuf);

	return 0;
}
Ejemplo n.º 2
0
static long CompareHFSPlusCatalogKeys(void * key, void * testKey)
{
    HFSPlusCatalogKey *searchKey, *trialKey;
    long              result, searchParentID, trialParentID;
  
    searchKey = key;
    trialKey  = testKey;
  
    searchParentID = SWAP_BE32(searchKey->parentID);
    trialParentID  = SWAP_BE32(trialKey->parentID);

    // parent dirID is unsigned
    if (searchParentID > trialParentID)      result = 1;
    else if (searchParentID < trialParentID) result = -1;
    else {
        // parent dirID's are equal, compare names
        if ((searchKey->nodeName.length == 0) || (trialKey->nodeName.length == 0))
            result = searchKey->nodeName.length - trialKey->nodeName.length;
        else
          if (gCaseSensitive) {
            result = BinaryUnicodeCompare(&searchKey->nodeName.unicode[0],
                                          SWAP_BE16(searchKey->nodeName.length),
                                          &trialKey->nodeName.unicode[0],
                                          SWAP_BE16(trialKey->nodeName.length));
          } else {
            result = FastUnicodeCompare(&searchKey->nodeName.unicode[0],
                                        SWAP_BE16(searchKey->nodeName.length),
                                        &trialKey->nodeName.unicode[0],
                                        SWAP_BE16(trialKey->nodeName.length));
          }
    }

    return result;
}
Ejemplo n.º 3
0
static long CompareHFSExtentsKeys(void * key, void * testKey)
{
    HFSExtentKey *searchKey, *trialKey;
    long         result;
  
    searchKey = key;
    trialKey  = testKey;
  
    // assume searchKey < trialKey
    result = -1;            

    if (searchKey->fileID == trialKey->fileID) {
        // FileNum's are equal; compare fork types
        if (searchKey->forkType == trialKey->forkType) {
            // Fork types are equal; compare allocation block number
            if (searchKey->startBlock == trialKey->startBlock) {
                // Everything is equal
                result = 0;
            } else {
                // Allocation block numbers differ; determine sign
                if (SWAP_BE16(searchKey->startBlock) > SWAP_BE16(trialKey->startBlock))
                    result = 1;
            }
        } else {
            // Fork types differ; determine sign
            if (searchKey->forkType > trialKey->forkType) result = 1;
        }
    } else {
        // FileNums differ; determine sign
        if (SWAP_BE32(searchKey->fileID) > SWAP_BE32(trialKey->fileID))
            result = 1;
    }

    return result;
}
Ejemplo n.º 4
0
bool HFSProbe (const void *buf)
{
	const HFSMasterDirectoryBlock *mdb;
	const HFSPlusVolumeHeader     *header;
	mdb=(const HFSMasterDirectoryBlock *)(((const char*)buf)+kMDBBaseOffset);
	header=(const HFSPlusVolumeHeader *)(((const char*)buf)+kMDBBaseOffset);
	
	if ( SWAP_BE16(mdb->drSigWord) == kHFSSigWord )
		return true;
	if (SWAP_BE16(header->signature) != kHFSPlusSigWord &&
        SWAP_BE16(header->signature) != kHFSXSigWord)
		return false;
	return true;
}
Ejemplo n.º 5
0
static void SwapFinderInfo(FndrFileInfo *dst, FndrFileInfo *src)
{
	dst->fdType = SWAP_BE32(src->fdType);
	dst->fdCreator = SWAP_BE32(src->fdCreator);
	dst->fdFlags = SWAP_BE16(src->fdFlags);
	// Don't bother with location
}
Ejemplo n.º 6
0
static void sendping(int junk)
{
	struct icmp6_hdr *pkt;
	int i;
	char packet[datalen + sizeof (struct icmp6_hdr)];

	pkt = (struct icmp6_hdr *) packet;

	pkt->icmp6_type = ICMP6_ECHO_REQUEST;
	pkt->icmp6_code = 0;
	pkt->icmp6_cksum = 0;
	pkt->icmp6_seq = SWAP_BE16(ntransmitted++);
	pkt->icmp6_id = myid;
	CLR(pkt->icmp6_seq % MAX_DUP_CHK);

	gettimeofday((struct timeval *) &pkt->icmp6_data8[4], NULL);

	i = sendto(pingsock, packet, sizeof(packet), 0,
			   (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in6));

	if (i < 0)
		bb_perror_msg_and_die("sendto");
	else if ((size_t)i != sizeof(packet))
		bb_error_msg_and_die("ping wrote %d chars; %d expected", i,
			   (int)sizeof(packet));

	signal(SIGALRM, sendping);
	if (pingcount == 0 || ntransmitted < pingcount) {	/* schedule next in 1s */
		alarm(PINGINTERVAL);
	} else {					/* done, wait for the last ping to come back */
		/* todo, don't necessarily need to wait so long... */
		signal(SIGALRM, pingstats);
		alarm(MAXWAIT);
	}
}
Ejemplo n.º 7
0
static void GetBTreeRecord(long index, char * nodeBuffer, long nodeSize,
                           char ** key, char ** data)
{
    long keySize;
    long recordOffset;
  
    recordOffset = SWAP_BE16(*((short *)(nodeBuffer + (nodeSize - 2 * index - 2))));
    *key = nodeBuffer + recordOffset;
    if (gIsHFSPlus) {
        keySize = SWAP_BE16(*(short *)*key);
        *data = *key + 2 + keySize;
    } else {
        keySize = **key;
        *data = *key + 2 + keySize - (keySize & 1);
    }
}
Ejemplo n.º 8
0
void
HFSGetDescription(CICell ih, char *str, long strMaxLen)
{

    UInt16 nodeSize;
    UInt32 firstLeafNode;
    long dirIndex;
    char *name;
    long flags, time;

    if (HFSInitPartition(ih) == -1)  { return; }

    /* Fill some crucial data structures by side effect. */
    dirIndex = 0;
    HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0);

    /* Now we can loook up the volume name node. */
    nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
    firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);

    dirIndex = firstLeafNode * nodeSize;

    GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);

    strncpy(str, name, strMaxLen);
    str[strMaxLen] = '\0';
}
Ejemplo n.º 9
0
static void GetBTreeRecord(u_int16_t index, char * nodeBuffer, u_int16_t nodeSize, char ** key, char ** data)
{
	u_int16_t recordOffset, keySize;

	recordOffset = SWAP_BE16(*((u_int16_t *)(nodeBuffer + (nodeSize - 2 * index - 2))));
	*key = nodeBuffer + recordOffset;

	if (gIsHFSPlus)
	{
		keySize = SWAP_BE16(*(u_int16_t *)*key);
		*data = *key + 2 + keySize;
	}
	else
	{
		keySize = **key;
		*data = *key + 2 + keySize - (keySize & 1);
	}
}
Ejemplo n.º 10
0
static long GetExtentSize(void * extents, long index)
{
    long                    size;
    HFSExtentDescriptor     *hfsExtents     = extents;
    HFSPlusExtentDescriptor *hfsPlusExtents = extents;
  
    if (gIsHFSPlus) size = SWAP_BE32(hfsPlusExtents[index].blockCount);
    else size = SWAP_BE16(hfsExtents[index].blockCount);

    return size;
}
Ejemplo n.º 11
0
static long GetExtentStart(void * extents, long index)
{
    long                    start;
    HFSExtentDescriptor     *hfsExtents     = extents;
    HFSPlusExtentDescriptor *hfsPlusExtents = extents;

    if (gIsHFSPlus) start = SWAP_BE32(hfsPlusExtents[index].startBlock);
    else start = SWAP_BE16(hfsExtents[index].startBlock);

    return start;
}
Ejemplo n.º 12
0
/*
 * hfs_swap_HFSPlusVolumeHeader
 */
void
hfs_swap_HFSPlusVolumeHeader (
    void *buf
)
{
    HFSPlusVolumeHeader *src = (HFSPlusVolumeHeader *)buf;

    src->signature			= SWAP_BE16 (src->signature);
    src->version			= SWAP_BE16 (src->version);
    src->attributes			= SWAP_BE32 (src->attributes);
    src->lastMountedVersion	= SWAP_BE32 (src->lastMountedVersion);

    src->journalInfoBlock	= SWAP_BE32 (src->journalInfoBlock);

    src->createDate			= SWAP_BE32 (src->createDate);
    src->modifyDate			= SWAP_BE32 (src->modifyDate);
    src->backupDate			= SWAP_BE32 (src->backupDate);
    src->checkedDate		= SWAP_BE32 (src->checkedDate);
    src->fileCount			= SWAP_BE32 (src->fileCount);
    src->folderCount		= SWAP_BE32 (src->folderCount);
    src->blockSize			= SWAP_BE32 (src->blockSize);
    src->totalBlocks		= SWAP_BE32 (src->totalBlocks);
    src->freeBlocks			= SWAP_BE32 (src->freeBlocks);
    src->nextAllocation		= SWAP_BE32 (src->nextAllocation);
    src->rsrcClumpSize		= SWAP_BE32 (src->rsrcClumpSize);
    src->dataClumpSize		= SWAP_BE32 (src->dataClumpSize);
    src->nextCatalogID		= SWAP_BE32 (src->nextCatalogID);
    src->writeCount			= SWAP_BE32 (src->writeCount);
    src->encodingsBitmap	= SWAP_BE64 (src->encodingsBitmap);

    /* Don't swap finderInfo */

    hfs_swap_HFSPlusForkData (&src->allocationFile);
    hfs_swap_HFSPlusForkData (&src->extentsFile);
    hfs_swap_HFSPlusForkData (&src->catalogFile);
    hfs_swap_HFSPlusForkData (&src->attributesFile);
    hfs_swap_HFSPlusForkData (&src->startupFile);
}
Ejemplo n.º 13
0
/*
 * Create a new indirect link
 *
 * An indirect link is a reference to a data node.  The only useable
 * fields in the link are the link number, parentID, name and text
 * encoding.  All other catalog fields are ignored.
 */
static int
createindirectlink(struct hfsmount *hfsmp, u_int32_t linknum,
			u_int32_t linkparid, char *linkName, cnid_t *linkcnid)
{
	struct FndrFileInfo *fip;
	struct cat_desc desc;
	struct cat_attr attr;
	int result;

	/* Setup the descriptor */
	bzero(&desc, sizeof(desc));
	desc.cd_nameptr = linkName;
	desc.cd_namelen = strlen(linkName);
	desc.cd_parentcnid = linkparid;

	/* Setup the default attributes */
	bzero(&attr, sizeof(attr));
	
	/* links are matched to data nodes by link ID and to volumes by create date */
	attr.ca_rdev = linknum;  /* note: cat backend overloads ca_rdev to be the linknum when nlink = 0 */
	attr.ca_itime = HFSTOVCB(hfsmp)->vcbCrDate;
	attr.ca_mode = S_IFREG;

	fip = (struct FndrFileInfo *)&attr.ca_finderinfo;
	fip->fdType    = SWAP_BE32 (kHardLinkFileType);	/* 'hlnk' */
	fip->fdCreator = SWAP_BE32 (kHFSPlusCreator);	/* 'hfs+' */
	fip->fdFlags   = SWAP_BE16 (kHasBeenInited);

	hfs_global_shared_lock_acquire(hfsmp);
	if (hfsmp->jnl) {
	    if (journal_start_transaction(hfsmp->jnl) != 0) {
			hfs_global_shared_lock_release(hfsmp);
			return EINVAL;
	    }
	}

	/* Create the indirect link directly in the catalog */
	result = cat_create(hfsmp, &desc, &attr, NULL);

	if (result == 0 && linkcnid != NULL)
		*linkcnid = attr.ca_fileid;

	if (hfsmp->jnl) {
	    journal_end_transaction(hfsmp->jnl);
	}
	hfs_global_shared_lock_release(hfsmp);

	return (result);
}
Ejemplo n.º 14
0
static u_int32_t GetExtentStart(void * extents, u_int32_t index)
{
	u_int32_t start;

	HFSExtentDescriptor		*hfsExtents		= extents;
	HFSPlusExtentDescriptor	*hfsPlusExtents	= extents;

	if (gIsHFSPlus)
	{
		start = SWAP_BE32(hfsPlusExtents[index].startBlock);
	}
	else
	{
		start = SWAP_BE16(hfsExtents[index].startBlock);
	}

	return start;
}
Ejemplo n.º 15
0
static u_int32_t GetExtentSize(void * extents, u_int32_t index)
{
	u_int32_t size = 0;

	HFSExtentDescriptor     *hfsExtents     = extents;
	HFSPlusExtentDescriptor *hfsPlusExtents = extents;

	if (gIsHFSPlus)
	{
		size = SWAP_BE32(hfsPlusExtents[index].blockCount);
	}
	else
	{
		size = SWAP_BE16(hfsExtents[index].blockCount);
	}

	return size;
}
Ejemplo n.º 16
0
static long ReadExtentsEntry(long fileID, long startBlock, void * entry)
{
    char             key[sizeof(HFSPlusExtentKey)];
    HFSExtentKey     *hfsKey     = (HFSExtentKey *)key;
    HFSPlusExtentKey *hfsPlusKey = (HFSPlusExtentKey *)key;

    // Make the extents key.
    if (gIsHFSPlus) {
        hfsPlusKey->forkType   = 0;
        hfsPlusKey->fileID     = SWAP_BE32(fileID);
        hfsPlusKey->startBlock = SWAP_BE32(startBlock);
    } else {
        hfsKey->forkType   = 0;
        hfsKey->fileID     = SWAP_BE32(fileID);
        hfsKey->startBlock = SWAP_BE16(startBlock);
    }

    return ReadBTreeEntry(kBTreeExtents, &key, entry, 0);
}
Ejemplo n.º 17
0
long HFSInitPartition(CICell ih)
{
    long extentSize, extentFile, nodeSize;
    void *extent;

    if (ih == gCurrentIH) {
#ifdef __i386__
        CacheInit(ih, gCacheBlockSize);
#endif
        return 0;
    }

#ifdef __i386__
    if (!gTempStr) gTempStr = (char *)malloc(4096);
    if (!gLinkTemp) gLinkTemp = (char *)malloc(64);
    if (!gBTreeHeaderBuffer) gBTreeHeaderBuffer = (char *)malloc(512);
    if (!gHFSMdbVib) {
        gHFSMdbVib = (char *)malloc(kBlockSize);
        gHFSMDB = (HFSMasterDirectoryBlock *)gHFSMdbVib;
    }
    if (!gHFSPlusHeader) {
        gHFSPlusHeader = (char *)malloc(kBlockSize);
        gHFSPlus = (HFSPlusVolumeHeader *)gHFSPlusHeader;
    }
    if (!gTempStr || !gLinkTemp || !gBTreeHeaderBuffer ||
        !gHFSMdbVib || !gHFSPlusHeader) return -1;
#endif /* __i386__ */

    gAllocationOffset = 0;
    gIsHFSPlus = 0;
    gCaseSensitive = 0;
    gBTHeaders[0] = 0;
    gBTHeaders[1] = 0;

    // Look for the HFS MDB
    Seek(ih, kMDBBaseOffset);
    Read(ih, (long)gHFSMdbVib, kBlockSize);

    if ( SWAP_BE16(gHFSMDB->drSigWord) == kHFSSigWord ) {
        gAllocationOffset = SWAP_BE16(gHFSMDB->drAlBlSt) * kBlockSize;

        // See if it is HFSPlus
        if (SWAP_BE16(gHFSMDB->drEmbedSigWord) != kHFSPlusSigWord) {
            // Normal HFS;
            gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSMDB->drAlBlkSiz);
            CacheInit(ih, gCacheBlockSize);
            gCurrentIH = ih;

            // grab the 64 bit volume ID
            bcopy(&gHFSMDB->drFndrInfo[6], &gVolID, 8);

            // Get the Catalog BTree node size.
            extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
            extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
            extentFile = kHFSCatalogFileID;
            ReadExtent(extent, extentSize, extentFile, 0, 256,
                       gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);

            nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 + 
                                 sizeof(BTNodeDescriptor)))->nodeSize);

            // If the BTree node size is larger than the block size, reset the cache.
            if (nodeSize > gBlockSize) {
                gCacheBlockSize = nodeSize;
                CacheInit(ih, gCacheBlockSize);
            }

            return 0;
        }

        // Calculate the offset to the embeded HFSPlus volume.
        gAllocationOffset += (long long)SWAP_BE16(gHFSMDB->drEmbedExtent.startBlock) *
                                        SWAP_BE32(gHFSMDB->drAlBlkSiz);
    }

    // Look for the HFSPlus Header
    Seek(ih, gAllocationOffset + kMDBBaseOffset);
    Read(ih, (long)gHFSPlusHeader, kBlockSize);

    // Not a HFS+ or HFSX volume.
    if (SWAP_BE16(gHFSPlus->signature) != kHFSPlusSigWord &&
        SWAP_BE16(gHFSPlus->signature) != kHFSXSigWord) {
	verbose("HFS signature was not present.\n");
        gCurrentIH = 0;
	return -1;
    }

    gIsHFSPlus = 1;
    gCacheBlockSize = gBlockSize = SWAP_BE32(gHFSPlus->blockSize);
    CacheInit(ih, gCacheBlockSize);
    gCurrentIH = ih;

    // grab the 64 bit volume ID
    bcopy(&gHFSPlus->finderInfo[24], &gVolID, 8);

    // Get the Catalog BTree node size.
    extent     = &gHFSPlus->catalogFile.extents;
    extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
    extentFile = kHFSCatalogFileID;

    ReadExtent(extent, extentSize, extentFile, 0, 256,
               gBTreeHeaderBuffer + kBTreeCatalog * 256, 0);

    nodeSize = SWAP_BE16(((BTHeaderRec *)(gBTreeHeaderBuffer + kBTreeCatalog * 256 +
                         sizeof(BTNodeDescriptor)))->nodeSize);

    // If the BTree node size is larger than the block size, reset the cache.
    if (nodeSize > gBlockSize) {
        gCacheBlockSize = nodeSize;
        CacheInit(ih, gCacheBlockSize);
    }

    return 0;
}
Ejemplo n.º 18
0
static long ReadBTreeEntry(long btree, void * key, char * entry, long * dirIndex)
{
    long             extentSize;
    void             *extent;
    short            extentFile;
    char             *nodeBuf;
    BTNodeDescriptor *node;
    long             nodeSize, result = 0, entrySize = 0;
    long             curNode, index = 0, lowerBound, upperBound;
    char             *testKey, *recordData;

    // Figure out which tree is being looked at.
    if (btree == kBTreeCatalog) {
        if (gIsHFSPlus) {
            extent     = &gHFSPlus->catalogFile.extents;
            extentSize = SWAP_BE64(gHFSPlus->catalogFile.logicalSize);
        } else {
            extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
            extentSize = SWAP_BE32(gHFSMDB->drCTFlSize);
        }
        extentFile = kHFSCatalogFileID;
    } else {
        if (gIsHFSPlus) {
            extent     = &gHFSPlus->extentsFile.extents;
            extentSize = SWAP_BE64(gHFSPlus->extentsFile.logicalSize);
        } else {
            extent     = (HFSExtentDescriptor *)&gHFSMDB->drXTExtRec;
            extentSize = SWAP_BE32(gHFSMDB->drXTFlSize);
        }
        extentFile = kHFSExtentsFileID;
    }

    // Read the BTree Header if needed.
    if (gBTHeaders[btree] == 0) {
        ReadExtent(extent, extentSize, extentFile, 0, 256,
                   gBTreeHeaderBuffer + btree * 256, 0);
        gBTHeaders[btree] = (BTHeaderRec *)(gBTreeHeaderBuffer + btree * 256 +
                                            sizeof(BTNodeDescriptor));
        if ((gIsHFSPlus && btree == kBTreeCatalog) &&
            (gBTHeaders[btree]->keyCompareType == kHFSBinaryCompare)) {
          gCaseSensitive = 1;
        }
    }

    curNode  = SWAP_BE32(gBTHeaders[btree]->rootNode);
    nodeSize = SWAP_BE16(gBTHeaders[btree]->nodeSize);
    nodeBuf  = (char *)malloc(nodeSize);
    node     = (BTNodeDescriptor *)nodeBuf;

    while (1) {
        // Read the current node.
        ReadExtent(extent, extentSize, extentFile,
                   curNode * nodeSize, nodeSize, nodeBuf, 1);
    
        // Find the matching key.
        lowerBound = 0;
        upperBound = SWAP_BE16(node->numRecords) - 1;
        while (lowerBound <= upperBound) {
            index = (lowerBound + upperBound) / 2;

            GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);

            if (gIsHFSPlus) {
                if (btree == kBTreeCatalog) {
                    result = CompareHFSPlusCatalogKeys(key, testKey);
                } else {
                    result = CompareHFSPlusExtentsKeys(key, testKey);
                }
            } else {
                if (btree == kBTreeCatalog) {
                    result = CompareHFSCatalogKeys(key, testKey);
                } else {
                    result = CompareHFSExtentsKeys(key, testKey);
                }
            }
      
            if (result < 0) upperBound = index - 1;        // search < trial
            else if (result > 0) lowerBound = index + 1;   // search > trial
            else break;                                    // search = trial
        }
    
        if (result < 0) {
            index = upperBound;
            GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &recordData);
        }
    
        // Found the closest key... Recurse on it if this is an index node.
        if (node->kind == kBTIndexNode) {
            curNode = SWAP_BE32( *((long *)recordData) );
        } else break;
    }
  
    // Return error if the file was not found.
    if (result != 0) { free(nodeBuf); return -1; }

    if (btree == kBTreeCatalog) {
        switch (SWAP_BE16(*(short *)recordData)) {
            case kHFSFolderRecord           : entrySize = 70;  break;
            case kHFSFileRecord             : entrySize = 102; break;
            case kHFSFolderThreadRecord     : entrySize = 46;  break;
            case kHFSFileThreadRecord       : entrySize = 46;  break;
            case kHFSPlusFolderRecord       : entrySize = 88;  break;
            case kHFSPlusFileRecord         : entrySize = 248; break;
            case kHFSPlusFolderThreadRecord : entrySize = 264; break;
            case kHFSPlusFileThreadRecord   : entrySize = 264; break;
        }
    } else {
        if (gIsHFSPlus) entrySize = sizeof(HFSPlusExtentRecord);
        else entrySize = sizeof(HFSExtentRecord);
    }
  
    bcopy(recordData, entry, entrySize);

    // Update dirIndex.
    if (dirIndex != 0) {
        index++;
        if (index == SWAP_BE16(node->numRecords)) {
            index = 0;
            curNode = SWAP_BE32(node->fLink);
        }
        *dirIndex = curNode * nodeSize + index;
    }
  
    free(nodeBuf);
  
    return 0;
}
Ejemplo n.º 19
0
static long GetCatalogEntryInfo(void * entry, long * flags, long * time,
                                FinderInfo * finderInfo, long * infoValid)
{
    long tmpTime = 0;
    long valid = 0;

    // Get information about the file.
    
    switch ( SWAP_BE16(*(short *)entry) )
    {
        case kHFSFolderRecord           :
            *flags = kFileTypeDirectory;
            tmpTime = SWAP_BE32(((HFSCatalogFolder *)entry)->modifyDate);
            break;

        case kHFSPlusFolderRecord       :
            *flags = kFileTypeDirectory |
                     (SWAP_BE16(((HFSPlusCatalogFolder *)entry)->bsdInfo.fileMode) & kPermMask);
            if (SWAP_BE32(((HFSPlusCatalogFolder *)entry)->bsdInfo.ownerID) != 0)
                *flags |= kOwnerNotRoot;
            tmpTime = SWAP_BE32(((HFSPlusCatalogFolder *)entry)->contentModDate);
            break;

        case kHFSFileRecord             :
            *flags = kFileTypeFlat;
            tmpTime = SWAP_BE32(((HFSCatalogFile *)entry)->modifyDate);
            if (finderInfo) {
                SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSCatalogFile *)entry)->userInfo);
                valid = 1;
            }
            break;

        case kHFSPlusFileRecord         :
            *flags = kFileTypeFlat |
                     (SWAP_BE16(((HFSPlusCatalogFile *)entry)->bsdInfo.fileMode) & kPermMask);
            if (SWAP_BE32(((HFSPlusCatalogFile *)entry)->bsdInfo.ownerID) != 0)
                *flags |= kOwnerNotRoot;
            tmpTime = SWAP_BE32(((HFSPlusCatalogFile *)entry)->contentModDate);
            if (finderInfo) {
                SwapFinderInfo((FndrFileInfo *)finderInfo, &((HFSPlusCatalogFile *)entry)->userInfo);
                valid = 1;
            }
            break;

        case kHFSFileThreadRecord       :
        case kHFSPlusFileThreadRecord   :
        case kHFSFolderThreadRecord     :
        case kHFSPlusFolderThreadRecord :
            *flags = kFileTypeUnknown;
            tmpTime = 0;
            break;
    }

    if (time != 0) {
        // Convert base time from 1904 to 1970.
        *time = tmpTime - 2082844800;
    }
    if (infoValid) *infoValid = valid;

    return 0;
}
Ejemplo n.º 20
0
/*
 * hfs_swap_HFSMasterDirectoryBlock
 *
 *  Specially modified to swap parts of the finder info
 */
void
hfs_swap_HFSMasterDirectoryBlock (
    void *buf
)
{
    HFSMasterDirectoryBlock *src = (HFSMasterDirectoryBlock *)buf;

    src->drSigWord		= SWAP_BE16 (src->drSigWord);
    src->drCrDate		= SWAP_BE32 (src->drCrDate);
    src->drLsMod		= SWAP_BE32 (src->drLsMod);
    src->drAtrb			= SWAP_BE16 (src->drAtrb);
    src->drNmFls		= SWAP_BE16 (src->drNmFls);
    src->drVBMSt		= SWAP_BE16 (src->drVBMSt);
    src->drAllocPtr		= SWAP_BE16 (src->drAllocPtr);
    src->drNmAlBlks		= SWAP_BE16 (src->drNmAlBlks);
    src->drAlBlkSiz		= SWAP_BE32 (src->drAlBlkSiz);
    src->drClpSiz		= SWAP_BE32 (src->drClpSiz);
    src->drAlBlSt		= SWAP_BE16 (src->drAlBlSt);
    src->drNxtCNID		= SWAP_BE32 (src->drNxtCNID);
    src->drFreeBks		= SWAP_BE16 (src->drFreeBks);

    /* Don't swap drVN */

    src->drVolBkUp		= SWAP_BE32 (src->drVolBkUp);
    src->drVSeqNum		= SWAP_BE16 (src->drVSeqNum);
    src->drWrCnt		= SWAP_BE32 (src->drWrCnt);
    src->drXTClpSiz		= SWAP_BE32 (src->drXTClpSiz);
    src->drCTClpSiz		= SWAP_BE32 (src->drCTClpSiz);
    src->drNmRtDirs		= SWAP_BE16 (src->drNmRtDirs);
    src->drFilCnt		= SWAP_BE32 (src->drFilCnt);
    src->drDirCnt		= SWAP_BE32 (src->drDirCnt);

    /* Swap just the 'blessed folder' in drFndrInfo */
    src->drFndrInfo[0]	= SWAP_BE32 (src->drFndrInfo[0]);

    src->drEmbedSigWord	= SWAP_BE16 (src->drEmbedSigWord);
	src->drEmbedExtent.startBlock = SWAP_BE16 (src->drEmbedExtent.startBlock);
	src->drEmbedExtent.blockCount = SWAP_BE16 (src->drEmbedExtent.blockCount);

    src->drXTFlSize		= SWAP_BE32 (src->drXTFlSize);
	src->drXTExtRec[0].startBlock = SWAP_BE16 (src->drXTExtRec[0].startBlock);
	src->drXTExtRec[0].blockCount = SWAP_BE16 (src->drXTExtRec[0].blockCount);
	src->drXTExtRec[1].startBlock = SWAP_BE16 (src->drXTExtRec[1].startBlock);
	src->drXTExtRec[1].blockCount = SWAP_BE16 (src->drXTExtRec[1].blockCount);
	src->drXTExtRec[2].startBlock = SWAP_BE16 (src->drXTExtRec[2].startBlock);
	src->drXTExtRec[2].blockCount = SWAP_BE16 (src->drXTExtRec[2].blockCount);

    src->drCTFlSize		= SWAP_BE32 (src->drCTFlSize);
	src->drCTExtRec[0].startBlock = SWAP_BE16 (src->drCTExtRec[0].startBlock);
	src->drCTExtRec[0].blockCount = SWAP_BE16 (src->drCTExtRec[0].blockCount);
	src->drCTExtRec[1].startBlock = SWAP_BE16 (src->drCTExtRec[1].startBlock);
	src->drCTExtRec[1].blockCount = SWAP_BE16 (src->drCTExtRec[1].blockCount);
	src->drCTExtRec[2].startBlock = SWAP_BE16 (src->drCTExtRec[2].startBlock);
	src->drCTExtRec[2].blockCount = SWAP_BE16 (src->drCTExtRec[2].blockCount);
}