Exemplo n.º 1
0
int
main (int argc, char *argv[])
{
  guestfs_h *g;
  int r;
  char *data;
  size_t i, size;

  if (test_start_nbdkit ("-n", NBDKIT_PLUGIN ("file"), "file=file-data",
                         NULL) == -1)
    exit (EXIT_FAILURE);

  g = guestfs_create ();
  if (g == NULL) {
    perror ("guestfs_create");
    exit (EXIT_FAILURE);
  }

  /* Using any exportname causes qemu to use the newstyle protocol. */
  r = guestfs_add_drive_opts (g, "/" /* exportname */,
                              GUESTFS_ADD_DRIVE_OPTS_FORMAT, "raw",
                              GUESTFS_ADD_DRIVE_OPTS_PROTOCOL, "nbd",
                              GUESTFS_ADD_DRIVE_OPTS_SERVER, server,
                              -1);
  if (r == -1)
    exit (EXIT_FAILURE);

  if (guestfs_launch (g) == -1)
    exit (EXIT_FAILURE);

  /* Check the data in the file is \x01-\x08 repeated 512 times. */
  data = guestfs_pread_device (g, "/dev/sda", 8 * 512, 0, &size);
  if (!data)
    exit (EXIT_FAILURE);
  if (size != 8 * 512) {
    fprintf (stderr, "%s FAILED: unexpected size (actual: %zu, expected: 512)\n",
             program_name, size);
    exit (EXIT_FAILURE);
  }

  for (i = 0; i < 512 * 8; i += 8) {
    if (data[i] != 1 || data[i+1] != 2 ||
        data[i+2] != 3 || data[i+3] != 4 ||
        data[i+4] != 5 || data[i+5] != 6 ||
        data[i+6] != 7 || data[i+7] != 8) {
      fprintf (stderr, "%s FAILED: unexpected data returned at offset %zu\n",
               program_name, i);
      exit (EXIT_FAILURE);
    }
  }

  free (data);

  guestfs_close (g);
  exit (EXIT_SUCCESS);
}
/* Windows Registry HKLM\SYSTEM\MountedDevices uses a blob of data
 * to store partitions.  This blob is described here:
 * http://www.goodells.net/multiboot/partsigs.shtml
 * The following function maps this blob to a libguestfs partition
 * name, if possible.
 */
static char *
map_registry_disk_blob (guestfs_h *g, const void *blob)
{
  CLEANUP_FREE_STRING_LIST char **devices = NULL;
  CLEANUP_FREE_PARTITION_LIST struct guestfs_partition_list *partitions = NULL;
  size_t i, j, len;
  uint64_t part_offset;

  /* First 4 bytes are the disk ID.  Search all devices to find the
   * disk with this disk ID.
   */
  devices = guestfs_list_devices (g);
  if (devices == NULL)
    return NULL;

  for (i = 0; devices[i] != NULL; ++i) {
    /* Read the disk ID. */
    CLEANUP_FREE char *diskid =
      guestfs_pread_device (g, devices[i], 4, 0x01b8, &len);
    if (diskid == NULL)
      continue;
    if (len < 4)
      continue;
    if (memcmp (diskid, blob, 4) == 0) /* found it */
      goto found_disk;
  }
  return NULL;

 found_disk:
  /* Next 8 bytes are the offset of the partition in bytes(!) given as
   * a 64 bit little endian number.  Luckily it's easy to get the
   * partition byte offset from guestfs_part_list.
   */
  memcpy (&part_offset, (char *) blob + 4, sizeof (part_offset));
  part_offset = le64toh (part_offset);

  partitions = guestfs_part_list (g, devices[i]);
  if (partitions == NULL)
    return NULL;

  for (j = 0; j < partitions->len; ++j) {
    if (partitions->val[j].part_start == part_offset) /* found it */
      goto found_partition;
  }
  return NULL;

 found_partition:
  /* Construct the full device name. */
  return safe_asprintf (g, "%s%d", devices[i], partitions->val[j].part_num);
}