Beispiel #1
0
static struct grub_archelp_data *
grub_cbfs_mount (grub_disk_t disk)
{
  struct cbfs_file hd;
  struct grub_archelp_data *data = NULL;
  grub_uint32_t ptr;
  grub_off_t header_off;
  struct cbfs_header head;

  if (grub_disk_get_size (disk) == GRUB_DISK_SIZE_UNKNOWN)
    goto fail;

  if (grub_disk_read (disk, grub_disk_get_size (disk) - 1,
		      GRUB_DISK_SECTOR_SIZE - sizeof (ptr),
		      sizeof (ptr), &ptr))
    goto fail;

  ptr = grub_cpu_to_le32 (ptr);
  header_off = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    + (grub_int32_t) ptr;

  if (grub_disk_read (disk, 0, header_off,
		      sizeof (head), &head))
    goto fail;

  if (!validate_head (&head))
    goto fail;

  data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data));
  if (!data)
    goto fail;

  data->cbfs_start = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    - (grub_be_to_cpu32 (head.romsize) - grub_be_to_cpu32 (head.offset));
  data->cbfs_end = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS)
    - grub_be_to_cpu32 (head.bootblocksize);
  data->cbfs_align = grub_be_to_cpu32 (head.align);

  if (data->cbfs_start >= (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS))
    goto fail;
  if (data->cbfs_end > (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS))
    data->cbfs_end = (grub_disk_get_size (disk) << GRUB_DISK_SECTOR_BITS);

  data->next_hofs = data->cbfs_start;

  if (grub_disk_read (disk, 0, data->cbfs_start, sizeof (hd), &hd))
    goto fail;

  if (grub_memcmp (hd.magic, CBFS_FILE_MAGIC, sizeof (CBFS_FILE_MAGIC) - 1))
    goto fail;

  data->disk = disk;

  return data;

