Exemplo n.º 1
0
void print_cluster(FILE *f, struct BPB_t *bpb, struct dir_t *dir)
{
    const uint32_t cluster_size = bpb->BytsPerSec * bpb->SecPerClus;

    for(uint16_t c = dir->FstClusLO; c < 0xFFF8; c = get_next_cluster(f, bpb, c)) {
        char buf[cluster_size];
        //FAT16 spec says that you have to subtract 2 from the cluster number to get the actual data
        //so weird. but whatevs....
        read_bytes(f, BPB_Data_addr(bpb) + (c - 2) * cluster_size, buf, sizeof(buf));

        printf("%.*s", (int)(sizeof(buf)), buf);
    }
}
Exemplo n.º 2
0
shared_ptr<FileBuffer> Fat::get_file_buff(string filename)
{
	if (m_filemap.find(filename) == m_filemap.end())
	{
		string err;
		err = "Can't find file ";
		err += filename;
		set_last_err_string(err);
		return NULL;
	}

	shared_ptr<FileBuffer> pbuff = get_file_buffer(m_filename);

	shared_ptr<FileBuffer> p(new FileBuffer);
	size_t filesize = m_filemap[filename].file_size;
	p->resize(filesize);

	int cur = m_filemap[filename].start_cluster;

	size_t off;
	for (off = 0; off < filesize; off += m_cluster)
	{
		size_t sz;
		sz = filesize - off;
		if (sz > m_cluster)
			sz = m_cluster;

		if (cur == 0xFFFF)
		{
			set_last_err_string("Early finished at fat");
			return NULL;
		}
		void *pcluster = get_data_buff(pbuff, cur);
		memcpy(p->data() + off, pcluster, sz);

		cur = get_next_cluster(pbuff, cur);
	}
	return p;
}
Exemplo n.º 3
0
unsigned int exfat_remove_used_space(disk_t *disk, const partition_t *partition, alloc_data_t *list_search_space)
{
  struct exfat_super_block *exfat_header;
  unsigned int cluster_shift;
  /* Load boot sector */
  exfat_header=(struct exfat_super_block *)MALLOC(0x200);
  if(disk->pread(disk, exfat_header, 0x200, partition->part_offset) != 0x200)
  {
    log_error("Can't read exFAT boot sector.\n");
    free(exfat_header);
    return 0;
  }
  cluster_shift=exfat_header->block_per_clus_bits + exfat_header->blocksize_bits;
  /* Load bitmap information */
  {
    const struct exfat_alloc_bitmap_entry *bitmap;
    const uint64_t start=partition->part_offset +
      exfat_cluster_to_offset(exfat_header, le32(exfat_header->rootdir_clusnr));
    unsigned char *buffer_rootdir=(unsigned char *)MALLOC(1<<cluster_shift);
    unsigned char *buffer;
    unsigned int i;
    unsigned int cluster_bitmap;
    const uint64_t start_exfat1=(uint64_t)le32(exfat_header->fat_blocknr) << exfat_header->blocksize_bits;
    uint64_t start_free=0;
    uint64_t end_free=0;
    if(disk->pread(disk, buffer_rootdir, 1 << cluster_shift, start) != (1<<cluster_shift))
    {
      log_error("exFAT: Can't root directory cluster.\n");
      free(buffer_rootdir);
      free(exfat_header);
      return 0; 
    }
    bitmap=exfat_get_bitmap(buffer_rootdir, 1<<cluster_shift);
    if(bitmap==NULL)
    {
      log_error("exFAT: Can't find bitmap.\n");
      free(buffer_rootdir);
      free(exfat_header);
      return 0; 
    }
    cluster_bitmap=le32(bitmap->first_cluster);
    log_trace("exfat_remove_used_space\n");
    buffer=(unsigned char *)MALLOC(1<<cluster_shift);
    for(i=2; i<le32(exfat_header->total_clusters)+2; i++)
    {
      const unsigned int offset_o=(i-2)%(8<<cluster_shift);
      if(offset_o==0)
      {
	exfat_read_cluster(disk, partition, exfat_header, buffer, cluster_bitmap);
	cluster_bitmap=get_next_cluster(disk, partition, UP_FAT32, start_exfat1, cluster_bitmap);
      }
      if(((buffer[offset_o/8]>>(offset_o%8))&1) != 0)
      {
	/* Not free */
	if(end_free+1==partition->part_offset + exfat_cluster_to_offset(exfat_header, i))
	  end_free+=(1<<cluster_shift);
	else
	{
	  if(start_free != end_free)
	    del_search_space(list_search_space, start_free, end_free);
	  start_free=partition->part_offset + exfat_cluster_to_offset(exfat_header, i);
	  end_free=start_free + (1<<cluster_shift) - 1;
	}
      }
    }
    free(buffer);
    if(start_free != end_free)
      del_search_space(list_search_space, start_free, end_free);
    free(buffer_rootdir);
    free(exfat_header);
  }
  return (1<<cluster_shift);
}
Exemplo n.º 4
0
int fat_readdir(struct dirent *d)
{
  int retVal=0;
  do {

    // Advance to next entry
    dir_sector_offset+=32;
    if (dir_sector_offset==512) {
      dir_sector_offset=0;
      dir_sector++;
      dir_sector_in_cluster++;
      if (dir_sector_in_cluster==sectors_per_cluster) {
	// Follow to next cluster
	int next_cluster=get_next_cluster(dir_cluster);
	if (next_cluster<0xFFFFFF0) {
	  dir_cluster=next_cluster;
	  dir_sector_in_cluster=0;
	  dir_sector=first_cluster_sector+(next_cluster-first_cluster)*sectors_per_cluster;
	} else {
	  // End of directory reached
	  dir_sector=-1;
	  retVal=-1;
	  break;
	}
      }
      if (dir_sector!=-1) retVal=read_sector(partition_start+dir_sector,dir_sector_buffer,0);
      if (retVal) dir_sector=-1;      
    }    

    if (dir_sector==-1) { retVal=-1; break; }
    if (!d) { retVal=-1; break; }

    // printf("Found dirent %d %d %d\n",dir_sector,dir_sector_offset,dir_sector_in_cluster);

    // XXX - Support FAT32 long names!

    // Put cluster number in d_ino
    d->d_ino=
      (dir_sector_buffer[dir_sector_offset+0x1A]<<0)|
      (dir_sector_buffer[dir_sector_offset+0x1B]<<8)|
      (dir_sector_buffer[dir_sector_offset+0x14]<<16)|
      (dir_sector_buffer[dir_sector_offset+0x15]<<24);

    int namelen=0;
    if (dir_sector_buffer[dir_sector_offset]) {
      for(int i=0;i<8;i++)
	if (dir_sector_buffer[dir_sector_offset+i])
	  d->d_name[namelen++]=dir_sector_buffer[dir_sector_offset+i];
      while(namelen&&d->d_name[namelen-1]==' ') namelen--;
    }
    if (dir_sector_buffer[dir_sector_offset+8]&&dir_sector_buffer[dir_sector_offset+8]!=' ') {
      d->d_name[namelen++]='.';
      for(int i=0;i<3;i++)
	if (dir_sector_buffer[dir_sector_offset+8+i])
	  d->d_name[namelen++]=dir_sector_buffer[dir_sector_offset+8+i];
      while(namelen&&d->d_name[namelen-1]==' ') namelen--;
    }
    d->d_name[namelen]=0;

    //    if (d->d_name[0]) dump_bytes(0,"dirent raw",&dir_sector_buffer[dir_sector_offset],32);
    
    d->d_off= //  XXX As a hack we put the size here
      (dir_sector_buffer[dir_sector_offset+0x1C]<<0)|
      (dir_sector_buffer[dir_sector_offset+0x1D]<<8)|
      (dir_sector_buffer[dir_sector_offset+0x1E]<<16)|
      (dir_sector_buffer[dir_sector_offset+0x1F]<<24);
    d->d_reclen=dir_sector_buffer[dir_sector_offset+0xb]; // XXX as a hack, we put DOS file attributes here
    if (d->d_off&0xC8) d->d_type=DT_UNKNOWN;
    else if (d->d_off&0x10) d->d_type=DT_DIR;
    else d->d_type=DT_REG;

  } while(0);
  return retVal;
}