Back to index

lshw  02.16
Classes | Defines | Functions | Variables
partitions.cc File Reference
#include "version.h"
#include "partitions.h"
#include "blockio.h"
#include "lvm.h"
#include "volumes.h"
#include "osutils.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>

Go to the source code of this file.

Classes

struct  maptypes
struct  efi_guid_t
struct  gpth
struct  efipartition
struct  dospartition
struct  systypes

Defines

#define _LARGEFILE_SOURCE
#define _FILE_OFFSET_BITS   64
#define LIFBLOCKSIZE   256
#define GPT_PMBR_LBA   0
#define GPT_PMBR_SECTORS   1
#define GPT_PRIMARY_HEADER_LBA   1
#define GPT_HEADER_SECTORS   1
#define GPT_PRIMARY_PART_TABLE_LBA   2
#define EFI_PMBR_OSTYPE_EFI   0xee
#define GPT_HEADER_SIGNATURE   0x5452415020494645LL /* "EFI PART" */
#define UNUSED_ENTRY_GUID
#define PARTITION_PRECIOUS   1
#define PARTITION_READONLY   (1LL << 60)
#define PARTITION_HIDDEN   (1LL << 62)
#define PARTITION_NOMOUNT   (1LL << 63)

Functions

 __ID ("@(#) $Id: partitions.cc 2433 2012-01-10 22:01:30Z lyonel $")
static bool detect_dosmap (source &s, hwNode &n)
static bool detect_macmap (source &s, hwNode &n)
static bool detect_lif (source &s, hwNode &n)
static bool detect_luks (source &s, hwNode &n)
static bool detect_gpt (source &s, hwNode &n)
static bool guess_logicalname (source &s, const hwNode &disk, unsigned int n, hwNode &partition)
static bool is_extended (unsigned char type)
static bool read_dospartition (source &s, unsigned short i, dospartition &p)
static bool analyse_dospart (source &s, unsigned char flags, unsigned char type, hwNode &partition)
static bool analyse_dosextpart (source &s, unsigned char flags, unsigned char type, hwNode &extpart)
uint32_t __efi_crc32 (const void *buf, unsigned long len, uint32_t seed)
static uint32_t efi_crc32 (const void *buf, unsigned long len)
static efi_guid_t read_efi_guid (uint8_t *buffer)
bool operator== (const efi_guid_t &guid1, const efi_guid_t &guid2)
static string tostring (const efi_guid_t &guid)
bool operator== (const efi_guid_t &guid1, const string &guid2)
bool scan_partitions (hwNode &n)

Variables

static struct maptypes []
static struct systypes []
static unsigned int lastlogicalpart = 5
static uint32_t crc32_tab []

Class Documentation

struct efi_guid_t

Definition at line 66 of file partitions.cc.

Class Members
uint8_t clock_seq_hi_and_reserved
uint8_t clock_seq_low
uint8_t node
uint16_t time_hi_and_version
uint32_t time_low
uint16_t time_mid
struct gpth

Definition at line 76 of file partitions.cc.

Collaboration diagram for gpth:
Class Members
uint64_t AlternateLBA
efi_guid_t DiskGUID
uint64_t FirstUsableLBA
uint32_t HeaderCRC32
uint32_t HeaderSize
uint64_t LastUsableLBA
uint64_t MyLBA
uint32_t NumberOfPartitionEntries
uint32_t PartitionEntryArrayCRC32
uint64_t PartitionEntryLBA
uint32_t Reserved1
uint32_t Revision
uint64_t Signature
uint32_t SizeOfPartitionEntry
struct efipartition

Definition at line 94 of file partitions.cc.

Collaboration diagram for efipartition:
Class Members
uint64_t Attributes
uint64_t EndingLBA
efi_guid_t PartitionGUID
string PartitionName
efi_guid_t PartitionTypeGUID
uint64_t StartingLBA
struct dospartition

Definition at line 113 of file partitions.cc.

Class Members
unsigned char flags
unsigned long long size
unsigned long long start
unsigned char type
struct systypes

Definition at line 122 of file partitions.cc.

Class Members
const char * capabilities
const char * description
const char * icon
const char * id
const unsigned char type

Define Documentation

#define _FILE_OFFSET_BITS   64

Definition at line 15 of file partitions.cc.

Definition at line 14 of file partitions.cc.

#define EFI_PMBR_OSTYPE_EFI   0xee

Definition at line 110 of file partitions.cc.

#define GPT_HEADER_SECTORS   1

Definition at line 107 of file partitions.cc.

#define GPT_HEADER_SIGNATURE   0x5452415020494645LL /* "EFI PART" */

Definition at line 111 of file partitions.cc.

#define GPT_PMBR_LBA   0

Definition at line 104 of file partitions.cc.

#define GPT_PMBR_SECTORS   1