fail:
  grub_free (data);
  grub_error (GRUB_ERR_BAD_FS, "not a cbfs filesystem");
  return 0;
}
Beispiel #2
0
static grub_disk_addr_t
grub_affs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
{
  int links;
  grub_uint32_t pos;
  int block = node->block;
  struct grub_affs_file file;
  struct grub_affs_data *data = node->data;
  grub_uint32_t mod;

  /* Find the block that points to the fileblock we are looking up by
     following the chain until the right table is reached.  */
  for (links = grub_divmod64 (fileblock, data->htsize, &mod); links; links--)
    {
      grub_disk_read (data->disk, block + data->blocksize - 1,
		      data->blocksize * (GRUB_DISK_SECTOR_SIZE
					 - GRUB_AFFS_FILE_LOCATION),
		      sizeof (file), &file);
      if (grub_errno)
	return 0;

      block = grub_be_to_cpu32 (file.extension);
    }

  /* Translate the fileblock to the block within the right table.  */
  fileblock = mod;
  grub_disk_read (data->disk, block,
		  GRUB_AFFS_BLOCKPTR_OFFSET
		  + (data->htsize - fileblock - 1) * sizeof (pos),
		  sizeof (pos), &pos);
  if (grub_errno)
    return 0;

  return grub_be_to_cpu32 (pos);
}
Beispiel #3
0
static struct grub_sfs_data *
grub_sfs_mount (grub_disk_t disk)
{
  struct grub_sfs_data *data;
  struct grub_sfs_objc *rootobjc;
  char *rootobjc_data = 0;
  unsigned int blk;

  data = grub_malloc (sizeof (*data));
  if (!data)
    return 0;

  /* Read the rootblock.  */
  grub_disk_read (disk, 0, 0, sizeof (struct grub_sfs_rblock),
		  (char *) &data->rblock);
  if (grub_errno)
    goto fail;

  /* Make sure this is a sfs filesystem.  */
  if (grub_strncmp ((char *) (data->rblock.header.magic), "SFS", 4))
    {
      grub_error (GRUB_ERR_BAD_FS, "not a sfs filesystem");
      goto fail;
    }

  data->blocksize = grub_be_to_cpu32 (data->rblock.blocksize);
  rootobjc_data = grub_malloc (data->blocksize);
  if (! rootobjc_data)
    goto fail;

  /* Read the root object container.  */
  grub_disk_read (disk, grub_be_to_cpu32 (data->rblock.rootobject), 0,
		  data->blocksize, rootobjc_data);
  if (grub_errno)
    goto fail;

  rootobjc = (struct grub_sfs_objc *) rootobjc_data;

  blk = grub_be_to_cpu32 (rootobjc->objects[0].file_dir.dir.dir_objc);
  data->diropen.size = 0;
  data->diropen.block = blk;
  data->diropen.data = data;
  data->disk = disk;
  data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));

  return data;

 fail:
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not an sfs filesystem");

  grub_free (data);
  grub_free (rootobjc_data);
  return 0;
}
static grub_err_t
grub_cpio_find_file (struct grub_archelp_data *data, char **name,
		     grub_int32_t *mtime, grub_uint32_t *mode)
{
  struct head hd;
  grub_size_t namesize;
  grub_uint32_t modeval;

  data->hofs = data->next_hofs;

  if (grub_disk_read (data->disk, 0, data->hofs, sizeof (hd), &hd))
    return grub_errno;

  if (grub_memcmp (hd.magic, MAGIC, sizeof (hd.magic)) != 0
#ifdef MAGIC2
      && grub_memcmp (hd.magic, MAGIC2, sizeof (hd.magic)) != 0
#endif
      )
    return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
  data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
  if (mtime)
    *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
  modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
  namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));

  if (mode)
    *mode = modeval;

  *name = grub_malloc (namesize + 1);
  if (*name == NULL)
    return grub_errno;

  if (grub_disk_read (data->disk, 0, data->hofs + sizeof (hd),
		      namesize, *name))
    {
      grub_free (*name);
      return grub_errno;
    }
  (*name)[namesize] = 0;

  if (data->size == 0 && modeval == 0 && namesize == 11
      && grub_memcmp(*name, "TRAILER!!!", 11) == 0)
    {
      *mode = GRUB_ARCHELP_ATTR_END;
      grub_free (*name);
      return GRUB_ERR_NONE;
    }

  data->dofs = data->hofs + ALIGN_CPIO (sizeof (hd) + namesize);
  data->next_hofs = data->dofs + ALIGN_CPIO (data->size);
  return GRUB_ERR_NONE;
}
Beispiel #5
0
static struct grub_hfsplus_data *
grub_hfsplus_mount (grub_disk_t disk)
{
  struct grub_hfsplus_data *data;
  struct grub_hfsplus_btheader header;
  struct grub_hfsplus_btnode node;
  grub_uint16_t magic;
  union {
    struct grub_hfs_sblock hfs;
    struct grub_hfsplus_volheader hfsplus;
  } volheader;

  data = grub_malloc (sizeof (*data));
  if (!data)
    return 0;

  data->disk = disk;

  /* Read the bootblock.  */
  grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
		  &volheader);
  if (grub_errno)
    goto fail;

  data->embedded_offset = 0;
  if (grub_be_to_cpu16 (volheader.hfs.magic) == GRUB_HFS_MAGIC)
    {
      grub_disk_addr_t extent_start;
      grub_disk_addr_t ablk_size;
      grub_disk_addr_t ablk_start;

      /* See if there's an embedded HFS+ filesystem.  */
      if (grub_be_to_cpu16 (volheader.hfs.embed_sig) != GRUB_HFSPLUS_MAGIC)
	{
	  grub_error (GRUB_ERR_BAD_FS, "not a HFS+ filesystem");
	  goto fail;
	}

      /* Calculate the offset needed to translate HFS+ sector numbers.  */
      extent_start = grub_be_to_cpu16 (volheader.hfs.embed_extent.first_block);
      ablk_size = grub_be_to_cpu32 (volheader.hfs.blksz);
      ablk_start = grub_be_to_cpu16 (volheader.hfs.first_block);
      data->embedded_offset = (ablk_start
			       + extent_start
			       * (ablk_size >> GRUB_DISK_SECTOR_BITS));

      grub_disk_read (disk, data->embedded_offset + GRUB_HFSPLUS_SBLOCK, 0,
		      sizeof (volheader), &volheader);
      if (grub_errno)
	goto fail;
    }
Beispiel #6
0
/* Iterate over the susp entries, starting with block SUA_BLOCK on the
   offset SUA_POS with a size of SUA_SIZE bytes.  Hook is called for
   every entry.  */
