Пример #1
0
ufs_inode_t* ufs_traverse_path(ufs_t *mount, const char *_path)
{
    uint32_t i;
    uint32_t inum = 2; // 2 == root
    ufs_inode_t *inode = p_alloc(mount->pool, sizeof(ufs_inode_t));
    char *path = p_alloc(mount->pool, strlen(_path)+1);
    strcpy(path, _path);
    
    if (!ufs_load_inode(mount, inode, inum))
        goto fail;
    
    char *last, *elem;
    for (elem = strtok_r(path, "/", &last);
         elem;
         elem = strtok_r(NULL, "/", &last)) {
        
        uint32_t next_inum = 0;
        uint8_t *dir = ufs_read_inode_data(mount, inode);
        if (!dir)
            goto fail;
        
        for (i=0; inode->size; ) {
            ufs_dir_t *entry = (ufs_dir_t*)&dir[i];
            fix_endian(entry->inum);
            fix_endian(entry->len);
            fix_endian(entry->namelen);
            
            if (entry->inum == 0)
                break;
            
            if ((entry->namelen == strlen(elem)) &&
                (strncmp(elem, entry->name, entry->namelen) == 0)) {
                next_inum = entry->inum;
                break;
            }
            
            i += entry->len;
        }
        
        p_free(dir);
        
        if (next_inum == 0) {
            sprintf(mount->error_str, "'%s' in '%s' doesn't exist", elem, _path);
            goto fail;
        }
        
        inum = next_inum;
        if (!ufs_load_inode(mount, inode, inum))
            goto fail;
    }
    
    p_free(path);
    return inode;
    
fail:
    p_free(inode);
    p_free(path);
    return NULL;
}
Пример #2
0
void make_bmp_header(t_bmp_header *header, size_t size) {
	memset(header, 0, sizeof(*header));
	header->magic = BMP_MAGIC;
	header->size = size * size * sizeof(int) + sizeof(t_bmp_header) + sizeof(t_bmp_info_header);
	header->offset = sizeof(t_bmp_header) + sizeof(t_bmp_info_header);
	fix_endian(&header->magic, sizeof(header->magic));
}
Пример #3
0
static void ReadWAVE( char *filename, Wave *wave ) {

	int fd = open( filename, O_RDWR );
	RIFFHeader riff_header = ReadRIFFHeader( fd );
	FmtHeader fmt_header = ReadFmtHeader( fd );

	read( fd, &wave->Subchunk2ID, sizeof(uint32_t));
	read( fd, &wave->Subchunk2Size, sizeof(uint32_t));
	fix_endian( &riff_header, &fmt_header, wave );

	ReadSamples( fd, wave );

	close( fd );

}
Пример #4
0
static void ReadBMP ( char* filename, Bitmap* bmp ) {


	int fd = open( filename, O_RDWR );
	BMPHeader bmp_header = ReadBMPHeader( fd );
	DIBHeader dib_header = ReadDIBHeader( fd );
	uint8_t buffer[BUFFER_SIZE];

#ifndef __APPLE__
	fix_endian( &bmp_header, &dib_header );
#endif
	int offset = bmp_header.offset;
	int size = bmp_header.size;
	int width = dib_header.width;
	int height = dib_header.height;

	// Read pixels
	lseek( fd, offset, SEEK_SET);
	uint8_t *data = malloc(size);
	uint8_t *ptr = (uint8_t*)data;

	for (int i=0; i < (size - offset) / BUFFER_SIZE; i++ ) {
		read( fd, buffer, BUFFER_SIZE );

		for (int i=0; i<BUFFER_SIZE; i++) {
			(*ptr++) = buffer[i];
		}
	}

	int remaining = (size - offset) % BUFFER_SIZE;
	if (remaining) {
		read( fd, buffer, remaining);

		for (int i=0; i<remaining; i++) {

			(*ptr++) = buffer[i];
		}
	}

	close( fd );

	flip( data, width, height );

	bmp->width = width;
	bmp->height = height;
	bmp->pixels = data;
}
Пример #5
0
static uint8_t svfs_load_inode(svfs_t *mount, svfs_inode_t *inode, uint32_t inum)
{
    uint32_t i;
    uint8_t block[4096];
    const uint32_t max_inode_blocks = mount->superblock.isize - 2;
    const uint32_t max_inodes = (max_inode_blocks * mount->blocksize) / 64;
    if (inum > max_inodes) {
        sprintf(mount->error_str, "svfs_load_inode: inode %u too big (max=%u)", inum, max_inodes);
        return 0;
    }
    
    const uint32_t inum_byte_idx_in_partition = ((inum-1) * 64) + (2 * mount->blocksize);
    const uint32_t inum_block = inum_byte_idx_in_partition / mount->blocksize;
    const uint32_t inum_byte_idx_in_block = inum_byte_idx_in_partition % mount->blocksize;
    
    if (!svfs_read_block(mount, block, inum_block))
        return 0;
    
    memcpy(inode, &block[inum_byte_idx_in_block], 64);
    
    fix_endian(inode->mode);
    fix_endian(inode->nlink);
    fix_endian(inode->uid);
    fix_endian(inode->gid);
    fix_endian(inode->size);
    fix_endian(inode->atime);
    fix_endian(inode->mtime);
    fix_endian(inode->ctime);
    
    for (i=0; i<13; i++) {
        uint32_t addr = inode->__addr[i*3 + 0];
        addr = (addr << 8) + inode->__addr[i*3 + 1];
        addr = (addr << 8) + inode->__addr[i*3 + 2];
        inode->addr[i] = addr;
    }
    
    return 1;
}
Пример #6
0
static uint8_t ufs_load_inode(ufs_t *mount, ufs_inode_t *inode, uint32_t inum)
{
    assert(sizeof(ufs_inode_t) == 128);
    
    /* Which cylinder group is this inode in? */
    const uint32_t group_num = inum / mount->superblock.ipg;
    
    /* Index of this inode in its cylinder group's inode table */
    const uint32_t group_ino_offset = inum % mount->superblock.ipg;
    
    /* Fragment address that contains inode */
    const uint32_t frag_addr = ufs_group_base(mount, group_num) +
                               mount->superblock.iblkno +
                               ((group_ino_offset * 128) / mount->frag_size);
    
    /* Byte offset into the fragment where the inode begins */
    const uint32_t frag_offset = (group_ino_offset * 128) % mount->frag_size;
    
    uint32_t i;
    uint8_t *buf = p_alloc(mount->pool, mount->frag_size);
    
    // slog("group_num = %u, ino_offset=%u, addr = 0x%08x, offset = 0x%08x\n", group_num, group_ino_offset, frag_addr, frag_offset);
    // slog("mount->superblock.iblkno = 0x%08x\n", mount->superblock.iblkno);
    
    if (!ufs_read_frag(mount, buf, frag_addr))
        goto fail;
    
    memcpy(inode, buf + frag_offset, 128);
    
    fix_endian(inode->mode);
    fix_endian(inode->nlink);
    fix_endian(inode->uid);
    fix_endian(inode->gid);
    fix_endian(inode->size_hi);
    fix_endian(inode->size);
    fix_endian(inode->atime);
    fix_endian(inode->mtime);
    fix_endian(inode->ctime);
    for (i=0; i<12; i++)
        fix_endian(inode->direct[i]);
    for (i=0; i<3; i++)
        fix_endian(inode->indirect[i]);
    fix_endian(inode->flags);
    fix_endian(inode->blocks);
    fix_endian(inode->gen);
    
    p_free(buf);
    return 1;
fail:
    if (buf)
        p_free(buf);
    return 0;
}
Пример #7
0
static uint8_t ufs_load_cylinder_group(ufs_t *mount, uint32_t frag_offset, ufs_cylinder_group_t *group)
{
    uint32_t numfrags = sizeof(ufs_cylinder_group_t) / mount->frag_size;
    numfrags += ((sizeof(ufs_cylinder_group_t) % mount->frag_size) != 0);
    
    uint8_t *buf = p_alloc(mount->pool, (numfrags+1) * mount->frag_size);
    uint32_t i;
    
    for (i=0; i <= numfrags; i++)
        ufs_read_frag(mount, &buf[i * mount->frag_size], frag_offset + i);
    memcpy(group, buf, sizeof(ufs_cylinder_group_t));
    
    fix_endian(group->link);
    fix_endian(group->rlink);
    fix_endian(group->time);
    fix_endian(group->cgx);
    fix_endian(group->ncyl);
    fix_endian(group->niblk);
    fix_endian(group->ndblk);
    fix_endian(group->csum_ndir);
    fix_endian(group->csum_nbfree);
    fix_endian(group->csum_nifree);
    fix_endian(group->csum_nffree);
    fix_endian(group->rotor);
    fix_endian(group->frotor);
    fix_endian(group->irotor);
    for (i=0; i<8; i++)
        fix_endian(group->frsum[i]);
    for (i=0; i<(32*8); i++)
        fix_endian(group->b[i/8][i%8]);
    fix_endian(group->magic);
    
    p_free(buf);
    return 1;
fail:
    p_free(buf);
    return 0;
}
Пример #8
0
static svfs_t* svfs_mount(partition_t *part)
{
    assert(sizeof(svfs_superblock_t) == 512);
    
    uint32_t i;
    svfs_t *mount = p_alloc(part->pool, sizeof(svfs_t));
    mount->pool = part->pool;
    mount->error_str = part->error_str;
    mount->part = part;
    
    part_get_block(part, (uint8_t*)&mount->superblock, 1);
    
    fix_endian(mount->superblock.isize);
    fix_endian(mount->superblock.fsize);
    fix_endian(mount->superblock.nfree);
    for (i=0; i<50; i++) {
        fix_endian(mount->superblock.free[i]);
    }
    fix_endian(mount->superblock.ninode);
    for (i=0; i<100; i++) {
        fix_endian(mount->superblock.inode[i]);
    }
    fix_endian(mount->superblock.time);
    for (i=0; i<4; i++) {
        fix_endian(mount->superblock.dinfo[i]);
    }
    fix_endian(mount->superblock.tfree);
    fix_endian(mount->superblock.tinode);
    fix_endian(mount->superblock.state);
    fix_endian(mount->superblock.lasti);
    fix_endian(mount->superblock.nbehind);
    fix_endian(mount->superblock.magic);
    fix_endian(mount->superblock.type);
    
    if (mount->superblock.magic != 0xfd187e20) {
        sprintf(part->error_str, "Magic doesn't match svfs");
        goto fail;
    }
    
    // It is SVFS!
    
    const uint32_t type = mount->superblock.type;
    if ((type != 1) && (type != 2) && (type != 4) && (type != 8)) {
        sprintf(part->error_str, "Unknown SVFS type (%u)", type);
        goto fail;
    }
    
    mount->blocksize = 512 * type;
    
    return mount;
    
fail:
    if (mount) p_free(mount);
    
    return NULL;
}
Пример #9
0
static disk_t* open_disk (const char *disk_path, char *error_str)
{
    disk_t *disk;
    uint8_t block[512];
    apple_partition_map_t apm;
    uint32_t i;
    alloc_pool_t *pool = p_new_pool(NULL);
    FILE *f;
    
    disk = p_alloc(pool, sizeof(disk_t));
    
    disk->pool = pool;
    disk->block_size = 512;
    disk->error_str = error_str;
    disk->path = disk_path;
    
    f = fopen(disk_path, "rb");
    if (f == NULL) {
        sprintf(error_str, "Can't open that path");
        goto fail;
    }
    
    disk->f = f;
    
    // Load the driver descriptor record
    
    disk_get_block(disk, block, 0);
    memcpy(&disk->ddr, block, sizeof(disk->ddr));
    
    fix_endian(disk->ddr.sbBlkSize);
    fix_endian(disk->ddr.sbBlkCount);
    fix_endian(disk->ddr.sbDevType);
    fix_endian(disk->ddr.sbDevId);
    fix_endian(disk->ddr.sbData);
    fix_endian(disk->ddr.sbDrvrCount);
    fix_endian(disk->ddr.ddBlock);
    fix_endian(disk->ddr.ddSize);
    fix_endian(disk->ddr.ddType);

    // If the DDR block exists, (it doesn't have to necessarially)
    if (memcmp(disk->ddr.sbSig, "ER", 2) == 0) {
        // Can't handle non-512 byte block sizes
        if (disk->ddr.sbBlkSize != 512) {
            sprintf(error_str, "This disk uses blkSize=%u and I can't handle that",
                    disk->ddr.sbBlkSize);
            goto fail;
        }
    }
    
    // slog("sizeof(apple_part_map_t) = %lu\n", sizeof(apple_partition_map_t));
    
    // Load the partition maps
    
    if (!disk_load_partition_map(disk, &apm, 0))
        goto fail;
    else if ((apm.pmMapBlkCnt > 256) || (apm.pmMapBlkCnt == 0)) {
        sprintf(error_str, "Crazy number of partitions on this disk %u", apm.pmMapBlkCnt);
        goto fail;
    }
    
    disk->num_partitions = apm.pmMapBlkCnt;
    disk->partition_maps = p_alloc(disk->pool, disk->num_partitions * sizeof(apple_partition_map_t));
    disk->partitions = p_alloc(disk->pool, disk->num_partitions * sizeof(partition_t));
    
    for (i=0; i<disk->num_partitions; i++) {
        if (!disk_load_partition_map(disk, &disk->partition_maps[i], i))
            goto fail;
        
        memset(&disk->partitions[i], 0, sizeof(partition_t));
        disk->partitions[i].disk = disk;
        disk->partitions[i].pool = disk->pool;
        disk->partitions[i].error_str = error_str;
        disk->partitions[i].start_block = disk->partition_maps[i].pmPyPartStart;
        disk->partitions[i].num_blocks = disk->partition_maps[i].pmPartBlkCnt;
        
        memcpy(disk->partitions[i].name, disk->partition_maps[i].pmPartName, 32);
        memcpy(disk->partitions[i].type, disk->partition_maps[i].pmPartType, 32);
        
        slog("%u type:%s name:%s\n", i, disk->partitions[i].type, disk->partitions[i].name);
        slog("bz_magic=0x%08x slice=%u\n", disk->partition_maps[i].bz.magic, disk->partition_maps[i].bz.slice);
    }
    
    return disk;
    
fail:
    if (f) fclose(f);
    p_free_pool(pool);
    return NULL;
}
Пример #10
0
static uint8_t disk_load_partition_map(disk_t *disk, apple_partition_map_t *apm, uint32_t idx)
{
    uint8_t block[512];
    
    disk_get_block(disk, block, 1 + idx);
    memcpy(apm, block, sizeof(apple_partition_map_t));
    
    fix_endian(apm->pmSigPad);
    fix_endian(apm->pmMapBlkCnt);
    fix_endian(apm->pmPyPartStart);
    fix_endian(apm->pmPartBlkCnt);
    fix_endian(apm->pmLgDataStart);
    fix_endian(apm->pmDataCnt);
    fix_endian(apm->pmPartStatus);
    fix_endian(apm->pmLgBootStart);
    fix_endian(apm->pmBootSize);
    fix_endian(apm->pmBootAddr);
    fix_endian(apm->pmBootAddr2);
    fix_endian(apm->pmBootEntry);
    fix_endian(apm->pmBootEntry2);
    fix_endian(apm->pmBootCksum);
    
    fix_endian(apm->bz.magic);
    fix_endian(apm->bz.inode);
    fix_endian(apm->bz.tmade);
    fix_endian(apm->bz.tmount);
    fix_endian(apm->bz.tunmount);
    fix_endian(apm->bz.abm_size);
    fix_endian(apm->bz.abm_ents);
    fix_endian(apm->bz.abm_start);
    
    if (memcmp(apm->pmSig, "PM", 2) != 0) {
        sprintf(disk->error_str, "partition index %u has bad magic %02x%02x",
                idx, apm->pmSig[0], apm->pmSig[1]);
        return 0;
    }
    
    return 1;
}
Пример #11
0
static ufs_t* ufs_mount(partition_t *part)
{
    ufs_t *mount = p_alloc(part->pool, sizeof(ufs_t));
    uint8_t *buf = p_alloc(part->pool, 32 * 512);
    uint32_t i;
    
    mount->pool = part->pool;
    mount->part = part;
    mount->error_str = part->error_str;
    
    for (i=0; i<4; i++)
        part_get_block(part, &buf[i*512], 16 + i);
    memcpy(&mount->superblock, buf, sizeof(ufs_superblock_t));
    
    fix_endian(mount->superblock.link);
    fix_endian(mount->superblock.rlink);
    fix_endian(mount->superblock.sblkno);
    fix_endian(mount->superblock.cblkno);
    fix_endian(mount->superblock.iblkno);
    fix_endian(mount->superblock.dblkno);
    fix_endian(mount->superblock.cgoffset);
    fix_endian(mount->superblock.cgmask);
    fix_endian(mount->superblock.time);
    fix_endian(mount->superblock.size);
    fix_endian(mount->superblock.dsize);
    fix_endian(mount->superblock.ncg);
    fix_endian(mount->superblock.bsize);
    fix_endian(mount->superblock.fsize);
    fix_endian(mount->superblock.frag);
    fix_endian(mount->superblock.minfree);
    fix_endian(mount->superblock.rotdelay);
    fix_endian(mount->superblock.rps);
    fix_endian(mount->superblock.bmask);
    fix_endian(mount->superblock.fmask);
    fix_endian(mount->superblock.bshift);
    fix_endian(mount->superblock.fshift);
    fix_endian(mount->superblock.maxcontig);
    fix_endian(mount->superblock.maxbpg);
    fix_endian(mount->superblock.fragshift);
    fix_endian(mount->superblock.fsbtodb);
    fix_endian(mount->superblock.sbsize);
    fix_endian(mount->superblock.csmask);
    fix_endian(mount->superblock.csshift);
    fix_endian(mount->superblock.nindir);
    fix_endian(mount->superblock.inopb);
    fix_endian(mount->superblock.nspf);
    fix_endian(mount->superblock.optim);
    fix_endian(mount->superblock.state);
    fix_endian(mount->superblock.id[0]);
    fix_endian(mount->superblock.id[1]);
    fix_endian(mount->superblock.csaddr);
    fix_endian(mount->superblock.cssize);
    fix_endian(mount->superblock.cgsize);
    fix_endian(mount->superblock.ntrak);
    fix_endian(mount->superblock.nsect);
    fix_endian(mount->superblock.spc);
    fix_endian(mount->superblock.ncyl);
    fix_endian(mount->superblock.cpg);
    fix_endian(mount->superblock.ipg);
    fix_endian(mount->superblock.fpg);
    fix_endian(mount->superblock.csum_ndir);
    fix_endian(mount->superblock.csum_nbfree);
    fix_endian(mount->superblock.csum_nifree);
    fix_endian(mount->superblock.csum_nffree);
    fix_endian(mount->superblock.cgrotor);
    fix_endian(mount->superblock.cpc);
    for (i=0; i<(32*8); i++)
        fix_endian(mount->superblock.postbl[i/8][i%8]);
    fix_endian(mount->superblock.magic);
    
    
    if (mount->superblock.magic != 0x00011954) {
        sprintf(part->error_str, "Magic doesn't match ufs");
        goto fail;
    }
    
    // It is UFS!
    
    mount->frag_size = mount->superblock.fsize;
    mount->frag_per_block = mount->superblock.frag;
    mount->block_size = mount->frag_size * mount->frag_per_block;
    assert(mount->block_size == mount->superblock.bsize);
    
    mount->num_groups = mount->superblock.ncg;
    mount->groups = (ufs_cylinder_group_t*)p_alloc(mount->pool,
                                                   mount->num_groups * sizeof(ufs_cylinder_group_t));
    
    for (i=0; i<mount->num_groups; i++) {
        uint32_t group_base = ufs_group_base(mount, i) + mount->superblock.cblkno;
        ufs_load_cylinder_group(mount, group_base, &mount->groups[i]);
        if ((mount->groups[i].cgx != i) || (mount->groups[i].magic != 0x00090255)) {
            sprintf(mount->error_str, "bad cylinder group %u frag_offset=0x%x", i, group_base);
            goto fail;
        }
    }
    
    if (buf)
        p_free(buf);
    return mount;
fail:
    if (mount) {
        if (mount->groups)
            p_free(mount->groups);
        p_free(mount);
    }
    if (buf)
        p_free(buf);
    return NULL;
}