コード例 #1
0
ファイル: hfs.c プロジェクト: JayMonkey/chameleon
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;
}
コード例 #2
0
ファイル: hfs.c プロジェクト: aosm/BootX
static long GetCatalogEntry(unsigned long *dirIndex, char **name,
			    long *flags, long *time)
{
  long              nodeSize, index;
  u_int32_t         curNode;
  u_int64_t         extentSize;
  void              *extent;
  char              *nodeBuf, *testKey, *entry;
  BTNodeDescriptor  *node;
  
  if (gIsHFSPlus) {
    extent     = &gHFSPlus->catalogFile.extents;
    extentSize = gHFSPlus->catalogFile.logicalSize;
  } else {
    extent     = (HFSExtentDescriptor *)&gHFSMDB->drCTExtRec;
    extentSize = gHFSMDB->drCTFlSize;
  }
  
  nodeSize = gBTHeaders[kBTreeCatalog]->nodeSize;
  nodeBuf = (char *)malloc(nodeSize);
  node = (BTNodeDescriptor *)nodeBuf;
  
  index   = *dirIndex % nodeSize;
  curNode = *dirIndex / nodeSize;
  
  // Read the BTree node and get the record for index.
  ReadExtent(extent, extentSize, kHFSCatalogFileID,
	     curNode * (u_int32_t)nodeSize, nodeSize, nodeBuf, 1);
  GetBTreeRecord(index, nodeBuf, nodeSize, &testKey, &entry);
  
  GetCatalogEntryInfo(entry, flags, time);
  
  // Get the file name.
  if (gIsHFSPlus) {
    utf_encodestr(((HFSPlusCatalogKey *)testKey)->nodeName.unicode,
		  ((HFSPlusCatalogKey *)testKey)->nodeName.length,
		  gTempStr, 256);
  } else {
    strncpy(gTempStr,
	    &((HFSCatalogKey *)testKey)->nodeName[1],
	    ((HFSCatalogKey *)testKey)->nodeName[0]);
  }
  *name = gTempStr;
  
  // Update dirIndex.
  index++;
  if (index == node->numRecords) {
    index = 0;
    curNode = node->fLink;
  }
  *dirIndex = curNode * nodeSize + index;
  
  free(nodeBuf);
  
  return 0;
}
コード例 #3
0
ファイル: hfs.c プロジェクト: carriercomm/osx-2
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;
}