static grub_err_t
grub_iso9660_susp_iterate (struct grub_iso9660_data *data,
			   int sua_block, int sua_pos, int sua_size,
			   grub_err_t (*hook)
			   (struct grub_iso9660_susp_entry *entry))
{
  char *sua;
  struct grub_iso9660_susp_entry *entry;

  auto grub_err_t load_sua (void);

  /* Load a part of the System Usage Area.  */
  grub_err_t load_sua (void)
    {
      sua = grub_malloc (sua_size);
      if (!sua)
	return grub_errno;

      if (grub_disk_read (data->disk, sua_block, sua_pos,
			  sua_size, sua))
	return grub_errno;

      entry = (struct grub_iso9660_susp_entry *) sua;
      return 0;
    }
Beispiel #7
0
/* Read LEN bytes from the file described by DATA starting with byte
   POS.  Return the amount of read bytes in READ.  */
static grub_ssize_t
grub_hfs_read_file (struct grub_hfs_data *data,
		    void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector,
				       unsigned offset, unsigned length),
		    grub_off_t pos, grub_size_t len, char *buf)
{
  grub_off_t i;
  grub_off_t blockcnt;

  blockcnt = grub_divmod64 (((len + pos)
			     + data->blksz - 1), data->blksz, 0);

  for (i = grub_divmod64 (pos, data->blksz, 0); i < blockcnt; i++)
    {
      grub_disk_addr_t blknr;
      grub_off_t blockoff;
      grub_off_t blockend = data->blksz;

      int skipfirst = 0;

      grub_divmod64 (pos, data->blksz, &blockoff);

      blknr = grub_hfs_block (data, data->extents, data->fileid, i, 1);
      if (grub_errno)
	return -1;

      /* Last block.  */
      if (i == blockcnt - 1)
	{
	  grub_divmod64 ((len + pos), data->blksz, &blockend);

	  /* The last portion is exactly EXT2_BLOCK_SIZE (data).  */
	  if (! blockend)
	    blockend = data->blksz;
	}

      /* First block.  */
      if (i == grub_divmod64 (pos, data->blksz, 0))
	{
	  skipfirst = blockoff;
	  blockend -= skipfirst;
	}

      /* If the block number is 0 this block is not stored on disk but
	 is zero filled instead.  */
      if (blknr)
	{
	  data->disk->read_hook = read_hook;
	  grub_disk_read (data->disk, blknr, skipfirst,
			  blockend, buf);
	  data->disk->read_hook = 0;
	  if (grub_errno)
	    return -1;
	}

      buf += data->blksz - skipfirst;
    }

  return len;
}
static struct grub_archelp_data *
grub_cpio_mount (grub_disk_t disk)
{
  struct head hd;
  struct grub_archelp_data *data;

  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
    goto fail;

  if (grub_memcmp (hd.magic, MAGIC, sizeof (MAGIC) - 1)
#ifdef MAGIC2
      && grub_memcmp (hd.magic, MAGIC2, sizeof (MAGIC2) - 1)
#endif
      )
    goto fail;

  data = (struct grub_archelp_data *) grub_zalloc (sizeof (*data));
  if (!data)
    goto fail;

  data->disk = disk;

  return data;

fail:
  grub_error (GRUB_ERR_BAD_FS, "not a " FSNAME " filesystem");
  return 0;
}
Beispiel #9
0
static grub_err_t
sun_pc_partition_map_iterate (grub_disk_t disk,
			      int (*hook) (grub_disk_t disk,
					   const grub_partition_t partition))
{
  grub_partition_t p;
  struct grub_sun_pc_block block;
  int partnum;
  grub_err_t err;

  p = (grub_partition_t) grub_zalloc (sizeof (struct grub_partition));
  if (! p)
    return grub_errno;

  p->partmap = &grub_sun_pc_partition_map;
  err = grub_disk_read (disk, 1, 0, sizeof (struct grub_sun_pc_block), &block);
  if (err)
    {
      grub_free (p);
      return err;
    }
  
  if (GRUB_PARTMAP_SUN_PC_MAGIC != grub_le_to_cpu16 (block.magic))
    {
      grub_free (p);
      return grub_error (GRUB_ERR_BAD_PART_TABLE, 
			 "not a sun_pc partition table");
    }

  if (! grub_sun_is_valid (&block))
    {
      grub_free (p);
      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
    }

  /* Maybe another error value would be better, because partition
     table _is_ recognized but invalid.  */
  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_PC_MAX_PARTS; partnum++)
    {
      struct grub_sun_pc_partition_descriptor *desc;

      if (block.partitions[partnum].id == 0
	  || block.partitions[partnum].id == GRUB_PARTMAP_SUN_PC_WHOLE_DISK_ID)
	continue;

      desc = &block.partitions[partnum];
      p->start = grub_le_to_cpu32 (desc->start_sector);
      p->len = grub_le_to_cpu32 (desc->num_sectors);
      p->number = partnum;
      if (p->len)
	{
	  if (hook (disk, p))
	    partnum = GRUB_PARTMAP_SUN_PC_MAX_PARTS;
	}
    }

  grub_free (p);

  return grub_errno;
}
Beispiel #10
0
static grub_err_t
read_node (grub_fshelp_node_t node, grub_off_t off, grub_size_t len, char *buf)
{
  grub_size_t i = 0;

  while (len > 0)
    {
      grub_size_t toread;
      grub_err_t err;
      while (i < node->have_dirents
	     && off >= grub_le_to_cpu32 (node->dirents[i].size))
	{
	  off -= grub_le_to_cpu32 (node->dirents[i].size);
	  i++;
	}
      if (i == node->have_dirents)
	return grub_error (GRUB_ERR_OUT_OF_RANGE, "read out of range");
      toread = grub_le_to_cpu32 (node->dirents[i].size);
      if (toread > len)
	toread = len;
      err = grub_disk_read (node->data->disk,
			    ((grub_disk_addr_t) grub_le_to_cpu32 (node->dirents[i].first_sector)) << GRUB_ISO9660_LOG2_BLKSZ,
			    off, toread, buf);
      if (err)
	return err;
      len -= toread;
      off += toread;
      buf += toread;
    }
  return GRUB_ERR_NONE;
}
Beispiel #11
0
/* Read the inode INO for the file described by DATA into INODE.  */
static grub_err_t
grub_ext2_read_inode (struct grub_ext2_data *data,
		      int ino, struct grub_ext2_inode *inode)
{
  struct grub_ext2_block_group blkgrp;
  struct grub_ext2_sblock *sblock = &data->sblock;
  int inodes_per_block;
  unsigned int blkno;
  unsigned int blkoff;

  /* It is easier to calculate if the first inode is 0.  */
  ino--;

  grub_ext2_blockgroup (data,
                        ino / grub_le_to_cpu32 (sblock->inodes_per_group),
			&blkgrp);
  if (grub_errno)
    return grub_errno;

  inodes_per_block = EXT2_BLOCK_SIZE (data) / EXT2_INODE_SIZE (data);
  blkno = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
    / inodes_per_block;
  blkoff = (ino % grub_le_to_cpu32 (sblock->inodes_per_group))
    % inodes_per_block;

  /* Read the inode.  */
  if (grub_disk_read (data->disk,
		      ((grub_le_to_cpu32 (blkgrp.inode_table_id) + blkno)
		        << LOG2_EXT2_BLOCK_SIZE (data)),
		      EXT2_INODE_SIZE (data) * blkoff,
		      sizeof (struct grub_ext2_inode), inode))
    return grub_errno;

  return 0;
}
Beispiel #12
0
static struct grub_cpio_data *
grub_cpio_mount (grub_disk_t disk)
{
  struct head hd;
  struct grub_cpio_data *data;

  if (grub_disk_read (disk, 0, 0, sizeof (hd), &hd))
    goto fail;

#ifndef MODE_USTAR
  if (hd.magic != MAGIC_BCPIO)
#else
  if (grub_memcmp (hd.magic, MAGIC_USTAR,
		   sizeof (MAGIC_USTAR) - 1))
#endif
    goto fail;

  data = (struct grub_cpio_data *) grub_malloc (sizeof (*data));
  if (!data)
    goto fail;

  data->disk = disk;

  return data;

fail:
  grub_error (GRUB_ERR_BAD_FS, "not a "
#ifdef MODE_USTAR
	      "tar"
#else
	      "cpio"
#endif
	      " filesystem");
  return 0;
}
Beispiel #13
0
static grub_err_t
read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb)
{
  unsigned i;
  grub_err_t err = GRUB_ERR_NONE;
  for (i = 0; i < ARRAY_SIZE (superblock_sectors); i++)
    {
      struct grub_btrfs_superblock sblock;
      err = grub_disk_read (disk, superblock_sectors[i], 0,
			    sizeof (sblock), &sblock);
      if (err == GRUB_ERR_OUT_OF_RANGE)
	break;

      if (grub_memcmp ((char *) sblock.signature, GRUB_BTRFS_SIGNATURE,
		       sizeof (GRUB_BTRFS_SIGNATURE) - 1) != 0)
	break;
      if (i == 0 || grub_le_to_cpu64 (sblock.generation)
	  > grub_le_to_cpu64 (sb->generation))
	grub_memcpy (sb, &sblock, sizeof (sblock));
    }

  if ((err == GRUB_ERR_OUT_OF_RANGE || !err) && i == 0)
    return grub_error (GRUB_ERR_BAD_FS, "not a Btrfs filesystem");

  if (err == GRUB_ERR_OUT_OF_RANGE)
    grub_errno = err = GRUB_ERR_NONE;

  return err;
}
Beispiel #14
0
static char *
grub_sfs_read_symlink (grub_fshelp_node_t node)
{
  struct grub_sfs_data *data = node->data;
  char *symlink;
  char *block;

  block = grub_malloc (data->blocksize);
  if (!block)
    return 0;

  grub_disk_read (data->disk, node->block, 0, data->blocksize, block);
  if (grub_errno)
    {
      grub_free (block);
      return 0;
    }

  /* This is just a wild guess, but it always worked for me.  How the
     SLNK block looks like is not documented in the SFS docs.  */
  symlink = grub_strdup (&block[24]);
  grub_free (block);
  if (!symlink)
    return 0;

  return symlink;
}
Beispiel #15
0
static PyObject *bits_disk_read(PyObject *self, PyObject *args)
{
    PyObject *pyfile, *pystr;
    grub_file_t file;
    grub_disk_addr_t sector;
    unsigned offset, length;

    if (!PyArg_ParseTuple(args, "O!KII:disk_read", &PyFile_Type, &pyfile, &sector, &offset, &length))
        return NULL;

    file = PyFile_AsFile(pyfile);
    if (!file->device->disk)
        return PyErr_Format(PyExc_RuntimeError, "Can't get disk device from non-disk-backed file");

    pystr = PyString_FromStringAndSize(NULL, length);
    if (!pystr)
        return PyErr_NoMemory();

    if (grub_disk_read(file->device->disk, sector, offset, length, PyString_AsString(pystr)) != GRUB_ERR_NONE) {
        Py_DECREF(pystr);
        return PyErr_SetFromErrno(PyExc_IOError);
    }

    return pystr;
}
Beispiel #16
0
static grub_err_t
grub_dmraid_nv_detect (grub_disk_t disk, struct grub_raid_array *array)
{
  grub_disk_addr_t sector;
  struct grub_nv_super sb;

  if (disk->partition)
    return grub_error (GRUB_ERR_OUT_OF_RANGE, "skip partition");

  sector = grub_disk_get_size (disk) - 2;

  if (grub_disk_read (disk, sector, 0, sizeof (sb), &sb))
    return grub_errno;

  if (grub_memcmp (sb.vendor, NV_ID_STRING, 6))
    return grub_error (GRUB_ERR_OUT_OF_RANGE, "not raid");

  if (sb.version != NV_VERSION)
    return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                       "unknown version: %d.%d", sb.version);

  switch (sb.array.raid_level)
    {
    case NV_LEVEL_0:
      array->level = 0;
      array->disk_size = sb.capacity / sb.array.total_volumes;
      break;

    case NV_LEVEL_1:
      array->level = 1;
      array->disk_size = sb.capacity;
      break;

    case NV_LEVEL_5:
      array->level = 5;
      array->layout = GRUB_RAID_LAYOUT_LEFT_ASYMMETRIC;
      array->disk_size = sb.capacity / (sb.array.total_volumes - 1);
      break;

    default:
      return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
                         "unsupported RAID level: %d", sb.array.raid_level);
    }

  array->number = 0;
  array->total_devs = sb.array.total_volumes;
  array->chunk_size = sb.array.stripe_block_size;
  array->disk_offset = 0;
  array->index = sb.unit_number;
  array->uuid_len = sizeof (sb.array.signature);
  array->uuid = grub_malloc (sizeof (sb.array.signature));
  if (! array->uuid)
    return grub_errno;

  grub_memcpy (array->uuid, (char *) &sb.array.signature,
               sizeof (sb.array.signature));

  return 0;
}
Beispiel #17
0
static grub_ssize_t
grub_cpio_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_cpio_data *data;

  data = file->data;
  return (grub_disk_read (data->disk, 0, data->dofs + file->offset,
			  len, buf)) ? -1 : (grub_ssize_t) len;
}
Beispiel #18
0
static grub_err_t
sun_partition_map_iterate (grub_disk_t disk,
                           int (*hook) (grub_disk_t disk,
					const grub_partition_t partition))
{
  grub_partition_t p;
  struct grub_disk raw;
  struct grub_sun_block block;
  int partnum;
  
  raw = *disk;
  raw.partition = 0;
  
  p = (grub_partition_t) grub_malloc (sizeof (struct grub_partition));
  if (! p)
    return grub_errno;

  p->offset = 0;
  p->data = 0;
  p->partmap = &grub_sun_partition_map;
  if (grub_disk_read (&raw, 0, 0, sizeof (struct grub_sun_block),
		      (char *) &block) == GRUB_ERR_NONE)
    {
      if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
	grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");
      
      if (! grub_sun_is_valid (&block))
	grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
      
      /* Maybe another error value would be better, because partition
	 table _is_ recognized but invalid.  */
      for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
	{
	  struct grub_sun_partition_descriptor *desc;
	  
	  if (block.infos[partnum].id == 0
	      || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
	    continue;

	  desc = &block.partitions[partnum];
	  p->start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder)
		      * grub_be_to_cpu16 (block.ntrks)
		      * grub_be_to_cpu16 (block.nsect));
	  p->len = grub_be_to_cpu32 (desc->num_sectors);
	  p->index = partnum;
	  if (p->len)
	    {
	      if (hook (disk, p))
		partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
	    }
	}
    }
  
  grub_free (p);

  return grub_errno;
}
Beispiel #19
0
/* Read into BLKGRP the blockgroup descriptor of blockgroup GROUP of
   the mounted filesystem DATA.  */
