예제 #1
0
static int FuseHFS_removexattr(const char *path, const char *name) {
	dprintf("removexattr %s %s\n", path, name);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// find file
	hfsdirent ent;
	if (hfs_stat(NULL, hfspath, &ent) == -1) {
		free(hfspath);
		return -ENOENT;
	}
	
	if (strcmp(name, XATTR_FINDERINFO_NAME) == 0) {
		free(hfspath);
		// not really removing it
		return 0;
	} else if (strcmp(name, XATTR_RESOURCEFORK_NAME) == 0 && (!(ent.flags & HFS_ISDIR))) {
		// resource fork
		hfsfile *fp = hfs_open(NULL, hfspath);
		hfs_setfork(fp, 1);
		hfs_seek(fp, 0, SEEK_SET);
		hfs_truncate(fp, 0);
		hfs_close(fp);
		free(hfspath);
		return 0;
	}
	
	free(hfspath);
	return -ENOATTR;	
}
예제 #2
0
/*
 * NAME:	opensrc()
 * DESCRIPTION:	open the source file; set hint for destination filename
 */
static
hfsfile *opensrc(hfsvol *vol, const char *srcname,
		 const char **dsthint, const char *ext)
{
  hfsfile *file;
  hfsdirent ent;
  static char name[HFS_MAX_FLEN + 4 + 1];
  char *ptr;

  file = hfs_open(vol, srcname);
  if (file == 0)
    {
      ERROR(errno, hfs_error);
      return 0;
    }

  if (hfs_fstat(file, &ent) == -1)
    {
      ERROR(errno, hfs_error);

      hfs_close(file);
      return 0;
    }

  strcpy(name, ent.name);

  for (ptr = name; *ptr; ++ptr)
    {
      switch (*ptr)
	{
	case '/':
	  *ptr = '-';
	  break;

	case ' ':
	  *ptr = '_';
	  break;
	}
    }

  if (ext)
    strcat(name, ext);

  *dsthint = name;

  return file;
}
예제 #3
0
static int FuseHFS_truncate (const char *path, off_t length) {
	dprintf("truncate %s %lu\n", path, length);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	hfsfile *file = hfs_open(NULL, hfspath);
	free(hfspath);
	if (file == NULL) return -errno;
	if (hfs_truncate(file, length) == -1) {
		hfs_close(file);
		perror("truncate");
		return -errno;
	}
	hfs_close(file);
	return 0;
}
예제 #4
0
static int FuseHFS_open(const char *path, struct fuse_file_info *fi) {
	dprintf("open %s\n", path);
	// apparently, MacFUSE won't open the same file more than once. This won't break if it stays this way.
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// open file
	hfsfile *file = NULL;
	if ((file = hfs_open(NULL, hfspath))) {
		// file
		fi->fh = (uint64_t)file;
		free(hfspath);
		return 0;
	}
	
	free(hfspath);
	perror("hfs_open");
	return -errno;
}
예제 #5
0
static int FuseHFS_create(const char *path, mode_t mode, struct fuse_file_info *fi) {
	dprintf("create %s\n", path);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// open file
	hfsfile *file;
	if ((file = hfs_create(NULL, hfspath, "TEXT", "FUSE"))) {
		// close and reopen, because it won't exist until it's closed
		hfs_close(file);
		file = hfs_open(NULL, hfspath);
		fi->fh = (uint64_t)file;
		free(hfspath);
		return 0;
	}
	
	free(hfspath);
	perror("hfs_create");
	return -errno;
}
예제 #6
0
static int FuseHFS_setxattr(const char *path, const char *name, const char *value,
				  size_t size, int flags, uint32_t position) {
	dprintf("setxattr %s %s %p %lu %02x %u\n", path, name, value, size, flags, position);
	if (_readonly) return -EPERM;
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// find file
	hfsdirent ent;
	if (hfs_stat(NULL, hfspath, &ent) == -1) {
		free(hfspath);
		return -ENOENT;
	}
	
	if (strcmp(name, XATTR_FINDERINFO_NAME) == 0) {
		if (size != 32) {
			dprintf("setxattr: finder info is not 32 bytes\n");
			free(hfspath);
			return -ERANGE;
		}
		// write finder info to dirent
		if (ent.flags & HFS_ISDIR) {
			// directory
			ent.u.dir.rect.top =		OSReadBigInt16(value, 0);
			ent.u.dir.rect.left =		OSReadBigInt16(value, 2);
			ent.u.dir.rect.bottom =		OSReadBigInt16(value, 4);
			ent.u.dir.rect.right =		OSReadBigInt16(value, 6);
			ent.fdflags =				OSReadBigInt16(value, 8);
			ent.fdlocation.v =			OSReadBigInt16(value, 10);
			ent.fdlocation.h =			OSReadBigInt16(value, 12);
			ent.u.dir.view =			OSReadBigInt16(value, 14);
			// DXInfo
			((DXInfo*)(ent.u.dir.xinfo))->frScroll.v   = OSReadBigInt16(value, 16);
			((DXInfo*)(ent.u.dir.xinfo))->frScroll.h   = OSReadBigInt16(value, 18);
			((DXInfo*)(ent.u.dir.xinfo))->frOpenChain  = OSReadBigInt32(value, 20);
			((DXInfo*)(ent.u.dir.xinfo))->frUnused     = OSReadBigInt16(value, 24);
			((DXInfo*)(ent.u.dir.xinfo))->frComment    = OSReadBigInt16(value, 26);
			((DXInfo*)(ent.u.dir.xinfo))->frPutAway    = OSReadBigInt32(value, 28);
		} else {
			// regular file
			memcpy(ent.u.file.type, value, 4);
			memcpy(ent.u.file.creator, value+4, 4);
			ent.u.file.type[4] = ent.u.file.type[4] = '\0';
			ent.fdflags       = OSReadBigInt16(value, 8);
			ent.fdlocation.v  = OSReadBigInt16(value, 10);
			ent.fdlocation.h  = OSReadBigInt16(value, 12);
			ent.u.file.window = OSReadBigInt16(value, 14);
			// FXInfo
			((FXInfo*)(ent.u.file.xinfo))->fdIconID    = OSReadBigInt16(value, 16);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[0] = OSReadBigInt16(value, 18);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[1] = OSReadBigInt16(value, 20);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[2] = OSReadBigInt16(value, 22);
			((FXInfo*)(ent.u.file.xinfo))->fdUnused[3] = OSReadBigInt16(value, 24);
			((FXInfo*)(ent.u.file.xinfo))->fdComment   = OSReadBigInt16(value, 26);
			((FXInfo*)(ent.u.file.xinfo))->fdPutAway   = OSReadBigInt32(value, 28);
			// bless parent folder if it's a system file
			if ((strcmp(ent.u.file.type, "zsys") == 0) && (strcmp(ent.u.file.creator, "MACS") == 0) && (strcmp(ent.name, "System") == 0)) {
				// bless
				dprintf("setxattr: blessing folder %lu\n", ent.parid);
				hfsvolent volent;
				hfs_vstat(NULL, &volent);
				volent.blessed = ent.parid;
				hfs_vsetattr(NULL, &volent);
			}
		}
		// update file
		hfs_setattr(NULL, hfspath, &ent);
		free(hfspath);
		return 0;
	} else if (strcmp(name, XATTR_RESOURCEFORK_NAME) == 0 && (!(ent.flags & HFS_ISDIR))) {
		// resource fork
		// TODO: how are resource forks truncated?
		hfsfile *fp = hfs_open(NULL, hfspath);
		hfs_setfork(fp, 1);
		hfs_seek(fp, position, SEEK_SET);
		hfs_write(fp, value, size);
		hfs_close(fp);
		// the end
		free(hfspath);
		return 0;
	} else {
		free(hfspath);
		return 0;
	}
	
	free(hfspath);
	return -ENOATTR;
	
}
예제 #7
0
static int FuseHFS_getxattr(const char *path, const char *name, char *value, size_t size,
				uint32_t position) {
	//dprintf("getxattr %s %s %p %lu %u\n", path, name, value, size, position);
	
	// convert to hfs path
	char *hfspath = mkhfspath(path);
	if (hfspath == NULL) return -ENOENT;
	
	// find file
	hfsdirent ent;
	if (hfs_stat(NULL, hfspath, &ent) == -1) {
		free(hfspath);
		return -ENOENT;
	}
	
	
	if (strcmp(name, XATTR_FINDERINFO_NAME) == 0) {
		if (value == NULL) {
			free(hfspath);
			return 32;
		}
		if (size < 32) {
			free(hfspath);
			return -ERANGE;
		}
		// return finder info
		if (ent.flags & HFS_ISDIR) {
			// directory info
			OSWriteBigInt16(value, 0, ent.u.dir.rect.top);
			OSWriteBigInt16(value, 2, ent.u.dir.rect.left);
			OSWriteBigInt16(value, 4, ent.u.dir.rect.bottom);
			OSWriteBigInt16(value, 6, ent.u.dir.rect.right);
			OSWriteBigInt16(value, 8, ent.fdflags);
			OSWriteBigInt16(value, 10, ent.fdlocation.v);
			OSWriteBigInt16(value, 12, ent.fdlocation.h);
			OSWriteBigInt16(value, 14, ent.u.dir.view);
			// DXInfo
			OSWriteBigInt16(value, 16, ((DXInfo*)(ent.u.dir.xinfo))->frScroll.v);
			OSWriteBigInt16(value, 18, ((DXInfo*)(ent.u.dir.xinfo))->frScroll.h);
			OSWriteBigInt32(value, 20, ((DXInfo*)(ent.u.dir.xinfo))->frOpenChain);
			OSWriteBigInt16(value, 24, ((DXInfo*)(ent.u.dir.xinfo))->frUnused);
			OSWriteBigInt16(value, 26, ((DXInfo*)(ent.u.dir.xinfo))->frComment);
			OSWriteBigInt32(value, 28, ((DXInfo*)(ent.u.dir.xinfo))->frPutAway);		
		} else {
			// file info
			memcpy(value, ent.u.file.type, 4);
			memcpy(value+4, ent.u.file.creator, 4);
			OSWriteBigInt16(value, 8, ent.fdflags);
			OSWriteBigInt16(value, 10, ent.fdlocation.v);
			OSWriteBigInt16(value, 12, ent.fdlocation.h);
			OSWriteBigInt16(value, 14, ent.u.file.window);
			// FXInfo
			OSWriteBigInt16(value, 16, ((FXInfo*)(ent.u.file.xinfo))->fdIconID);
			OSWriteBigInt16(value, 18, ((FXInfo*)(ent.u.file.xinfo))->fdUnused[0]);
			OSWriteBigInt16(value, 20, ((FXInfo*)(ent.u.file.xinfo))->fdUnused[1]);
			OSWriteBigInt16(value, 22, ((FXInfo*)(ent.u.file.xinfo))->fdUnused[2]);
			OSWriteBigInt16(value, 24, ((FXInfo*)(ent.u.file.xinfo))->fdUnused[3]);
			OSWriteBigInt16(value, 26, ((FXInfo*)(ent.u.file.xinfo))->fdComment);
			OSWriteBigInt32(value, 28, ((FXInfo*)(ent.u.file.xinfo))->fdPutAway);
		}
		free(hfspath);
		return 32;
	} else if (strcmp(name, XATTR_RESOURCEFORK_NAME) == 0 && (!(ent.flags & HFS_ISDIR)) && ent.u.file.rsize) {
		// resource fork
		if (value == NULL) {
			free(hfspath);
			return ent.u.file.rsize-position;
		}
		int bw = ent.u.file.rsize-position;
		if (bw > size) bw = size;
		// copy resource fork
		hfsfile *fp = hfs_open(NULL, hfspath);
		hfs_setfork(fp, 1);
		hfs_seek(fp, position, SEEK_SET);
		hfs_read(fp, value, bw);
		hfs_close(fp);
		// the end
		free(hfspath);
		return bw;
	}
	
	free(hfspath);
	dprintf("getxattr: ENOATTR\n");
	return -ENOATTR;
}
예제 #8
0
TSK_FS_INFO *
tsk_fs_open(TSK_IMG_INFO * img_info, TSK_OFF_T offset,
    const TSK_TCHAR * type)
{

    /* We will try different file systems ... 
     * We need to try all of them in case more than one matches
     */
    if (type == NULL) {
        TSK_FS_INFO *fs_info, *fs_set = NULL;
        char *set = NULL;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fsopen: Auto detection mode at offset %" PRIuOFF "\n",
                offset);

        if ((fs_info =
                ntfs_open(img_info, offset, TSK_FS_INFO_TYPE_NTFS_AUTO,
                    1)) != NULL) {
            set = "NTFS";
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                fatfs_open(img_info, offset, TSK_FS_INFO_TYPE_FAT_AUTO,
                    1)) != NULL) {
            if (set == NULL) {
                set = "FAT";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "FAT or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ext2fs_open(img_info, offset, TSK_FS_INFO_TYPE_EXT_AUTO,
                    1)) != NULL) {
            if (set == NULL) {
                set = "EXT2/3";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "EXT2/3 or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ffs_open(img_info, offset,
                    TSK_FS_INFO_TYPE_FFS_AUTO)) != NULL) {
            if (set == NULL) {
                set = "UFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "UFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }


#if TSK_USE_HFS
        if ((fs_info =
                hfs_open(img_info, offset, TSK_FS_INFO_TYPE_HFS,
                    1)) != NULL) {
            if (set == NULL) {
                set = "HFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "HFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }
#endif

        if ((fs_info =
                iso9660_open(img_info, offset, TSK_FS_INFO_TYPE_ISO9660,
                    1)) != NULL) {
            if (set != NULL) {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "ISO9660 or %s", set);
                return NULL;
            }
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }


        if (fs_set == NULL) {
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNKTYPE;
            tsk_errstr[0] = '\0';
            tsk_errstr2[0] = '\0';
            return NULL;
        }
        return fs_set;
    }
    else {
        uint8_t ftype;
        ftype = tsk_fs_parse_type(type);

        switch (ftype & TSK_FS_INFO_TYPE_FS_MASK) {
        case TSK_FS_INFO_TYPE_FFS_TYPE:
            return ffs_open(img_info, offset, ftype);
        case TSK_FS_INFO_TYPE_EXT_TYPE:
            return ext2fs_open(img_info, offset, ftype, 0);
        case TSK_FS_INFO_TYPE_FAT_TYPE:
            return fatfs_open(img_info, offset, ftype, 0);
        case TSK_FS_INFO_TYPE_NTFS_TYPE:
            return ntfs_open(img_info, offset, ftype, 0);
        case TSK_FS_INFO_TYPE_ISO9660_TYPE:
            return iso9660_open(img_info, offset, ftype, 0);
#if 0
        case TSK_FS_INFO_TYPE_HFS_TYPE:
            return hfs_open(img_info, offset, ftype, 0);
#endif
        case TSK_FS_INFO_TYPE_RAW_TYPE:
            return rawfs_open(img_info, offset);
        case TSK_FS_INFO_TYPE_SWAP_TYPE:
            return swapfs_open(img_info, offset);
        case TSK_FS_INFO_TYPE_UNSUPP:
        default:
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNSUPTYPE;
            snprintf(tsk_errstr, TSK_ERRSTR_L, "%s", type);
            return NULL;
        }
    }
}
예제 #9
0
/**
 * \ingroup fslib
 * Tries to process data in a disk image at a given offset as a file system. 
 * Returns a structure that can be used for analysis and reporting. 
 *
 * @param a_img_info Disk image to analyze
 * @param a_offset Byte offset to start analyzing from
 * @param a_ftype Type of file system (or autodetect)
 *
 * @return NULL on error 
 */
