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; }
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); }
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; }
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; }
/* 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; }
/* 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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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, §or, &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; }
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; }
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; }
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; }
/* 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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; } }