inline static grub_err_t
grub_ext2_blockgroup (struct grub_ext2_data *data, int group,
		      struct grub_ext2_block_group *blkgrp)
{
  return grub_disk_read (data->disk,
                         ((grub_le_to_cpu32 (data->sblock.first_data_block) + 1)
                          << LOG2_EXT2_BLOCK_SIZE (data)),
			 group * sizeof (struct grub_ext2_block_group),
			 sizeof (struct grub_ext2_block_group), blkgrp);
}
Beispiel #20
0
static struct grub_ext2_data *
grub_ext2_mount (grub_disk_t disk)
{
  struct grub_ext2_data *data;

  data = grub_malloc (sizeof (struct grub_ext2_data));
  if (!data)
    return 0;

  /* Read the superblock.  */
  grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_ext2_sblock),
                  &data->sblock);
  if (grub_errno)
    goto fail;

  /* Make sure this is an ext2 filesystem.  */
  if (grub_le_to_cpu16 (data->sblock.magic) != EXT2_MAGIC)
    {
      grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");
      goto fail;
    }

  /* Check the FS doesn't have feature bits enabled that we don't support. */
  if (grub_le_to_cpu32 (data->sblock.feature_incompat)
        & ~(EXT2_DRIVER_SUPPORTED_INCOMPAT | EXT2_DRIVER_IGNORED_INCOMPAT))
    {
      grub_error (GRUB_ERR_BAD_FS, "filesystem has unsupported incompatible features");
      goto fail;
    }


  data->disk = disk;

  data->diropen.data = data;
  data->diropen.ino = 2;
  data->diropen.inode_read = 1;

  data->inode = &data->diropen.inode;

  grub_ext2_read_inode (data, 2, data->inode);
  if (grub_errno)
    goto fail;

  return data;

 fail:
  if (grub_errno == GRUB_ERR_OUT_OF_RANGE)
    grub_error (GRUB_ERR_BAD_FS, "not an ext2 filesystem");

  grub_free (data);
  return 0;
}
Beispiel #21
0
static grub_ssize_t
grub_cbfs_read (grub_file_t file, char *buf, grub_size_t len)
{
  struct grub_archelp_data *data;
  grub_ssize_t ret;

  data = file->data;
  data->disk->read_hook = file->read_hook;
  data->disk->read_hook_data = file->read_hook_data;

  ret = (grub_disk_read (data->disk, 0, data->dofs + file->offset,
			 len, buf)) ? -1 : (grub_ssize_t) len;
  data->disk->read_hook = 0;

  return ret;
}
Beispiel #22
0
static grub_err_t
sun_partition_map_iterate (grub_disk_t disk,
                           int (*hook) (grub_disk_t disk,
					const grub_partition_t partition))
{
  struct grub_partition p;
  struct grub_sun_block block;
  int partnum;
  grub_err_t err;

  p.partmap = &grub_sun_partition_map;
  err = grub_disk_read (disk, 0, 0, sizeof (struct grub_sun_block),
			&block);
  if (err)
    return err;

  if (GRUB_PARTMAP_SUN_MAGIC != grub_be_to_cpu16 (block.magic))
    return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a sun partition table");

  if (! grub_sun_is_valid (&block))
      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
  
  /* Maybe another error value would be better, because partition
     table _is_ recognized but invalid.  */
  for (partnum = 0; partnum < GRUB_PARTMAP_SUN_MAX_PARTS; partnum++)
    {
      struct grub_sun_partition_descriptor *desc;

      if (block.infos[partnum].id == 0
	  || block.infos[partnum].id == GRUB_PARTMAP_SUN_WHOLE_DISK_ID)
	continue;

      desc = &block.partitions[partnum];
      p.start = ((grub_uint64_t) grub_be_to_cpu32 (desc->start_cylinder)
		  * grub_be_to_cpu16 (block.ntrks)
		  * grub_be_to_cpu16 (block.nsect));
      p.len = grub_be_to_cpu32 (desc->num_sectors);
      p.number = p.index = partnum;
      if (p.len)
	{
	  if (hook (disk, &p))
	    partnum = GRUB_PARTMAP_SUN_MAX_PARTS;
	}
    }

  return grub_errno;
}
Beispiel #23
0
Datei: ldm.c Projekt: flihp/grub2
int
grub_util_is_ldm (grub_disk_t disk)
{
  int i;
  int has_ldm = msdos_has_ldm_partition (disk);
  for (i = 0; i < 3; i++)
    {
      grub_disk_addr_t sector = LDM_LABEL_SECTOR;
      grub_err_t err;
      struct grub_ldm_label label;

      switch (i)
	{
	case 0:
	  if (!has_ldm)
	    continue;
	  sector = LDM_LABEL_SECTOR;
	  break;
	case 1:
	  /* LDM is never inside a partition.  */
	  if (!has_ldm || disk->partition)
	    continue;
	  sector = grub_disk_get_size (disk);
	  if (sector == GRUB_DISK_SIZE_UNKNOWN)
	    continue;
	  sector--;
	  break;
	  /* FIXME: try the third copy.  */
	case 2:
	  sector = gpt_ldm_sector (disk);
	  if (!sector)
	    continue;
	  break;
	}
      err = grub_disk_read (disk, sector, 0, sizeof(label), &label);
      if (err)
	{
	  grub_errno = GRUB_ERR_NONE;
	  return 0;
	}
      /* This check is more relaxed on purpose.  */
      if (grub_memcmp (label.magic, LDM_MAGIC, sizeof (label.magic)) == 0)
	return 1;
    }

  return 0;
}
Beispiel #24
0
static grub_err_t
decomp_nextvcn (struct grub_ntfs_comp *cc)
{
    if (cc->comp_head >= cc->comp_tail)
        return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
    if (grub_disk_read
            (cc->disk,
             (cc->comp_table[cc->comp_head][1] -
              (cc->comp_table[cc->comp_head][0] - cc->cbuf_vcn)) * cc->spc, 0,
             cc->spc << BLK_SHR, cc->cbuf))
        return grub_errno;
    cc->cbuf_vcn++;
    if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head][0]))
        cc->comp_head++;
    cc->cbuf_ofs = 0;
    return 0;
}
Beispiel #25
0
static grub_err_t
dvh_partition_map_iterate (grub_disk_t disk,
                           int (*hook) (grub_disk_t disk,
					const grub_partition_t partition))
{
  struct grub_partition p;
  union
  {
    struct grub_dvh_block dvh;
    grub_uint32_t raw[0];
  } block;
  unsigned partnum;
  grub_err_t err;

  p.partmap = &grub_dvh_partition_map;
  err = grub_disk_read (disk, 0, 0, sizeof (struct grub_dvh_block),
			&block);
  if (err)
    return err;

  if (DVH_MAGIC != grub_be_to_cpu32 (block.dvh.magic))
    return grub_error (GRUB_ERR_BAD_PART_TABLE, "not a dvh partition table");

  if (! grub_dvh_is_valid (block.raw))
      return grub_error (GRUB_ERR_BAD_PART_TABLE, "invalid checksum");
  
  /* Maybe another error value would be better, because partition
     table _is_ recognized but invalid.  */
  for (partnum = 0; partnum < ARRAY_SIZE (block.dvh.parts); partnum++)
    {
      if (block.dvh.parts[partnum].length == 0)
	continue;

      if (partnum == 10)
	continue;

      p.start = grub_be_to_cpu32 (block.dvh.parts[partnum].start);
      p.len = grub_be_to_cpu32 (block.dvh.parts[partnum].length);
      p.number = p.index = partnum;
      if (hook (disk, &p))
	break;
    }

  return grub_errno;
}
Beispiel #26
0
static grub_err_t
decomp_nextvcn (struct grub_ntfs_comp *cc)
{
  if (cc->comp_head >= cc->comp_tail)
    return grub_error (GRUB_ERR_BAD_FS, "compression block overflown");
  if (grub_disk_read
      (cc->disk,
       (cc->comp_table[cc->comp_head].next_lcn -
	(cc->comp_table[cc->comp_head].next_vcn - cc->cbuf_vcn)) << cc->log_spc,
       0,
       1 << (cc->log_spc + GRUB_NTFS_BLK_SHR), cc->cbuf))
    return grub_errno;
  cc->cbuf_vcn++;
  if ((cc->cbuf_vcn >= cc->comp_table[cc->comp_head].next_vcn))
    cc->comp_head++;
  cc->cbuf_ofs = 0;
  return 0;
}
Beispiel #27
0
static char *
grub_affs_read_symlink (grub_fshelp_node_t node)
{
  struct grub_affs_data *data = node->data;
  char *symlink;

  symlink = grub_malloc (GRUB_AFFS_SYMLINK_SIZE (data->blocksize));
  if (!symlink)
    return 0;

  grub_disk_read (data->disk, node->block, GRUB_AFFS_SYMLINK_OFFSET,
		  GRUB_AFFS_SYMLINK_SIZE (data->blocksize), symlink);
  if (grub_errno)
    {
      grub_free (symlink);
      return 0;
    }
  grub_dprintf ("affs", "Symlink: `%s'\n", symlink);
  return symlink;
}
Beispiel #28
0
static grub_err_t
grub_gpt_device_partentry (grub_device_t device,
			   struct grub_gpt_partentry *entry)
{
  grub_disk_t disk = device->disk;
  grub_partition_t p;
  grub_err_t err;

