示例#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
/**
 * Reads volume label into str.
 * Reads boot sector, performs dome checking, loads root dir
 * and parses volume label.
 */
void
EXFATGetDescription(CICell ih, char *str, long strMaxLen)
{
    struct exfatbootfile *boot;
    u_int32_t bytesPerSector = 0;
    u_int32_t sectorsPerCluster = 0;
    long long  rdirOffset = 0;
    char *buf = NULL;
    struct direntry_label *dire = NULL;
    int loopControl = 0;
	
    DBG("EXFAT: start %x:%x\n", ih->biosdev, ih->part_no);
	
    buf = (char *)malloc(MAX_BLOCK_SIZE);
    if (buf == 0)
    {
        goto error;
    }
	bzero(buf,MAX_BLOCK_SIZE );
	
    /*
     * Read the boot sector, check signatures, and do some minimal
     * sanity checking.  NOTE: the size of the read below is intended
     * to be a multiple of all supported block sizes, so we don't
     * have to determine or change the device's block size.
     */
    Seek(ih, 0);
    Read(ih, (long)buf, MAX_BLOCK_SIZE);
	
    // take our boot structure
    boot = (struct exfatbootfile *) buf;
    
    /*
     * The first three bytes are an Intel x86 jump instruction.  I assume it
     * can be the same forms as DOS FAT:
     *    0xE9 0x?? 0x??
     *    0xEC 0x?? 0x90
     * where 0x?? means any byte value is OK.
     */
    if (boot->reserved1[0] != 0xE9
        && (boot->reserved1[0] != 0xEB || boot->reserved1[2] != 0x90))
    {
        goto error;
    }
	
	// Check the "EXFAT   " signature.
    if (memcmp((const char *)boot->bf_sysid, EXFAT_BBID, EXFAT_BBIDLEN) != 0)
    {
        goto error;
    }
	
    /*
     * Make sure the bytes per sector and sectors per cluster are
     * powers of two, and within reasonable ranges.
     */
    bytesPerSector = 1 << boot->bf_bpss;	/* Just one byte; no swapping needed */
    DBG("EXFAT: bpss=%d, bytesPerSector=%d\n", boot->bf_bpss, bytesPerSector);
    if (boot->bf_bpss < 9 || boot->bf_bpss > 12)
    {
        DBG("EXFAT: invalid bytes per sector shift(%d)\n", boot->bf_bpss);
        goto error;
    }
	
    sectorsPerCluster = 1 << boot->bf_spcs;	/* Just one byte; no swapping needed */
    DBG("EXFAT: spcs=%d, sectorsPerCluster=%d\n", boot->bf_spcs, sectorsPerCluster);
    if (boot->bf_spcs > (25 - boot->bf_bpss))
    {
        DBG("EXFAT: invalid sectors per cluster shift (%d)\n", boot->bf_spcs);
        goto error;
    }
    
	// calculate root dir cluster offset
    rdirOffset = boot->bf_cloff + (boot->bf_rdircl - 2) * sectorsPerCluster;
    DBG("EXFAT: rdirOffset=%d\n", rdirOffset);
	
    // load MAX_BLOCK_SIZE bytes of root dir
    Seek(ih, rdirOffset * bytesPerSector);
    Read(ih, (long)buf, MAX_BLOCK_SIZE);
    DBG("buf 0 1 2 = %x %x %x\n", 0x00ff & buf[0], 0x00ff & buf[1], 0x00ff & buf[2]);
	
    str[0] = '\0';
	
    /*
     * Search for volume label dir entry (type 0x83), convert from unicode and put to str.
     * Set loopControl var to avoid searching outside of buf.
     */
    loopControl = MAX_BLOCK_SIZE / sizeof(struct direntry_label);
    dire = (struct direntry_label *)buf;
    while (loopControl && dire->type && dire->type != 0x83)
    {
        dire++;
        loopControl--;
    }
    if (dire->type == 0x83 && dire->llen > 0 && dire->llen <= 11)
    {
        utf_encodestr( dire->label, (int)dire->llen, (u_int8_t *)str, strMaxLen, OSLittleEndian );
    }
    DBG("EXFAT: label=%s\n", str);
	
    free(buf);
    PAUSE();
    return;
	
error:
    if (buf) free(buf);
    DBG("EXFAT: error\n");
    PAUSE();
    return;
}