Definition at line 105 of file partitions.cc.

#define GPT_PRIMARY_HEADER_LBA   1

Definition at line 106 of file partitions.cc.

Definition at line 108 of file partitions.cc.

#define LIFBLOCKSIZE   256

Definition at line 34 of file partitions.cc.

#define PARTITION_HIDDEN   (1LL << 62)

Definition at line 506 of file partitions.cc.

#define PARTITION_NOMOUNT   (1LL << 63)

Definition at line 507 of file partitions.cc.

#define PARTITION_PRECIOUS   1

Definition at line 504 of file partitions.cc.

#define PARTITION_READONLY   (1LL << 60)

Definition at line 505 of file partitions.cc.

Value:
((efi_guid_t) \
{ \
  0x00000000, 0x0000, 0x0000, 0x00, 00, \
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } \
})

Definition at line 497 of file partitions.cc.


Function Documentation

uint32_t __efi_crc32 ( const void *  buf,
unsigned long  len,
uint32_t  seed 
)

Definition at line 618 of file partitions.cc.

{
  unsigned long i;
  register uint32_t crc32val;
  const unsigned char *s = (const unsigned char *)buf;

  crc32val = seed;
  for (i = 0;  i < len;  i ++)
  {
    crc32val =
      crc32_tab[(crc32val ^ s[i]) & 0xff] ^
      (crc32val >> 8);
  }
  return crc32val;
}

Here is the caller graph for this function:

__ID ( "@(#) $Id: partitions.cc 2433 2012-01-10 22:01:30Z lyonel $"  )
static bool analyse_dosextpart ( source s,
unsigned char  flags,
unsigned char  type,
hwNode extpart 
) [static]

Definition at line 381 of file partitions.cc.