  if (!disk || !disk->partition)
    return grub_error (GRUB_ERR_BUG, "not a partition");

  if (grub_strcmp (disk->partition->partmap->name, "gpt"))
    return grub_error (GRUB_ERR_BAD_ARGUMENT, "not a GPT partition");

  p = disk->partition;
  disk->partition = p->parent;
  err = grub_disk_read (disk, p->offset, p->index, sizeof (*entry), entry);
  disk->partition = p;

  return err;
}
static char *
grub_cpio_get_link_target (struct grub_archelp_data *data)
{
  char *ret;
  grub_err_t err;

  if (data->size == 0)
    return grub_strdup ("");
  ret = grub_malloc (data->size + 1);
  if (!ret)
    return NULL;

  err = grub_disk_read (data->disk, 0, data->dofs, data->size, 
			ret);
  if (err)
    {
      grub_free (ret);
      return NULL;
    }
  ret[data->size] = '\0';
  return ret;
}
Beispiel #30
0
static struct grub_ext4_extent_header *
grub_ext4_find_leaf (struct grub_ext2_data *data, char *buf,
                     struct grub_ext4_extent_header *ext_block,
                     grub_uint32_t fileblock)
{
  struct grub_ext4_extent_idx *index;

  while (1)
    {
      int i;
      grub_disk_addr_t block;

      index = (struct grub_ext4_extent_idx *) (ext_block + 1);

      if (grub_le_to_cpu16(ext_block->magic) != EXT4_EXT_MAGIC)
        return 0;

      if (ext_block->depth == 0)
        return ext_block;

      for (i = 0; i < grub_le_to_cpu16 (ext_block->entries); i++)
        {
          if (fileblock < grub_le_to_cpu32(index[i].block))
            break;
        }

      if (--i < 0)
        return 0;

      block = grub_le_to_cpu16 (index[i].leaf_hi);
      block = (block << 32) + grub_le_to_cpu32 (index[i].leaf);
      if (grub_disk_read (data->disk,
                          block << LOG2_EXT2_BLOCK_SIZE (data),
                          0, EXT2_BLOCK_SIZE(data), buf))
        return 0;

      ext_block = (struct grub_ext4_extent_header *) buf;
    }
}