예제 #1
0
// This returns true if a GPT partition matches the search criteria. If a match
// isn't found (or if the file doesn't contain a GPT), it returns false. The
// filename and partition number that matched is left in a global, since we
// could have multiple hits.
static int do_search(CgptFindParams *params, char *fileName) {
  int retval = 0;
  int i;
  struct drive drive;
  GptEntry *entry;
  char partlabel[GPT_PARTNAME_LEN];

  if (CGPT_OK != DriveOpen(fileName, &drive, O_RDONLY))
    return 0;

  if (GPT_SUCCESS != GptSanityCheck(&drive.gpt)) {
    (void) DriveClose(&drive, 0);
    return 0;
  }

  for (i = 0; i < GetNumberOfEntries(&drive); ++i) {
    entry = GetEntry(&drive.gpt, ANY_VALID, i);

    if (GuidIsZero(&entry->type))
      continue;

    int found = 0;
    if ((params->set_unique && GuidEqual(&params->unique_guid, &entry->unique))
        || (params->set_type && GuidEqual(&params->type_guid, &entry->type))) {
      found = 1;
    } else if (params->set_label) {
      if (CGPT_OK != UTF16ToUTF8(entry->name,
                                 sizeof(entry->name) / sizeof(entry->name[0]),
                                 (uint8_t *)partlabel, sizeof(partlabel))) {
        Error("The label cannot be converted from UTF16, so abort.\n");
        return 0;
      }
      if (!strncmp(params->label, partlabel, sizeof(partlabel)))
        found = 1;
    }
    if (found && match_content(params, &drive, entry)) {
      params->hits++;
      retval++;
      showmatch(params, fileName, i+1, entry);
      if (!params->match_partnum)
        params->match_partnum = i+1;
    }
  }

  (void) DriveClose(&drive, 0);

  return retval;
}
예제 #2
0
// This method gets the partition details such as the attributes, the
// guids of the partitions, etc. Input is the partition number or the
// unique id of the partition. Output is populated in the respective
// fields of params.
int CgptGetPartitionDetails(CgptAddParams *params) {
  struct drive drive;
  int result = CGPT_FAILED;
  int index;

  if (params == NULL)
    return CGPT_FAILED;

  if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDWR))
    return CGPT_FAILED;

  if (CgptCheckAddValidity(&drive)) {
    goto bad;
  }

  int max_part = GetNumberOfEntries(&drive);
  if (params->partition > 0) {
    if (params->partition >= max_part) {
      Error("invalid partition number: %d\n", params->partition);
      goto bad;
    }
  } else {
    if (!params->set_unique) {
      Error("either partition or unique_id must be specified\n");
      goto bad;
    }
    for (index = 0; index < max_part; index++) {
      GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
      if (GuidEqual(&entry->unique, &params->unique_guid)) {
        params->partition = index + 1;
        break;
      }
    }
    if (index >= max_part) {
      Error("no partitions with the given unique id available\n");
      goto bad;
    }
  }
  index = params->partition - 1;

  {
    // GPT-specific code
    GptEntry *entry = GetEntry(&drive.gpt, PRIMARY, index);
    params->begin = entry->starting_lba;
    params->size =  entry->ending_lba - entry->starting_lba + 1;
    memcpy(&params->type_guid, &entry->type, sizeof(Guid));
    memcpy(&params->unique_guid, &entry->unique, sizeof(Guid));
    params->raw_value = entry->attrs.fields.gpt_att;
  }

  params->successful = GetSuccessful(&drive, PRIMARY, index);
  params->tries = GetTries(&drive, PRIMARY, index);
  params->priority = GetPriority(&drive, PRIMARY, index);
  result = CGPT_OK;

bad:
  DriveClose(&drive, 0);
  return result;
}
예제 #3
0
int CgptGetBootPartitionNumber(CgptBootParams *params) {
  struct drive drive;
  int gpt_retval= 0;
  int retval;

  if (params == NULL)
    return CGPT_FAILED;

  if (CGPT_OK != DriveOpen(params->drive_name, &drive, O_RDONLY,
                           params->drive_size))
    return CGPT_FAILED;

  if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) {
    Error("GptSanityCheck() returned %d: %s\n",
          gpt_retval, GptError(gpt_retval));
    retval = CGPT_FAILED;
    goto done;
  }

  if (CGPT_OK != ReadPMBR(&drive)) {
    Error("Unable to read PMBR\n");
    retval = CGPT_FAILED;
    goto done;
  }

  char buf[GUID_STRLEN];
  GuidToStr(&drive.pmbr.boot_guid, buf, sizeof(buf));

  int numEntries = GetNumberOfEntries(&drive);
  int i;
  for(i = 0; i < numEntries; i++) {
      GptEntry *entry = GetEntry(&drive.gpt, ANY_VALID, i);

      if (GuidEqual(&entry->unique, &drive.pmbr.boot_guid)) {
        params->partition = i + 1;
        retval = CGPT_OK;
        goto done;
      }
  }

  Error("Didn't find any boot partition\n");
  params->partition = 0;
  retval = CGPT_FAILED;

done:
  (void) DriveClose(&drive, 1);
  return retval;
}
예제 #4
0
void EntryDetails(GptEntry *entry, uint32_t index, int raw) {
  char contents[256];                   // scratch buffer for formatting output
  uint8_t label[GPT_PARTNAME_LEN];
  char type[GUID_STRLEN], unique[GUID_STRLEN];

  UTF16ToUTF8(entry->name, sizeof(entry->name) / sizeof(entry->name[0]),
              label, sizeof(label));
  require(snprintf(contents, sizeof(contents),
                   "Label: \"%s\"", label) < sizeof(contents));
  printf(PARTITION_FMT, (int)entry->starting_lba,
         (int)(entry->ending_lba - entry->starting_lba + 1),
         index+1, contents);

  if (!raw && CGPT_OK == ResolveType(&entry->type, type)) {
    printf(PARTITION_MORE, "Type: ", type);
  } else {
    GuidToStr(&entry->type, type, GUID_STRLEN);
    printf(PARTITION_MORE, "Type: ", type);
  }
  GuidToStr(&entry->unique, unique, GUID_STRLEN);
  printf(PARTITION_MORE, "UUID: ", unique);

  if (!raw) {
    if (GuidEqual(&guid_chromeos_kernel, &entry->type)) {
      int tries = (entry->attrs.fields.gpt_att &
                   CGPT_ATTRIBUTE_TRIES_MASK) >>
          CGPT_ATTRIBUTE_TRIES_OFFSET;
      int successful = (entry->attrs.fields.gpt_att &
                        CGPT_ATTRIBUTE_SUCCESSFUL_MASK) >>
          CGPT_ATTRIBUTE_SUCCESSFUL_OFFSET;
      int priority = (entry->attrs.fields.gpt_att &
                      CGPT_ATTRIBUTE_PRIORITY_MASK) >>
          CGPT_ATTRIBUTE_PRIORITY_OFFSET;
      require(snprintf(contents, sizeof(contents),
                       "priority=%d tries=%d successful=%d",
                       priority, tries, successful) < sizeof(contents));
      printf(PARTITION_MORE, "Attr: ", contents);
    }
  } else {