{
  source extendedpart = s;
  int i = 0;
  dospartition pte[2];                            // we only read entries #0 and #1

  if(!is_extended(type))                          // this is not an extended partition
    return false;

  extpart.setDescription("Extended partition");
  extpart.addCapability("extended", "Extended partition");
  extpart.addCapability("partitioned", "Partitioned disk");
  extpart.addCapability("partitioned:extended", "Extended partition");
  extpart.setSize(extpart.getCapacity());

  extpart.describeCapability("nofs", "No filesystem");

  do
  {
    for(i=0; i<2; i++)
      if(!read_dospartition(extendedpart, i, pte[i]))
        return false;

    if((pte[0].type == 0) || (pte[0].size == 0))
      return true;
    else
    {
      hwNode partition("logicalvolume", hw::volume);
      source spart = extendedpart;

      spart.offset = extendedpart.offset + pte[0].start;
      spart.size = pte[0].size;

      partition.setPhysId(lastlogicalpart);
      partition.setCapacity(spart.size);

      if(analyse_dospart(spart, pte[0].flags, pte[0].type, partition))
      {
        guess_logicalname(spart, extpart, lastlogicalpart, partition);
        extpart.addChild(partition);
        lastlogicalpart++;
      }
    }

    if((pte[1].type == 0) || (pte[1].size == 0))
      return true;
    else
    {
      extendedpart.offset = s.offset + pte[1].start;
      extendedpart.size = pte[1].size;
      if(!is_extended(pte[1].type))
        return false;
    }
  } while(true);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool analyse_dospart ( source s,
unsigned char  flags,
unsigned char  type,
hwNode partition 
) [static]

Definition at line 443 of file partitions.cc.

{
  int i = 0;

  if(is_extended(type))
    return analyse_dosextpart(s, flags, type, partition);

  if(flags!=0 && flags!=0x80)                     // inconsistency: partition is either bootable or non-bootable
    return false;

  if(s.offset==0 || s.size==0)                    // unused entry
    return false;

  partition.setCapacity(s.size);

  if(flags == 0x80)
    partition.addCapability("bootable", "Bootable partition (active)");

  while(dos_sys_types[i].id)
  {
    if(dos_sys_types[i].type == type)
    {
      partition.setDescription(string(dos_sys_types[i].description)+" partition");
      if(lowercase(dos_sys_types[i].capabilities) != "")
      {
        vector<string> capabilities;
        splitlines(dos_sys_types[i].capabilities, capabilities, ',');

        for(unsigned j=0; j<capabilities.size(); j++)
          partition.addCapability(capabilities[j]);
      }
      if(lowercase(dos_sys_types[i].icon) != "")
        partition.addHint("icon", string(dos_sys_types[i].icon));
      else
        partition.addHint("icon", string("disc"));
      break;
    }
    i++;
  }

  partition.describeCapability("nofs", "No filesystem");
  partition.describeCapability("boot", "Contains boot code");
  partition.describeCapability("multi", "Multi-volumes");
  partition.describeCapability("hidden", "Hidden partition");

  scan_lvm(partition, s);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool detect_dosmap ( source s,
hwNode n 
) [static]

Definition at line 1138 of file partitions.cc.

{
  static unsigned char buffer[BLOCKSIZE];
  int i = 0;
  unsigned char flags;
  unsigned char type;
  unsigned long long start, size;
  bool partitioned = false;
  unsigned long signature = 0;

  if(s.offset!=0)
    return false;                                 // partition tables must be at the beginning of the disk

  if(readlogicalblocks(s, buffer, 0, 1)!=1)       // read the first sector
    return false;

  if(le_short(buffer+510)!=0xaa55)                // wrong magic number
    return false;

  signature=le_long(buffer+440);
  if(signature == 0xffffffffL)
    signature = 0;
  if(signature)
  {
    char buffer[8+1];
    snprintf(buffer, sizeof(buffer), "%08lx", signature);
    n.setConfig("signature", buffer);
  }

  lastlogicalpart = 5;

  for(i=0; i<4; i++)
  {
    source spart = s;
    hwNode partition("volume", hw::volume);

    flags = buffer[446 + i*16];
    type = buffer[446 + i*16 + 4];
    start = le_long(buffer + 446 + i*16 + 8);
    size = le_long(buffer + 446 + i*16 + 12);

    if(flags!=0 && flags!=0x80)                   // inconsistency: partition is either bootable or non-bootable
      return false;

    spart.blocksize = s.blocksize;
    spart.offset = s.offset + start*spart.blocksize;
    spart.size = size*spart.blocksize;

    partition.setDescription("Primary partition");
    partition.addCapability("primary", "Primary partition");
    partition.setPhysId(i+1);
    partition.setCapacity(spart.size);

    if(analyse_dospart(spart, flags, type, partition))
    {
      guess_logicalname(spart, n, i+1, partition);
      scan_volume(partition, spart);
      n.addChild(partition);
      partitioned = true;
    }
  }

  return partitioned;
}

Here is the call graph for this function:

static bool detect_gpt ( source s,
hwNode n 
) [static]

Definition at line 687 of file partitions.cc.

{
  static uint8_t buffer[BLOCKSIZE];
  static gpth gpt_header;
  uint32_t i = 0;
  char gpt_version[8];
  uint8_t *partitions = NULL;
  uint8_t type;

  if(s.offset!=0)
    return false;                                 // partition tables must be at the beginning of the disk

                                                  // read the first sector
  if(readlogicalblocks(s, buffer, GPT_PMBR_LBA, 1)!=1)
    return false;

  if(le_short(buffer+510)!=0xaa55)                // wrong magic number
    return false;

  for(i=0; i<4; i++)
  {
    type = buffer[446 + i*16 + 4];

    if((type != 0) && (type != EFI_PMBR_OSTYPE_EFI))
      return false;                               // the EFI pseudo-partition must be the only partition
  }

                                                  // read the second sector
  if(readlogicalblocks(s, buffer, GPT_PRIMARY_HEADER_LBA, 1)!=1)
    return false;                                 // (partition table header)

  gpt_header.Signature = le_longlong(buffer);
  gpt_header.Revision = be_long(buffer + 0x8);    // big endian so that 1.0 -> 0x100
  gpt_header.HeaderSize = le_long(buffer + 0xc);
  gpt_header.HeaderCRC32 = le_long(buffer + 0x10);
  gpt_header.MyLBA = le_longlong(buffer + 0x18);
  gpt_header.AlternateLBA = le_longlong(buffer + 0x20);
  gpt_header.FirstUsableLBA = le_longlong(buffer + 0x28);
  gpt_header.LastUsableLBA = le_longlong(buffer + 0x30);
  gpt_header.DiskGUID = read_efi_guid(buffer + 0x38);
  gpt_header.PartitionEntryLBA = le_longlong(buffer + 0x48);
  gpt_header.NumberOfPartitionEntries = le_long(buffer + 0x50);
  gpt_header.SizeOfPartitionEntry = le_long(buffer + 0x54);
  gpt_header.PartitionEntryArrayCRC32 = le_long(buffer + 0x58);

                                                  // zero-out the CRC32 before re-calculating it
  memset(buffer + 0x10, 0, sizeof(gpt_header.HeaderCRC32));
  if(gpt_header.Signature != GPT_HEADER_SIGNATURE)
    return false;

  if(efi_crc32(buffer, 92) != gpt_header.HeaderCRC32)
    return false;                                 // check CRC32

  snprintf(gpt_version, sizeof(gpt_version), "%d.%02d", (gpt_header.Revision >> 8), (gpt_header.Revision & 0xff));

  n.addCapability("gpt-"+string(gpt_version), "GUID Partition Table version "+string(gpt_version));
  n.addHint("partitions", gpt_header.NumberOfPartitionEntries);
  n.setConfig("guid", tostring(gpt_header.DiskGUID));
  n.setHandle("GUID:" + tostring(gpt_header.DiskGUID));
  n.addHint("guid", tostring(gpt_header.DiskGUID));

  partitions = (uint8_t*)malloc(gpt_header.NumberOfPartitionEntries * gpt_header.SizeOfPartitionEntry + BLOCKSIZE);
  if(!partitions)
    return false;
  memset(partitions, 0, gpt_header.NumberOfPartitionEntries * gpt_header.SizeOfPartitionEntry + BLOCKSIZE);
  readlogicalblocks(s, partitions,
    gpt_header.PartitionEntryLBA,
    (gpt_header.NumberOfPartitionEntries * gpt_header.SizeOfPartitionEntry)/BLOCKSIZE + 1);

  for(i=0; i<gpt_header.NumberOfPartitionEntries; i++)
  {
    hwNode partition("volume", hw::volume);
    efipartition p;

    p.PartitionTypeGUID = read_efi_guid(partitions + gpt_header.SizeOfPartitionEntry * i);
    p.PartitionGUID = read_efi_guid(partitions + gpt_header.SizeOfPartitionEntry * i + 0x10);
    p.StartingLBA = le_longlong(partitions + gpt_header.SizeOfPartitionEntry * i + 0x20);
    p.EndingLBA = le_longlong(partitions + gpt_header.SizeOfPartitionEntry * i + 0x28);
    p.Attributes = le_longlong(partitions + gpt_header.SizeOfPartitionEntry * i + 0x30);
    for(int j=0; j<36; j++)
    {
      wchar_t c = le_short(partitions + gpt_header.SizeOfPartitionEntry * i + 0x38 + 2*j);
      if(!c)
        break;
      else
        p.PartitionName += utf8(c);
    }

    if(!(p.PartitionTypeGUID == UNUSED_ENTRY_GUID))
    {
      source spart = s;
      if(p.PartitionTypeGUID == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B")
      {
        partition.setDescription("System partition");
        partition.setVendor("EFI");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "024DEE41-33E7-11D3-9D69-0008C781F39F")
      {
        partition.setDescription("MBR partition scheme");
        partition.setVendor("EFI");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "21686148-6449-6E6F-744E-656564454649")
      {
        partition.setDescription("BIOS Boot partition");
        partition.setVendor("EFI");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F")
      {
        partition.setDescription("swap partition");
        partition.setVendor("Linux");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "A19D880F-05FC-4D3B-A006-743F0F84911E")
      {
        partition.setDescription("RAID partition");
        partition.setVendor("Linux");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "E6D6D379-F507-44C2-A23C-238F2A3DF928")
      {
        partition.setDescription("LVM Physical Volume");
        partition.setVendor("Linux");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "8DA63339-0007-60C0-C436-083AC8230908")
      {
        partition.setDescription("reserved partition");
        partition.setVendor("Linux");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "75894C1E-3AEB-11D3-B7C1-7B03A0000000")
      {
        partition.setDescription("data partition");
        partition.setVendor("HP-UX");
      }
      else
      if(p.PartitionTypeGUID == "E2A1E728-32E3-11D6-A682-7B03A0000000")
      {
        partition.setDescription("service partition");
        partition.setVendor("HP-UX");
        partition.addCapability("nofs");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "48465300-0000-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("Apple HFS+ partition");
        partition.setVendor("Mac OS X");
      }
      else
      if(p.PartitionTypeGUID == "6A898CC3-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("OS X ZFS partition or Solaris /usr partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "52414944-0000-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("RAID partition");
        partition.setVendor("Mac OS X");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "52414944-5F4F-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("RAID partition (offline)");
        partition.setVendor("Mac OS X");
        partition.addCapability("multi");
        partition.addCapability("offline");
      }
      else
      if(p.PartitionTypeGUID == "4C616265-6C00-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("Apple label");
        partition.setVendor("Mac OS X");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "5265636F-7665-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("recovery partition");
        partition.setVendor("Apple TV");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "53746F72-6167-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("Apple Core Storage (File Vault)");
        partition.setVendor("Mac OS X");
        partition.addCapability("encrypted");
      }
      else
      if(p.PartitionTypeGUID == "426F6F74-0000-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("boot partition");
        partition.setVendor("Mac OS X");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "55465300-0000-11AA-AA11-00306543ECAC")
      {
        partition.setDescription("UFS partition");
        partition.setVendor("Mac OS X");
      }
      else
      if(p.PartitionTypeGUID == "516E7CB4-6ECF-11D6-8FF8-00022D09712B")
      {
        partition.setDescription("data partition");
        partition.setVendor("FreeBSD");
      }
      else
      if(p.PartitionTypeGUID == "516E7CB6-6ECF-11D6-8FF8-00022D09712B")
      {
        partition.setDescription("UFS partition");
        partition.setVendor("FreeBSD");
      }
      else
      if(p.PartitionTypeGUID == "516E7CBA-6ECF-11D6-8FF8-00022D09712B")
      {
        partition.setDescription("ZFS partition");
        partition.setVendor("FreeBSD");
      }
      else
      if(p.PartitionTypeGUID == "516E7CB8-6ECF-11D6-8FF8-00022D09712B")
      {
        partition.setDescription("Vinum Volume Manager partition");
        partition.setVendor("FreeBSD");
      }
      else
      if(p.PartitionTypeGUID == "516E7CB5-6ECF-11D6-8FF8-00022D09712B")
      {
        partition.setDescription("swap partition");
        partition.setVendor("FreeBSD");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "83BD6B9D-7F41-11DC-BE0B-001560B84F0F")
      {
        partition.setDescription("boot partition");
        partition.setVendor("FreeBSD");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7")
      {
        partition.setDescription("data partition");
        partition.setVendor("Windows");
      }
      else
      if(p.PartitionTypeGUID == "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC")
      {
        partition.setDescription("recovery environment");
        partition.setVendor("Windows");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "37AFFC90-EF7D-4E96-91C3-2D7AE055B174")
      {
        partition.setDescription("IBM GPFS partition");
        partition.setVendor("Windows");
      }
      else
      if(p.PartitionTypeGUID == "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3")
      {
        partition.setDescription("LDM configuration");
        partition.setVendor("Windows");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "AF9B60A0-1431-4F62-BC68-3311714A69AD")
      {
        partition.setDescription("LDM data partition");
        partition.setVendor("Windows");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "E3C9E316-0B5C-4DB8-817D-F92DF00215AE")
      {
        partition.setDescription("reserved partition");
        partition.setVendor("Windows");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "FE3A2A5D-4F32-41A7-B725-ACCC3285A309")
      {
        partition.setDescription("kernel");
        partition.setVendor("ChromeOS");
      }
      else
      if(p.PartitionTypeGUID == "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC")
      {
        partition.setDescription("root filesystem");
        partition.setVendor("ChromeOS");
      }
      else
      if(p.PartitionTypeGUID == "2E0A753D-9E48-43B0-8337-B15192CB1B5E")
      {
        partition.setDescription("reserved");
        partition.setVendor("ChromeOS");
      }
      else
      if(p.PartitionTypeGUID == "6A82CB45-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("boot partition");
        partition.setVendor("Solaris");
        partition.addCapability("boot");
      }
      else
      if(p.PartitionTypeGUID == "6A85CF4D-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("root partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "6A87C46F-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("swap partition");
        partition.setVendor("Solaris");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "6A8B642B-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("backup partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "6A8EF2E9-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("/var partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "6A90BA39-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("/home partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "6A9283A5-1DD2-11B2-99A6-080020736631")
      {
        partition.setDescription("alternate sector");
        partition.setVendor("Solaris");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "6A945A3B-1DD2-11B2-99A6-080020736631" ||
         p.PartitionTypeGUID == "6A9630D1-1DD2-11B2-99A6-080020736631" ||
         p.PartitionTypeGUID == "6A980767-1DD2-11B2-99A6-080020736631" ||
         p.PartitionTypeGUID == "6A96237F-1DD2-11B2-99A6-080020736631" ||
         p.PartitionTypeGUID == "6A8D2AC7-1DD2-11B2-99A6-080020736631"
        )
      {
        partition.setDescription("reserved partition");
        partition.setVendor("Solaris");
      }
      else
      if(p.PartitionTypeGUID == "49F48D32-B10E-11DC-B99B-0019D1879648")
      {
        partition.setDescription("swap partition");
        partition.setVendor("NetBSD");
        partition.addCapability("nofs");
      }
      else
      if(p.PartitionTypeGUID == "49F48D5A-B10E-11DC-B99B-0019D1879648")
      {
        partition.setDescription("FFS partition");
        partition.setVendor("NetBSD");
      }
      else
      if(p.PartitionTypeGUID == "49F48D82-B10E-11DC-B99B-0019D1879648")
      {
        partition.setDescription("LFS partition");
        partition.setVendor("NetBSD");
      }
      else
      if(p.PartitionTypeGUID == "49F48DAA-B10E-11DC-B99B-0019D1879648")
      {
        partition.setDescription("RAID partition");
        partition.setVendor("NetBSD");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "2DB519C4-B10F-11DC-B99B-0019D1879648")
      {
        partition.setDescription("concatenated partition");
        partition.setVendor("NetBSD");
        partition.addCapability("multi");
      }
      else
      if(p.PartitionTypeGUID == "2DB519EC-B10F-11DC-B99B-0019D1879648")
      {
        partition.setDescription("encrypted partition");
        partition.setVendor("NetBSD");
        partition.addCapability("encrypted");
      }
      else
      if(p.PartitionTypeGUID == "42465331-3ba3-10f1-802a-4861696b7521")             // is it really used ?
      {
        partition.setDescription("BeFS partition");
        partition.setVendor("Haiku");
      }
      else
        partition.setDescription("EFI partition");
      partition.setPhysId(i+1);
      partition.setCapacity(BLOCKSIZE * (p.EndingLBA - p.StartingLBA));
      partition.addHint("type", tostring(p.PartitionTypeGUID));
      partition.addHint("guid", tostring(p.PartitionGUID));
      partition.setSerial(tostring(p.PartitionGUID));
      partition.setHandle("GUID:" + tostring(p.PartitionGUID));
      partition.setConfig("name", p.PartitionName);
      if(p.Attributes && PARTITION_PRECIOUS)
        partition.addCapability("precious", "This partition is required for the platform to function");
      if(p.Attributes && PARTITION_READONLY)
        partition.addCapability("readonly", "Read-only partition");
      if(p.Attributes && PARTITION_HIDDEN)
        partition.addCapability("hidden");
      if(p.Attributes && PARTITION_NOMOUNT)
        partition.addCapability("nomount", "No automatic mount");

      partition.describeCapability("nofs", "No filesystem");
      partition.describeCapability("boot", "Contains boot code");
      partition.describeCapability("multi", "Multi-volumes");
      partition.describeCapability("hidden", "Hidden partition");
      partition.describeCapability("encrypted", "Contains encrypted data");

      spart.blocksize = s.blocksize;
      spart.offset = s.offset + p.StartingLBA*spart.blocksize;
      spart.size = (p.EndingLBA - p.StartingLBA)*spart.blocksize;
      guess_logicalname(spart, n, i+1, partition);
      scan_volume(partition, spart);
      n.addChild(partition);
    }
  }

  free(partitions);

  return true;
}

Here is the call graph for this function:

static bool detect_lif ( source s,
hwNode n 
) [static]

Definition at line 1271 of file partitions.cc.

{
  static unsigned char buffer[LIFBLOCKSIZE];
  source lifvolume;
  unsigned long dir_start = 0, dir_length = 0;
  unsigned lif_version = 0;
  unsigned long ipl_addr = 0, ipl_length = 0, ipl_entry = 0;

  if(s.offset!=0)
    return false;                                 // LIF boot volumes must be at the beginning of the disk

  lifvolume = s;
  lifvolume.blocksize = LIFBLOCKSIZE;             // LIF blocks are 256 bytes long

                                                  // read the first block
  if(readlogicalblocks(lifvolume, buffer, 0, 1)!=1)
    return false;

  if(be_short(buffer)!=0x8000)                    // wrong magic number
    return false;

  dir_start = be_long(buffer+8);
  dir_length = be_long(buffer+16);
  lif_version = be_short(buffer+20);

  if(dir_start<2) return false;                   // blocks 0 and 1 are reserved
  if(dir_length<1) return false;                  // no directory to read from
  if(lif_version<1) return false;                 // weird LIF version

  ipl_addr = be_long(buffer+240);                 // byte address of IPL on media
  ipl_length = be_long(buffer+244);               // size of boot code
  ipl_entry = be_long(buffer+248);                // boot code entry point

#if 0
  fprintf(stderr, "system: %x\n", be_short(buffer+12));
  fprintf(stderr, "start of directory: %ld\n", dir_start);
  fprintf(stderr, "length of directory: %ld\n", dir_length);
  fprintf(stderr, "lif version: %x\n", lif_version);
  fprintf(stderr, "tracks per surface: %ld\n", be_long(buffer+24));
  fprintf(stderr, "number of surfaces: %ld\n", be_long(buffer+28));
  fprintf(stderr, "blocks per track: %ld\n", be_long(buffer+32));
  fprintf(stderr, "ipl addr: %ld\n", ipl_addr);
  fprintf(stderr, "ipl length: %ld\n", ipl_length);
  fprintf(stderr, "ipl entry point: %lx\n", ipl_entry);
#endif

  if((ipl_addr!=0) && (ipl_length>0)) n.addCapability("bootable", "Bootable disk");

  return true;
}

Here is the call graph for this function:

static bool detect_luks ( source s,
hwNode n 
) [static]

Definition at line 1322 of file partitions.cc.

{
  static char buffer[BLOCKSIZE];
  source luksvolume;
  unsigned luks_version = 0;

  luksvolume = s;
  luksvolume.blocksize = BLOCKSIZE;
                                                  // read the first block
  if(readlogicalblocks(luksvolume, buffer, 0, 1)!=1)
    return false;

  if(memcmp(buffer, "LUKS", 4) != 0)                    // wrong magic number
    return false;
  if(be_short(buffer+4) != 0xbabe)
    return false;

  luks_version = be_short(buffer+6);
  if(luks_version<1)
    return false;                 // weird LUKS version
  else
  {
    hwNode partition("volume", hw::volume);
    scan_volume(partition, luksvolume);
    partition.setLogicalName(n.getLogicalName());
    n.addChild(partition);
  }

  return true;
}

Here is the call graph for this function:

static bool detect_macmap ( source s,
hwNode n 
) [static]

Definition at line 1204 of file partitions.cc.

{
  static unsigned char buffer[BLOCKSIZE];
  unsigned long count = 0, i = 0;
  unsigned long long start = 0, size = 0;
  string type = "";

  if(s.offset!=0)
    return false;                                 // partition maps must be at the beginning of the disk

  if(readlogicalblocks(s, buffer, 1, 1)!=1)       // read the second sector
    return false;

  if(be_short(buffer)!=0x504d)                    // wrong magic number
    return false;

  count = be_long(buffer+4);

  for (i = 1; i <= count; i++)
  {
    hwNode partition("volume", hw::volume);

    if((i>1) && readlogicalblocks(s, buffer, i, 1)!=1)
      return false;

    if(be_short(buffer)!=0x504d) continue;        // invalid map entry

    start = be_long(buffer + 8);
    size = be_long(buffer + 12);
    type = hw::strip(string((char*)buffer +  48, 32));

    partition.setPhysId(i);
    partition.setCapacity(size * s.blocksize);
    if(lowercase(type) == "apple_bootstrap")
      partition.addCapability("bootable", "Bootstrap partition");

    if(lowercase(type) == "linux_lvm")
    {
      partition.addHint("icon", string("md"));
      partition.addCapability("multi");
    }
    else
      partition.addHint("icon", string("disc"));

    for(unsigned int j=0; j<type.length(); j++)
      if(type[j] == '_') type[j] = ' ';
    partition.setDescription(type);

    if(true /*analyse_macpart(flags, type, start, size, partition)*/)
    {
      source spart = s;

      spart.blocksize = s.blocksize;
      spart.offset = s.offset + start*spart.blocksize;
      spart.size = size*spart.blocksize;

      guess_logicalname(spart, n, i, partition);

      scan_volume(partition, spart);
      n.addChild(partition);
    }
  }

  return true;
}

Here is the call graph for this function:

static uint32_t efi_crc32 ( const void *  buf,
unsigned long  len 
) [inline, static]

Definition at line 640 of file partitions.cc.

{
  return (__efi_crc32(buf, len, ~0L) ^ ~0L);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool guess_logicalname ( source s,
const hwNode disk,
unsigned int  n,
hwNode partition 
) [static]

Definition at line 293 of file partitions.cc.

{
  struct stat buf;
  char name[10];
  int dev = 0;

  snprintf(name, sizeof(name), "%d", n);
  if(disk.getBusInfo()!="")
    partition.setBusInfo(disk.getBusInfo()+string(",")+string(name));

  if(fstat(s.fd, &buf)!=0) return false;
  if(!S_ISBLK(buf.st_mode)) return false;

  if(s.diskname!="")
    dev = open_dev(buf.st_rdev + n, s.diskname+string(name));
  else
    dev = open_dev(buf.st_rdev + n, disk.getLogicalName()+string(name));

  if(dev>=0)
  {
    source spart = s;
    unsigned char buffer1[BLOCKSIZE], buffer2[BLOCKSIZE];

    spart.offset = 0;
    spart.fd = dev;
    spart.diskname = "";

    // read the first sector
    if((readlogicalblocks(s, buffer1, 0, 1)!=1) ||
      (readlogicalblocks(spart, buffer2, 0, 1)!=1))
    {
      close(dev);
      return false;
    }

    close(dev);

    if(memcmp(buffer1, buffer2, BLOCKSIZE)==0)
    {
      partition.claim();
      if(s.diskname!="")
        partition.setLogicalName(s.diskname+string(name));
      else
        partition.setLogicalName(disk.getLogicalName()+string(name));
      return true;
    }
  }

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bool is_extended ( unsigned char  type) [static]

Definition at line 345 of file partitions.cc.

{
  return (type == 0x5) || (type == 0xf) || (type == 0x85);
}

Here is the caller graph for this function:

bool operator== ( const efi_guid_t guid1,
const efi_guid_t guid2 
)

Definition at line 663 of file partitions.cc.

{
  return (guid1.time_low == guid2.time_low) &&
    (guid1.time_mid == guid2.time_mid) &&
    (guid1.time_hi_and_version == guid2.time_hi_and_version) &&
    (guid1.clock_seq_hi_and_reserved == guid2.clock_seq_hi_and_reserved) &&
    (guid1.clock_seq_low == guid2.clock_seq_low) &&
    (memcmp(guid1.node, guid2.node, sizeof(guid1.node))==0);
}
bool operator== ( const efi_guid_t guid1,
const string &  guid2 
)

Definition at line 682 of file partitions.cc.

{
  return strcasecmp(tostring(guid1).c_str(), guid2.c_str()) == 0;
}

Here is the call graph for this function:

static bool read_dospartition ( source s,
unsigned short  i,
dospartition p 
) [static]

Definition at line 351 of file partitions.cc.

{
  static unsigned char buffer[BLOCKSIZE];
  unsigned char flags = 0;

  if(readlogicalblocks(s, buffer, 0, 1)!=1)       // read the first sector
    return false;

  if(le_short(buffer+510)!=0xaa55)                // wrong magic number
    return false;

  flags = buffer[446 + i*16];
  if(flags!=0 && flags!=0x80)
// inconsistency: partition is either
    return false;                                 // bootable or non-bootable

  p.flags = flags;
  p.type = buffer[446 + i*16 + 4];
  p.start = s.blocksize*(unsigned long long)le_long(buffer + 446 + i*16 + 8);
  p.size = s.blocksize*(unsigned long long)le_long(buffer + 446 + i*16 + 12);

  return true;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static efi_guid_t read_efi_guid ( uint8_t *  buffer) [static]

Definition at line 646 of file partitions.cc.

{
  efi_guid_t result;

  memset(&result, 0, sizeof(result));

  result.time_low = le_long(buffer);
  result.time_mid = le_short(buffer+4);
  result.time_hi_and_version = le_short(buffer+4+2);
  result.clock_seq_hi_and_reserved = *(buffer+4+2+2);
  result.clock_seq_low = *(buffer+4+2+2+1);
  memcpy(result.node, buffer+4+2+2+1+1, sizeof(result.node));

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool scan_partitions ( hwNode n)

Definition at line 1353 of file partitions.cc.

{
  int i = 0;
  source s;
  int fd = open(n.getLogicalName().c_str(), O_RDONLY | O_NONBLOCK);
  hwNode * medium = NULL;

  if (fd < 0)
    return false;

  if(n.isCapable("removable"))
  {
    medium = n.addChild(hwNode("medium", hw::disk));

    medium->claim();
    medium->setSize(n.getSize());
    medium->setCapacity(n.getCapacity());
    medium->setLogicalName(n.getLogicalName());
  }
  else
    medium = &n;

  s.diskname = n.getLogicalName();
  s.fd = fd;
  s.offset = 0;
  s.blocksize = BLOCKSIZE;
  s.size = medium->getSize();

  while(map_types[i].id)
  {
    if(map_types[i].detect && map_types[i].detect(s, *medium))
    {
      medium->addCapability(string("partitioned"), "Partitioned disk");
      medium->addCapability(string("partitioned:") + string(map_types[i].id), string(map_types[i].description));
      break;
    }
    i++;
  }

  if(!medium->isCapable("partitioned"))
  {
    if(scan_volume(*medium, s))    // whole disk volume?
      medium->setClass(hw::volume);
  }

  close(fd);

//if(medium != &n) free(medium);

  return false;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static string tostring ( const efi_guid_t guid) [static]

Definition at line 674 of file partitions.cc.

{
  char buffer[50];

  snprintf(buffer, sizeof(buffer), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid.time_low, guid.time_mid,guid.time_hi_and_version,guid.clock_seq_hi_and_reserved,guid.clock_seq_low,guid.node[0],guid.node[1],guid.node[2],guid.node[3],guid.node[4],guid.node[5]);
  return string(buffer);
}

Variable Documentation

uint32_t crc32_tab[] [static]

Definition at line 559 of file partitions.cc.

unsigned int lastlogicalpart = 5 [static]

Definition at line 291 of file partitions.cc.

struct maptypes[] [static]
Initial value:
{
  {"bsd", "BSD disklabel", NULL},
  {"gpt", "GUID partition table", detect_gpt},
  {"dos", "MS-DOS partition table", detect_dosmap},
  {"mac", "Apple Macintosh partition map", detect_macmap},
  {"lif", "HP-UX LIF", detect_lif},
  {"luks", "Linux Unified Key Setup", detect_luks},
  {"solaris-x86", "Solaris disklabel", NULL},
  {"solaris-sparc", "Solaris disklabel", NULL},
  {"raid", "Linux RAID", NULL},
  {"lvm", "Linux LVM Physical Volume", NULL},
  {"atari", "Atari ST", NULL},
  {"amiga", "Amiga", NULL},
  { NULL, NULL, NULL }
}

Definition at line 49 of file partitions.cc.

struct systypes[] [static]

Definition at line 131 of file partitions.cc.