TSK_FS_INFO *
tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset,
    TSK_FS_TYPE_ENUM a_ftype)
{
    if (a_img_info == NULL) {
        tsk_error_reset();
        tsk_errno = TSK_ERR_FS_ARG;
        snprintf(tsk_errstr, TSK_ERRSTR_L,
            "tsk_fs_open_img: Null image handle");
        return NULL;
    }

    /* We will try different file systems ... 
     * We need to try all of them in case more than one matches
     */
    if (a_ftype == TSK_FS_TYPE_DETECT) {
        TSK_FS_INFO *fs_info, *fs_set = NULL;
        char *set = NULL;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fsopen: Auto detection mode at offset %" PRIuOFF "\n",
                a_offset);

        if ((fs_info =
                ntfs_open(a_img_info, a_offset, TSK_FS_TYPE_NTFS_DETECT,
                    1)) != NULL) {
            set = "NTFS";
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                fatfs_open(a_img_info, a_offset, TSK_FS_TYPE_FAT_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "FAT";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "FAT or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ext2fs_open(a_img_info, a_offset, TSK_FS_TYPE_EXT_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "EXT2/3";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "EXT2/3 or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }

        if ((fs_info =
                ffs_open(a_img_info, a_offset,
                    TSK_FS_TYPE_FFS_DETECT)) != NULL) {
            if (set == NULL) {
                set = "UFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "UFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }


#if TSK_USE_HFS
        if ((fs_info =
                hfs_open(a_img_info, a_offset, TSK_FS_TYPE_HFS_DETECT,
                    1)) != NULL) {
            if (set == NULL) {
                set = "HFS";
                fs_set = fs_info;
            }
            else {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "HFS or %s", set);
                return NULL;
            }
        }
        else {
            tsk_error_reset();
        }
#endif

        if ((fs_info =
                iso9660_open(a_img_info, a_offset,
                    TSK_FS_TYPE_ISO9660_DETECT, 1)) != NULL) {
            if (set != NULL) {
                fs_set->close(fs_set);
                fs_info->close(fs_info);
                tsk_error_reset();
                tsk_errno = TSK_ERR_FS_UNKTYPE;
                snprintf(tsk_errstr, TSK_ERRSTR_L, "ISO9660 or %s", set);
                return NULL;
            }
            fs_set = fs_info;
        }
        else {
            tsk_error_reset();
        }


        if (fs_set == NULL) {
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNKTYPE;
            tsk_errstr[0] = '\0';
            tsk_errstr2[0] = '\0';
            return NULL;
        }
        return fs_set;
    }
    else {
        if (TSK_FS_TYPE_ISNTFS(a_ftype))
            return ntfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISFAT(a_ftype))
            return fatfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISFFS(a_ftype))
            return ffs_open(a_img_info, a_offset, a_ftype);
        else if (TSK_FS_TYPE_ISEXT(a_ftype))
            return ext2fs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISHFS(a_ftype))
            return hfs_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISISO9660(a_ftype))
            return iso9660_open(a_img_info, a_offset, a_ftype, 0);
        else if (TSK_FS_TYPE_ISRAW(a_ftype))
            return rawfs_open(a_img_info, a_offset);
        else if (TSK_FS_TYPE_ISSWAP(a_ftype))
            return swapfs_open(a_img_info, a_offset);
        else {
            tsk_error_reset();
            tsk_errno = TSK_ERR_FS_UNSUPTYPE;
            snprintf(tsk_errstr, TSK_ERRSTR_L, "%X", (int) a_ftype);
            return NULL;
        }
    }
}
예제 #10
0
파일: hfs.c 프로젝트: Excito/parted
PedFileSystem*
hfsplus_open (PedGeometry* geom)
{
	uint8_t			buf[PED_SECTOR_SIZE_DEFAULT];
	PedFileSystem*		fs;
	HfsPVolumeHeader*	vh;
	HfsPPrivateFSData* 	priv_data;
	PedGeometry*		wrapper_geom;
	unsigned int		map_sectors;

	if (!hfsc_can_use_geom (geom))
		return NULL;

	fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
	if (!fs) goto hpo;
	vh = (HfsPVolumeHeader*) ped_malloc (sizeof (HfsPVolumeHeader));
	if (!vh) goto hpo_fs;
	priv_data = (HfsPPrivateFSData*)ped_malloc (sizeof (HfsPPrivateFSData));
	if (!priv_data) goto hpo_vh;

	fs->geom = ped_geometry_duplicate (geom);
	if (!fs->geom) goto hpo_pd;
	fs->type_specific = (void*) priv_data;

	if ((wrapper_geom = hfs_and_wrapper_probe (geom))) {
		HfsPrivateFSData* 	hfs_priv_data;
		PedSector		abs_sect, length;
		unsigned int		bs;

		ped_geometry_destroy (wrapper_geom);
		priv_data->wrapper = hfs_open(geom);
		if (!priv_data->wrapper) goto hpo_gm;
		hfs_priv_data = (HfsPrivateFSData*)
			priv_data->wrapper->type_specific;
		bs = PED_BE32_TO_CPU (hfs_priv_data->mdb->block_size)
		     / PED_SECTOR_SIZE_DEFAULT;
		abs_sect = (PedSector) geom->start
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->start_block)
			   + (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.start_block )
			                 * bs;
		length = (PedSector) PED_BE16_TO_CPU (
					    hfs_priv_data->mdb->old_new
					    .embedded.location.block_count)
				     * bs;
		priv_data->plus_geom = ped_geometry_new (geom->dev, abs_sect,
							 length);
		if (!priv_data->plus_geom) goto hpo_wr;
		priv_data->free_geom = 1;
	} else {
		priv_data->wrapper = NULL;
		priv_data->plus_geom = fs->geom;
		priv_data->free_geom = 0;
	}

	if (!ped_geometry_read (priv_data->plus_geom, buf, 2, 1)) goto hpo_pg;
	memcpy (vh, buf, sizeof (HfsPVolumeHeader));
	priv_data->vh = vh;

	if (vh->signature != PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->signature != PED_CPU_TO_BE16(HFSX_SIGNATURE)) {
		ped_exception_throw (
			PED_EXCEPTION_BUG,
			PED_EXCEPTION_CANCEL,
			_("No valid HFS[+X] signature has been found while "
			  "opening."));
		goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSP_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSP_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFS+ isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	if (vh->signature == PED_CPU_TO_BE16(HFSX_SIGNATURE)
	    && vh->version != PED_CPU_TO_BE16(HFSX_VERSION)) {
		if (ped_exception_throw (
			PED_EXCEPTION_NO_FEATURE,
			PED_EXCEPTION_IGNORE_CANCEL,
			_("Version %d of HFSX isn't supported."),
			PED_BE16_TO_CPU(vh->version))
				!= PED_EXCEPTION_IGNORE)
			goto hpo_pg;
	}

	priv_data->jib_start_block = 0;
	priv_data->jl_start_block = 0;
	if (vh->attributes & PED_CPU_TO_BE32(1<<HFSP_JOURNALED)) {
		if (!hfsj_replay_journal(fs))
			goto hpo_pg;
	}

	priv_data->bad_blocks_loaded = 0;
	priv_data->bad_blocks_xtent_nb = 0;
	priv_data->bad_blocks_xtent_list = NULL;
	priv_data->extents_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_XTENT_ID),
				   vh->extents_file.extents,
				   PED_BE64_TO_CPU (
					vh->extents_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->extents_file) goto hpo_pg;
	priv_data->catalog_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFS_CATALOG_ID),
				   vh->catalog_file.extents,
				   PED_BE64_TO_CPU (
					vh->catalog_file.logical_size )
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->catalog_file) goto hpo_ce;
	priv_data->attributes_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ATTRIB_ID),
				   vh->attributes_file.extents,
				   PED_BE64_TO_CPU (
					vh->attributes_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->attributes_file) goto hpo_cc;

	map_sectors = ( PED_BE32_TO_CPU (vh->total_blocks)
	                + PED_SECTOR_SIZE_DEFAULT * 8 - 1 )
		      / (PED_SECTOR_SIZE_DEFAULT * 8);
	priv_data->dirty_alloc_map = (uint8_t*)
		ped_malloc ((map_sectors + 7) / 8);
	if (!priv_data->dirty_alloc_map) goto hpo_cl;
	memset(priv_data->dirty_alloc_map, 0, (map_sectors + 7) / 8);
	priv_data->alloc_map = (uint8_t*)
		ped_malloc (map_sectors * PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->alloc_map) goto hpo_dm;

	priv_data->allocation_file =
		hfsplus_file_open (fs, PED_CPU_TO_BE32 (HFSP_ALLOC_ID),
				   vh->allocation_file.extents,
				   PED_BE64_TO_CPU (
					vh->allocation_file.logical_size)
				   / PED_SECTOR_SIZE_DEFAULT);
	if (!priv_data->allocation_file) goto hpo_am;
	if (!hfsplus_file_read (priv_data->allocation_file,
				priv_data->alloc_map, 0, map_sectors)) {
		hfsplus_close(fs);
		return NULL;
	}

	fs->type = &hfsplus_type;
	fs->checked = ((PED_BE32_TO_CPU (vh->attributes) >> HFS_UNMOUNTED) & 1)
	      && !((PED_BE32_TO_CPU (vh->attributes) >> HFSP_INCONSISTENT) & 1);

	return fs;

/*--- clean error handling ---*/
hpo_am: free(priv_data->alloc_map);
hpo_dm: free(priv_data->dirty_alloc_map);
hpo_cl: hfsplus_file_close (priv_data->attributes_file);
hpo_cc:	hfsplus_file_close (priv_data->catalog_file);
hpo_ce:	hfsplus_file_close (priv_data->extents_file);
hpo_pg: if (priv_data->free_geom) ped_geometry_destroy (priv_data->plus_geom);
hpo_wr: if (priv_data->wrapper) hfs_close(priv_data->wrapper);
hpo_gm: ped_geometry_destroy (fs->geom);
hpo_pd: free(priv_data);
hpo_vh: free(vh);
hpo_fs: free(fs);
hpo:	return NULL;
}
예제 #11
0
파일: desktop.c 프로젝트: art4711/bitrig
int
make_desktop(hfsvol *vol, int end)
/* hfsvol  *vol;				   Mac volume */
{
	hfsfile		*hfp;			/* Mac file */
	hfsdirent	ent;			/* Mac finderinfo */
	unsigned short	clps;			/* clump size */
	unsigned short	blks;			/* blocks in a clump */
	unsigned char	*blk;			/* user data */
	int		i;

	/* set up default directory entries - not all these fields
	   are needed, but we'll set them up anyway ... */
	ent.rsize = 0;				/* resource size == 0 */
	strcpy(ent.creator, DBFC);		/* creator */
	strcpy(ent.type, DBT);			/* type */
	ent.crdate = ent.mddate = time(0);	/* date is now */
	ent.fdflags = HFS_FNDR_ISINVISIBLE;	/* invisible files */

	/* clear the DB file */
	blk = hce->hfs_ce + hce->hfs_ce_size*HFS_BLOCKSZ;
	blks = hce->hfs_dt_size;
	clps = blks*HFS_BLOCKSZ;

	memset(blk, 0, clps);

	/* create "Desktop DB" (if it doesn't exist) */
	if(hfs_create(vol, DB, ent.type, ent.creator) == 0)
	{
	    /* DB file size from hce_mem info */
	    /* set up "Desktop DB" data - following found by od'ing
	       the "Desktop DB" file */
	    d_putw(blk+8, 0x100);
	    d_putw(blk+10, 0x3);

	    d_putw(blk+32, 0x200);
	    d_putw(blk+34, 0x25);

	    d_putl(blk+36, blks);
	    d_putl(blk+40, blks - 1);

	    d_putw(blk+48, clps);
	    d_putw(blk+50, 0xff);

	    d_putw(blk+120, 0x20a);
	    d_putw(blk+122, 0x100);

	    d_putw(blk+248, 0x8000);

	    d_putl(blk+504, 0x1f800f8);
	    d_putl(blk+508, 0x78000e);

	    /* entries for "Desktop DB" */
	    ent.dsize = clps;			/* size = clump size */
	
	    /* open file */
	    if((hfp = hfs_open(vol, DB)) == 0)
		err(1, hfs_error);

	    /* "write" file */
	    write_fork(hfp, clps);

	    /* set DB file attributes */
	    if (hfs_fsetattr(hfp, &ent) < 0)
		err(1, hfs_error);

	    /* find the real start of the file */
	    end += hce->hfs_ce_size;

	    /* close DB file */
	    if (hfs_close(hfp, end, 0) < 0)
		err(1, hfs_error);
	}
	else
	{
	    /* if it already exists, then make sure it has the correct
	       type/creator and flags */
	    if(hfs_setattr(vol, DB, &ent) < 0)
		err(1, hfs_error);
	}

	/* setup "Desktop DF" file as an empty file */
	strcpy(ent.type, DFT);			/* type */
	ent.dsize = 0;				/* empty */

	/* create DF file (if it doesn't exist) - no need to open it */
	hfs_create(vol, DF, ent.type, ent.creator);

	/* set DB file attributes */
	if (hfs_setattr(vol, DF, &ent) < 0)
	    err(1, hfs_error);
	return 0;
}
예제 #12
0
파일: volume.c 프로젝트: ajinkya93/OpenBSD
/*	copy_to_mac_vol: copy all files in a directory to corresponding
**			 Mac folder.
**
**	Files are copied recursively to corresponding folders on the Mac
**	volume. The caller routine needs to do a hfs_chdir before calling this
**	routine. 
*/
int FDECL2(copy_to_mac_vol, hfsvol *, vol, struct directory *, node)
{
	struct directory_entry * s_entry;	/* ISO directory entry */
	struct directory_entry * s_entry1;	/* tmp ISO directory entry */
	struct directory *dpnt;			/* ISO directory */

	hfsfile *hfp;				/* HFS file */
	hfsdirent *ent;				/* HFS file entities */
	long id;				/* current HFS folder */
	long dext, rext;			/* real data/rsrc start blk */
	int ret;				/* result code */
	int new_name;				/* HFS file has modified name */

	int	tens;
	int	digits;
	int	i;

	/* store the current HFS directory ID */
	if ((id = hfs_getcwd(vol)) == 0)
	    return(-1);

	if (verbose > 1)
	    fprintf(stderr,"HFS scanning %s\n", node->whole_name);

	/* loop through the ISO directory entries and process files */
	for(s_entry = node->contents; s_entry; s_entry = s_entry->next)
	{
	    /* ignore directory and associated (rsrc) files */
	    if(s_entry->isorec.flags[0])
		    continue;

	    /* ignore any non-Mac type file */
	    if(!s_entry->hfs_ent)
		    continue;

#ifdef DEBUG
	    fprintf(stderr," Name = %s", s_entry->whole_name); 
	    fprintf(stderr,"   Startb =  %d\n", s_entry->starting_block);
#endif /* DEBUG */

	    ent = s_entry->hfs_ent;

	    /* create file */
	    i = HFS_MAX_FLEN - strlen(ent->name);
	    new_name = 0;
	    tens = TEN;
	    digits = 1;

	    while (1)
	    {
		/* try to open file - if it exists, then append '_' to
		   the name and try again */
		errno = 0;
		if ((hfs_create(vol, ent->name, ent->type, ent->creator)) < 0)
		{
		    if (errno != EEXIST )
		    {
			/* not an "exist" error, or we can't append as
			   the filename is already HFS_MAX_FLEN chars */
			snprintf(hce->error, ERROR_SIZE, 
				"can't HFS create file %s",
				s_entry->whole_name);
			return(-1);
		    }
		    else if (i == 0)
		    {
			/* File name at max HFS length - make unique name */
			if (!new_name) new_name++;

			sprintf(ent->name + HFS_MAX_FLEN - digits - 1,
					"%s%d", LCHAR, new_name);
			new_name++;
			if (new_name == tens) {
			    tens *= TEN;
			    digits++;
			}
		    }
		    else
		    {
			/* append '_' to get new name */
			strcat(ent->name, LCHAR);
			i--;
			new_name = 1;
		    }
		}
		else
		    break;
	    }

	    /* warn that we have a new name */
	    if (new_name && verbose > 0)
	    {
		fprintf(stderr, "Using HFS name: %s for %s\n", ent->name,
			s_entry->whole_name);
	    }

	    /* open file */
	    if ((hfp = hfs_open(vol, ent->name)) == 0)
	    {
		snprintf(hce->error, ERROR_SIZE, "can't HFS open %s", 
		    s_entry->whole_name);
		return(-1);
	    }

	    /* if it has a data fork, then "write" it out */
	    if (ent->dsize)
		write_fork(hfp, ent->dsize);

	    /* if it has a resource fork, set the fork and "write" it out */
	    if (ent->rsize)
	    {
		if ((hfs_setfork(hfp, 1)) < 0)
		    return(-1);
		write_fork(hfp, ent->rsize);
	    }

	    /* update any HFS file attributes */
	    if ((hfs_fsetattr(hfp, ent)) < 0)
	    {
		snprintf(hce->error, ERROR_SIZE, "can't HFS set attributes %s",
			s_entry->whole_name);
		return(-1);
	    }

	    /* get the ISO starting block of data fork (may be zero)
	       and convert to the equivalent HFS block */
	    if (ent->dsize)
		dext = s_entry->starting_block * BLK_CONV;
	    else
		dext = 0;

	    /* if the file has a resource fork (associated file), get it's
	       ISO starting block and convert as above */
	    if (s_entry->assoc && ent->rsize)
		rext = s_entry->assoc->starting_block * BLK_CONV;
	    else
		rext = 0;

	    /* close the file and update the starting blocks */
	    if (hfs_close(hfp, dext, rext) < 0)
	    {
		snprintf(hce->error, ERROR_SIZE, "can't HFS close file %s",
			s_entry->whole_name);
		return(-1);
	    }
	}

	/* process sub-directories  - have a slight problem here,
	   if the directory had been relocated, then we need to find
	   the real directory - we do this by first finding the real
	   directory_entry, and then finding it's directory info */

	/* following code taken from joliet.c */
	for(s_entry=node->contents;s_entry;s_entry=s_entry->next)
	{
	    if((s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
	    {
		/* if the directory has been reloacted, then search the
		   relocated directory for the real entry */
		for(s_entry1=reloc_dir->contents;s_entry1;s_entry1=s_entry1->next)
		{
		    if(s_entry1->parent_rec == s_entry)
			break;
		}

		/* have a problem - can't find the real directory */
		if(s_entry1 == NULL)
		{
		    snprintf(hce->error, ERROR_SIZE,
		    	"can't locate relocated directory %s", 
			s_entry->whole_name);
		    return(-1);
		}
	    }
	    else
		s_entry1 = s_entry;

	    /* now have the correct entry - now find the actual directory */
	    if ((s_entry1->isorec.flags[0] & 2) && strcmp(s_entry1->name,".") && strcmp(s_entry1->name,".."))
	    {
		if((s_entry->de_flags & RELOCATED_DIRECTORY) != 0)
		    dpnt = reloc_dir->subdir;
		else
		    dpnt = node->subdir;

		while(1)
		{
		    if (dpnt->self == s_entry1)
			break;
		    dpnt = dpnt->next;
		    if(!dpnt)
		    {
			snprintf(hce->error, ERROR_SIZE, 
			    "can't find directory location %s", 
			    s_entry1->whole_name);
			return (-1);
		    }
		}
		/* now have the correct directory - so do the HFS stuff */
		ent = dpnt->hfs_ent;

		/* if we don't have hfs entries, then this is a "deep"
		   directory - this will be processed later */
		if (!ent)
		    continue;

		/* make sub-folder */
		i = HFS_MAX_FLEN - strlen(ent->name);
		new_name = 0;
		tens = TEN;
		digits = 1;

		while (1)
		{
		    /* try to create new directory  - if it exists, then
		       append '_' to the name and try again */
		    errno = 0;
		    if (hfs_mkdir(vol, ent->name) < 0)
		    {
			if (errno != EEXIST)
			{
			    /* not an "exist" error, or we can't append as
			       the filename is already HFS_MAX_FLEN chars */
			    snprintf(hce->error, ERROR_SIZE, 
			    	"can't HFS create folder %s",
				s_entry->whole_name);
			    return(-1);
			}
			else if (i == 0)
			{
			    /* File name at max HFS length - make unique name */
			    if (!new_name) new_name++;

			    sprintf(ent->name + HFS_MAX_FLEN - digits - 1,
					"%s%d", LCHAR, new_name);
			    new_name++;
			    if (new_name == tens) {
				tens *= TEN;
				digits++;
			    }
			}
			else
			{
			    /* append '_' to get new name */
			    strcat(ent->name, LCHAR);
			    i--;
			    new_name = 1;
			}
		    }
		    else
			break;
		}

		/* warn that we have a new name */
		if (new_name && verbose > 0)
		{
		    fprintf(stderr, "Using HFS name: %s for %s\n", ent->name,
			s_entry->whole_name);
		}

		/* see if we need to "bless" this folder */
		if (hfs_bless && strcmp(s_entry->whole_name, hfs_bless) == 0) {
		    hfs_stat(vol, ent->name, ent);
		    hfs_vsetbless(vol, ent->cnid);
		    if (verbose > 0) {
			fprintf(stderr, "Blessing %s (%s)\n",
				ent->name, s_entry->whole_name);
		    }
		    /* stop any further checks */
		    hfs_bless = NULL;
		}

		/* change to sub-folder */
		if (hfs_chdir(vol, ent->name) < 0)
		    return(-1);

		/* recursively copy files ... */
		ret = copy_to_mac_vol(vol, dpnt);
		if (ret < 0)
		    return(ret);

		/* change back to this folder */
		if (hfs_setcwd(vol, id) < 0)
		    return(-1);
	    }
	}

	return(0);
}
예제 #13
0
/**
 * \ingroup fslib
 * Tries to process data in a disk image at a given offset as a file system.
 * Returns a structure that can be used for analysis and reporting.
 *
 * @param a_img_info Disk image to analyze
 * @param a_offset Byte offset to start analyzing from
 * @param a_ftype Type of file system (or autodetect)
 *
 * @return NULL on error
 */
TSK_FS_INFO *
tsk_fs_open_img(TSK_IMG_INFO * a_img_info, TSK_OFF_T a_offset,
    TSK_FS_TYPE_ENUM a_ftype)
{
    TSK_FS_INFO *fs_info;

    const struct {
        char* name;
        TSK_FS_INFO* (*open)(TSK_IMG_INFO*, TSK_OFF_T,
                                 TSK_FS_TYPE_ENUM, uint8_t);
        TSK_FS_TYPE_ENUM type;
    } FS_OPENERS[] = {
        { "NTFS",     ntfs_open,    TSK_FS_TYPE_NTFS_DETECT    },
        { "FAT",      fatfs_open,   TSK_FS_TYPE_FAT_DETECT     },
        { "EXT2/3/4", ext2fs_open,  TSK_FS_TYPE_EXT_DETECT     },
        { "UFS",      ffs_open,     TSK_FS_TYPE_FFS_DETECT     },
        { "YAFFS2",   yaffs2_open,  TSK_FS_TYPE_YAFFS2_DETECT  },
#if TSK_USE_HFS
        { "HFS",      hfs_open,     TSK_FS_TYPE_HFS_DETECT     },
#endif
        { "ISO9660",  iso9660_open, TSK_FS_TYPE_ISO9660_DETECT }
    };

    if (a_img_info == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr("tsk_fs_open_img: Null image handle");
        return NULL;
    }

    /* We will try different file systems ...
     * We need to try all of them in case more than one matches
     */
    if (a_ftype == TSK_FS_TYPE_DETECT) {
        unsigned long i;
        const char *name_first = "";
        TSK_FS_INFO *fs_first = NULL;

        if (tsk_verbose)
            tsk_fprintf(stderr,
                "fsopen: Auto detection mode at offset %" PRIuOFF "\n",
                a_offset);

        for (i = 0; i < sizeof(FS_OPENERS)/sizeof(FS_OPENERS[0]); ++i) {
            if ((fs_info = FS_OPENERS[i].open(
                    a_img_info, a_offset, FS_OPENERS[i].type, 1)) != NULL) {
                // fs opens as type i
                if (fs_first == NULL) {
                    // first success opening fs
                    name_first = FS_OPENERS[i].name;
                    fs_first = fs_info;
                }
                else {
                    // second success opening fs, which means we
                    // cannot autodetect the fs type and must give up
                    fs_first->close(fs_first);
                    fs_info->close(fs_info);
                    tsk_error_reset();
                    tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
                    tsk_error_set_errstr(
                        "%s or %s", FS_OPENERS[i].name, name_first);
                    return NULL;
                }
            }
            else {
                // fs does not open as type i
                tsk_error_reset();
            }
        }

        if (fs_first == NULL) {
            tsk_error_reset();
            tsk_error_set_errno(TSK_ERR_FS_UNKTYPE);
        }

        return fs_first;
    }
    else if (TSK_FS_TYPE_ISNTFS(a_ftype)) {
        return ntfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISFAT(a_ftype)) {
        return fatfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISFFS(a_ftype)) {
        return ffs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISEXT(a_ftype)) {
        return ext2fs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISHFS(a_ftype)) {
        return hfs_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISISO9660(a_ftype)) {
        return iso9660_open(a_img_info, a_offset, a_ftype, 0);
    }
    else if (TSK_FS_TYPE_ISRAW(a_ftype)) {
        return rawfs_open(a_img_info, a_offset);
    }
    else if (TSK_FS_TYPE_ISSWAP(a_ftype)) {
        return swapfs_open(a_img_info, a_offset);
    }
    else if (TSK_FS_TYPE_ISYAFFS2(a_ftype)) {
        return yaffs2_open(a_img_info, a_offset, a_ftype, 0);
    }
    tsk_error_reset();
    tsk_error_set_errno(TSK_ERR_FS_UNSUPTYPE);
    tsk_error_set_errstr("%X", (int) a_ftype);
    return NULL;
}