summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--configure.in19
-rw-r--r--doc/api/tmpl/hal-unused.sgml299
-rw-r--r--doc/api/tmpl/libhal-storage.sgml324
-rw-r--r--doc/spec/hal-spec-properties.xml208
-rw-r--r--doc/spec/hal-spec.html1081
-rw-r--r--hald/linux/addons/addon-storage.c9
-rw-r--r--hald/linux/blockdev.c2
-rw-r--r--hald/linux/probing/Makefile.am4
-rw-r--r--hald/linux/probing/probe-storage.c182
-rw-r--r--hald/linux/probing/probe-volume.c439
-rw-r--r--libhal-storage/libhal-storage.c59
-rw-r--r--libhal-storage/libhal-storage.h64
-rw-r--r--libhal/libhal.h7
-rw-r--r--partutil/Makefile.am11
-rw-r--r--partutil/partutil.c1791
-rw-r--r--partutil/partutil.h412
17 files changed, 4120 insertions, 793 deletions
diff --git a/Makefile.am b/Makefile.am
index d0838701..16968d21 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = libhal libhal-storage hald hald-runner tools \
+SUBDIRS = libhal libhal-storage partutil hald hald-runner tools \
fdi doc po privileges
pkgconfigdir = $(libdir)/pkgconfig
diff --git a/configure.in b/configure.in
index 42b0cf94..cedcb226 100644
--- a/configure.in
+++ b/configure.in
@@ -100,6 +100,21 @@ fi
AC_SUBST(ACPI_PROC)
AM_CONDITIONAL(ACPI_PROC, test x$acpi_proc = xyes)
+
+dnl libparted
+AC_ARG_ENABLE([parted], AC_HELP_STRING([--enable-parted], [Use libparted]), [use_parted=$enableval], [use_parted=no])
+if test "x$use_parted" = "xyes" ; then
+ USE_PARTED=yes
+ AC_DEFINE(USE_PARTED,1,[Whether libparted is to be used])
+ PARTED_CHECK_LIBPARTED(1.7.1, ,
+ [AC_MSG_ERROR([*** libparted >= 1.7.1 not installed - please install first ***])])
+else
+ USE_PARTED=no
+fi
+AC_SUBST(USE_PARTED)
+AM_CONDITIONAL(USE_PARTED, test x$use_parted == xyes)
+
+
#### gcc warning flags
if test "x$GCC" = "xyes"; then
@@ -184,7 +199,7 @@ AM_CONDITIONAL(GCOV, test x$enable_gcov = xyes)
EXPAT_LIB=""
-AC_ARG_WITH(expat, [ --with-expat=<dir> ese expat from here],
+AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
[
expat=$withval
CPPFLAGS="$CPPFLAGS -I$withval/include"
@@ -457,6 +472,7 @@ tools/linux/Makefile
tools/device-manager/hal-device-manager
tools/device-manager/Makefile
tools/device-manager/Const.py
+partutil/Makefile
privileges/Makefile
fdi/Makefile
fdi/preprobe/Makefile
@@ -510,6 +526,7 @@ echo "
use acpid interface: ${acpi_acpid}
use libusb: ${USE_LIBUSB}
use libpci: ${USE_LIBPCI}
+ use libparted: ${USE_PARTED}
use PolicyKit: ${msg_polkit}
diff --git a/doc/api/tmpl/hal-unused.sgml b/doc/api/tmpl/hal-unused.sgml
index 0f22ab22..6fb25b02 100644
--- a/doc/api/tmpl/hal-unused.sgml
+++ b/doc/api/tmpl/hal-unused.sgml
@@ -370,6 +370,61 @@ sysfs
</para>
+<!-- ##### ENUM LibHalDriveBus ##### -->
+<para>
+
+</para>
+
+@LIBHAL_DRIVE_BUS_UNKNOWN:
+@LIBHAL_DRIVE_BUS_IDE:
+@LIBHAL_DRIVE_BUS_SCSI:
+@LIBHAL_DRIVE_BUS_USB:
+@LIBHAL_DRIVE_BUS_IEEE1394:
+@LIBHAL_DRIVE_BUS_CCW:
+
+<!-- ##### ENUM LibHalDriveCdromCaps ##### -->
+<para>
+
+</para>
+
+@LIBHAL_DRIVE_CDROM_CAPS_CDROM:
+@LIBHAL_DRIVE_CDROM_CAPS_CDR:
+@LIBHAL_DRIVE_CDROM_CAPS_CDRW:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDRAM:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDROM:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDR:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDRW:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL:
+@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL:
+@LIBHAL_DRIVE_CDROM_CAPS_BDROM:
+@LIBHAL_DRIVE_CDROM_CAPS_BDR:
+@LIBHAL_DRIVE_CDROM_CAPS_BDRE:
+@LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM:
+@LIBHAL_DRIVE_CDROM_CAPS_HDDVDR:
+@LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW:
+
+<!-- ##### ENUM LibHalDriveType ##### -->
+<para>
+
+</para>
+
+@LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
+@LIBHAL_DRIVE_TYPE_DISK:
+@LIBHAL_DRIVE_TYPE_CDROM:
+@LIBHAL_DRIVE_TYPE_FLOPPY:
+@LIBHAL_DRIVE_TYPE_TAPE:
+@LIBHAL_DRIVE_TYPE_COMPACT_FLASH:
+@LIBHAL_DRIVE_TYPE_MEMORY_STICK:
+@LIBHAL_DRIVE_TYPE_SMART_MEDIA:
+@LIBHAL_DRIVE_TYPE_SD_MMC:
+@LIBHAL_DRIVE_TYPE_CAMERA:
+@LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
+@LIBHAL_DRIVE_TYPE_ZIP:
+@LIBHAL_DRIVE_TYPE_JAZ:
+@LIBHAL_DRIVE_TYPE_FLASHKEY:
+
<!-- ##### TYPEDEF LibHalPolicyContext ##### -->
<para>
@@ -413,6 +468,40 @@ sysfs
@LIBHAL_POLICY_RESULT_PERMISSON_DENIED:
@LIBHAL_POLICY_RESULT_NO_SUCH_POLICY:
+<!-- ##### ENUM LibHalVolumeDiscType ##### -->
+<para>
+
+</para>
+
+@LIBHAL_VOLUME_DISC_TYPE_CDROM:
+@LIBHAL_VOLUME_DISC_TYPE_CDR:
+@LIBHAL_VOLUME_DISC_TYPE_CDRW:
+@LIBHAL_VOLUME_DISC_TYPE_DVDROM:
+@LIBHAL_VOLUME_DISC_TYPE_DVDRAM:
+@LIBHAL_VOLUME_DISC_TYPE_DVDR:
+@LIBHAL_VOLUME_DISC_TYPE_DVDRW:
+@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR:
+@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW:
+@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL:
+@LIBHAL_VOLUME_DISC_TYPE_BDROM:
+@LIBHAL_VOLUME_DISC_TYPE_BDR:
+@LIBHAL_VOLUME_DISC_TYPE_BDRE:
+@LIBHAL_VOLUME_DISC_TYPE_HDDVDROM:
+@LIBHAL_VOLUME_DISC_TYPE_HDDVDR:
+@LIBHAL_VOLUME_DISC_TYPE_HDDVDRW:
+
+<!-- ##### ENUM LibHalVolumeUsage ##### -->
+<para>
+
+</para>
+
+@LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM:
+@LIBHAL_VOLUME_USAGE_PARTITION_TABLE:
+@LIBHAL_VOLUME_USAGE_RAID_MEMBER:
+@LIBHAL_VOLUME_USAGE_CRYPTO:
+@LIBHAL_VOLUME_USAGE_UNKNOWN:
+@LIBHAL_VOLUME_USAGE_OTHER:
+
<!-- ##### MACRO SB_BUFFER_SIZE ##### -->
<para>
@@ -975,6 +1064,95 @@ sysfs
@x:
+<!-- ##### FUNCTION libhal_drive_find_all_volumes ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@drive:
+@num_volumes:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_from_udi ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@udi:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_compute_icon_name ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_primary ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_secondary ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_default_use_managed_keyword ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_get_desired_mount_point ##### -->
+<para>
+
+</para>
+
+@drive:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_get_mount_fs ##### -->
+<para>
+
+</para>
+
+@drive:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_get_mount_options ##### -->
+<para>
+
+</para>
+
+@drive:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_drive_policy_is_mountable ##### -->
+<para>
+
+</para>
+
+@drive:
+@policy:
+@Returns:
+
<!-- ##### FUNCTION libhal_policy_context_set_txt_source ##### -->
<para>
@@ -1238,6 +1416,127 @@ sysfs
@default_gid:
@Returns:
+<!-- ##### FUNCTION libhal_storage_policy_free ##### -->
+<para>
+
+</para>
+
+@policy:
+
+<!-- ##### FUNCTION libhal_storage_policy_lookup_icon ##### -->
+<para>
+
+</para>
+
+@policy:
+@icon:
+@Returns:
+
+<!-- ##### FUNCTION libhal_storage_policy_set_icon_mapping ##### -->
+<para>
+
+</para>
+
+@policy:
+@pairs:
+
+<!-- ##### FUNCTION libhal_storage_policy_set_icon_path ##### -->
+<para>
+
+</para>
+
+@policy:
+@icon:
+@path:
+
+<!-- ##### FUNCTION libhal_volume_from_udi ##### -->
+<para>
+
+</para>
+
+@hal_ctx:
+@udi:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_compute_display_name ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_compute_icon_name ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_compute_size_as_string ##### -->
+<para>
+
+</para>
+
+@volume:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_get_desired_mount_point ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_get_mount_fs ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_get_mount_options ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_is_mountable ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@Returns:
+
+<!-- ##### FUNCTION libhal_volume_policy_should_be_visible ##### -->
+<para>
+
+</para>
+
+@drive:
+@volume:
+@policy:
+@target_mount_point:
+@Returns:
+
<!-- ##### FUNCTION lstat ##### -->
<para>
diff --git a/doc/api/tmpl/libhal-storage.sgml b/doc/api/tmpl/libhal-storage.sgml
index ae280397..c99e3c21 100644
--- a/doc/api/tmpl/libhal-storage.sgml
+++ b/doc/api/tmpl/libhal-storage.sgml
@@ -151,108 +151,6 @@ libhal-storage
@Returns:
-<!-- ##### FUNCTION libhal_storage_policy_free ##### -->
-<para>
-
-</para>
-
-@policy:
-
-
-<!-- ##### FUNCTION libhal_storage_policy_set_icon_path ##### -->
-<para>
-
-</para>
-
-@policy:
-@icon:
-@path:
-
-
-<!-- ##### FUNCTION libhal_storage_policy_set_icon_mapping ##### -->
-<para>
-
-</para>
-
-@policy:
-@pairs:
-
-
-<!-- ##### FUNCTION libhal_storage_policy_lookup_icon ##### -->
-<para>
-
-</para>
-
-@policy:
-@icon:
-@Returns:
-
-
-<!-- ##### ENUM LibHalDriveBus ##### -->
-<para>
-
-</para>
-
-@LIBHAL_DRIVE_BUS_UNKNOWN:
-@LIBHAL_DRIVE_BUS_IDE:
-@LIBHAL_DRIVE_BUS_SCSI:
-@LIBHAL_DRIVE_BUS_USB:
-@LIBHAL_DRIVE_BUS_IEEE1394:
-@LIBHAL_DRIVE_BUS_CCW:
-
-<!-- ##### ENUM LibHalDriveType ##### -->
-<para>
-
-</para>
-
-@LIBHAL_DRIVE_TYPE_REMOVABLE_DISK:
-@LIBHAL_DRIVE_TYPE_DISK:
-@LIBHAL_DRIVE_TYPE_CDROM:
-@LIBHAL_DRIVE_TYPE_FLOPPY:
-@LIBHAL_DRIVE_TYPE_TAPE:
-@LIBHAL_DRIVE_TYPE_COMPACT_FLASH:
-@LIBHAL_DRIVE_TYPE_MEMORY_STICK:
-@LIBHAL_DRIVE_TYPE_SMART_MEDIA:
-@LIBHAL_DRIVE_TYPE_SD_MMC:
-@LIBHAL_DRIVE_TYPE_CAMERA:
-@LIBHAL_DRIVE_TYPE_PORTABLE_AUDIO_PLAYER:
-@LIBHAL_DRIVE_TYPE_ZIP:
-@LIBHAL_DRIVE_TYPE_JAZ:
-@LIBHAL_DRIVE_TYPE_FLASHKEY:
-
-<!-- ##### ENUM LibHalDriveCdromCaps ##### -->
-<para>
-
-</para>
-
-@LIBHAL_DRIVE_CDROM_CAPS_CDROM:
-@LIBHAL_DRIVE_CDROM_CAPS_CDR:
-@LIBHAL_DRIVE_CDROM_CAPS_CDRW:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDRAM:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDROM:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDR:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDRW:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSR:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRW:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRDL:
-@LIBHAL_DRIVE_CDROM_CAPS_DVDPLUSRWDL:
-@LIBHAL_DRIVE_CDROM_CAPS_BDROM:
-@LIBHAL_DRIVE_CDROM_CAPS_BDR:
-@LIBHAL_DRIVE_CDROM_CAPS_BDRE:
-@LIBHAL_DRIVE_CDROM_CAPS_HDDVDROM:
-@LIBHAL_DRIVE_CDROM_CAPS_HDDVDR:
-@LIBHAL_DRIVE_CDROM_CAPS_HDDVDRW:
-
-<!-- ##### FUNCTION libhal_drive_from_udi ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@udi:
-@Returns:
-
-
<!-- ##### FUNCTION libhal_drive_from_device_file ##### -->
<para>
@@ -476,69 +374,6 @@ libhal-storage
@drive:
@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_compute_icon_name ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_is_mountable ##### -->
-<para>
-
-</para>
-
-@drive:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_get_desired_mount_point ##### -->
-<para>
-
-</para>
-
-@drive:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_get_mount_options ##### -->
-<para>
-
-</para>
-
-@drive:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_get_mount_fs ##### -->
-<para>
-
-</para>
-
-@drive:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_find_all_volumes ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@drive:
-@num_volumes:
@Returns:
@@ -547,78 +382,6 @@ libhal-storage
</para>
-@hal_ctx:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_default_use_managed_keyword ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_primary ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_drive_policy_default_get_managed_keyword_secondary ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@Returns:
-
-
-<!-- ##### ENUM LibHalVolumeUsage ##### -->
-<para>
-
-</para>
-
-@LIBHAL_VOLUME_USAGE_MOUNTABLE_FILESYSTEM:
-@LIBHAL_VOLUME_USAGE_PARTITION_TABLE:
-@LIBHAL_VOLUME_USAGE_RAID_MEMBER:
-@LIBHAL_VOLUME_USAGE_CRYPTO:
-@LIBHAL_VOLUME_USAGE_UNKNOWN:
-@LIBHAL_VOLUME_USAGE_OTHER:
-
-<!-- ##### ENUM LibHalVolumeDiscType ##### -->
-<para>
-
-</para>
-
-@LIBHAL_VOLUME_DISC_TYPE_CDROM:
-@LIBHAL_VOLUME_DISC_TYPE_CDR:
-@LIBHAL_VOLUME_DISC_TYPE_CDRW:
-@LIBHAL_VOLUME_DISC_TYPE_DVDROM:
-@LIBHAL_VOLUME_DISC_TYPE_DVDRAM:
-@LIBHAL_VOLUME_DISC_TYPE_DVDR:
-@LIBHAL_VOLUME_DISC_TYPE_DVDRW:
-@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR:
-@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSRW:
-@LIBHAL_VOLUME_DISC_TYPE_DVDPLUSR_DL:
-@LIBHAL_VOLUME_DISC_TYPE_BDROM:
-@LIBHAL_VOLUME_DISC_TYPE_BDR:
-@LIBHAL_VOLUME_DISC_TYPE_BDRE:
-@LIBHAL_VOLUME_DISC_TYPE_HDDVDROM:
-@LIBHAL_VOLUME_DISC_TYPE_HDDVDR:
-@LIBHAL_VOLUME_DISC_TYPE_HDDVDRW:
-
-<!-- ##### FUNCTION libhal_volume_from_udi ##### -->
-<para>
-
-</para>
-
-@hal_ctx:
-@udi:
@Returns:
@@ -929,90 +692,3 @@ libhal-storage
@Returns:
-<!-- ##### FUNCTION libhal_volume_policy_compute_size_as_string ##### -->
-<para>
-
-</para>
-
-@volume:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_compute_display_name ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_compute_icon_name ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_should_be_visible ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@target_mount_point:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_is_mountable ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_get_desired_mount_point ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_get_mount_options ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
-<!-- ##### FUNCTION libhal_volume_policy_get_mount_fs ##### -->
-<para>
-
-</para>
-
-@drive:
-@volume:
-@policy:
-@Returns:
-
-
diff --git a/doc/spec/hal-spec-properties.xml b/doc/spec/hal-spec-properties.xml
index c3ff5223..77fac0bd 100644
--- a/doc/spec/hal-spec-properties.xml
+++ b/doc/spec/hal-spec-properties.xml
@@ -2288,9 +2288,7 @@
<entry>partitiontable</entry>
<entry></entry>
<entry>
- The volume contains a partitiontable. If an MS-DOS extended
- partition table is found, then <literal>volume.fstype</literal>
- will be <literal>msdos_extended_partitiontable</literal>.
+ The volume contains a partitiontable.
</entry>
</row>
<row>
@@ -2315,7 +2313,7 @@
<entry>
<literal>volume.fstype</literal> (string)
</entry>
- <entry>examples: ext3, vfat, msdos_extended_partitiontable</entry>
+ <entry>examples: ext3, vfat</entry>
<entry>Yes (is blank if the type is unknown)</entry>
<entry>The specific type of either the file system or what the volume is used for, cf. volume.fsusage</entry>
</row>
@@ -2405,6 +2403,7 @@
If the volume stems from the Linux Device Mapper this property is set to <literal>TRUE</literal>.
</entry>
</row>
+
<row>
<entry>
<literal>volume.partition.number</literal> (int)
@@ -2418,53 +2417,188 @@
The number of the partition.
</entry>
</row>
+
+
<row>
<entry>
- <literal>volume.partition.msdos_part_table_type</literal> (int)
+ <literal>volume.partition.label</literal> (string)
</entry>
- <entry>examples: 0x83, 0xfd, 0x8e</entry>
+ <entry></entry>
<entry>
- No
+ If, and only if, <literal>volume.is_partition</literal>
+ is set to <literal>TRUE</literal>.
</entry>
<entry>
- If available, this is the partition type if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
+ Label of partition. Only available for "apm" and "gpt"
+ partition tables. Note that this is not the same as the
+ file system label defined in <literal>volume.label</literal>.
</entry>
</row>
<row>
<entry>
- <literal>volume.partition.msdos_part_table_start</literal> (uint64)
+ <literal>volume.partition.uuid</literal> (string)
</entry>
<entry></entry>
<entry>
- No
+ If, and only if, <literal>volume.is_partition</literal>
+ is set to <literal>TRUE</literal>.
</entry>
<entry>
- If available, this is the partition start offset if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
+ The UUID or GUID of the partition table entry. Only available for
+ "gpt" partition tables.
</entry>
</row>
+
<row>
<entry>
- <literal>volume.partition.msdos_part_table_size</literal> (uint64)
+ <literal>volume.partition.scheme</literal> (string)
</entry>
<entry></entry>
<entry>
- No
+ If, and only if, <literal>volume.is_partition</literal>
+ is set to <literal>TRUE</literal>.
</entry>
<entry>
- If available, this is the partition size if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
- This information is derived from the partition table so it might
- not be reliable and match e.g. <literal>volume.size</literal>.
- Specifically, for MS-DOS extended partition tables, this number
- will be larger as the actual volume is only e.g. 1 kilobyte
- (e.g. <literal>volume.size</literal>) while
- <literal>volume.partition.msdos_part_table_size</literal>
- will be the size enclosing all the logical partitions.
+ The scheme of the partition table this entry is part of.
+ Note that this is not necessarily the same as
+ <literal>storage.partitioning_scheme</literal> as
+ some partition tables can embed other partition tables.
</entry>
</row>
<row>
+ <entry></entry>
+ <entry>mbr</entry>
+ <entry></entry>
+ <entry>
+ Master Boot Record
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>embr</entry>
+ <entry></entry>
+ <entry>
+ Extended Master Boot Record
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>gpt</entry>
+ <entry></entry>
+ <entry>
+ GUID Partition Table as defined by EFI
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>apm</entry>
+ <entry></entry>
+ <entry>
+ Apple Partition Map
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>volume.partition.type</literal> (string)
+ </entry>
+ <entry></entry>
+ <entry>
+ If, and only if, <literal>volume.is_partition</literal>
+ is set to <literal>TRUE</literal>.
+ </entry>
+ <entry>
+ The type of the partition table entry. Depends on
+ <literal>volume.partition.scheme</literal>.
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>mbr</literal> and <literal>embr</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ The hexadecimal encoding of the 8-bit partition type, see
+ http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
+ for a list. For example the Linux partition type is represented
+ as the string "0x83".
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>gpt</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ The GUID encoded as a string. See http://en.wikipedia.org/wiki/GUID_Partition_Table
+ for a list of well-known GUID's.
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>apm</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ Defined in http://developer.apple.com/documentation/mac/Devices/Devices-126.html.
+ Also note that for FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16"
+ and "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf.
+ http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html
+ </entry>
+ </row>
+
+ <row>
+ <entry>
+ <literal>volume.partition.flags</literal> (strlist)
+ </entry>
+ <entry></entry>
+ <entry>
+ If, and only if, <literal>volume.is_partition</literal>
+ is set to <literal>TRUE</literal>.
+ </entry>
+ <entry>
+ Flags conveying specific information about the partition
+ entry. Dependent on the partitioning scheme.
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>mbr</literal> and <literal>embr</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ Only one flag, "boot", is defined. This is used by some BIOS'es and
+ boot loaders to populate a boot menu. It means that a partition is
+ bootable.
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>gpt</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ Only the flag "required" is recognized. This corresponds to
+ bit 0 of the attibutes (at offset 48), meaning
+ "Required for the platform to function. The system cannot
+ function normally if this partition is removed. This
+ partition should be considered as part of the hardware of the
+ system, and if it is removed the system may not boot. It may
+ contain diagnostics, recovery tools, or other code or data that is
+ critical to the functioning of a system independent of any OS."
+ </entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry><literal>apm</literal> entries</entry>
+ <entry></entry>
+ <entry>
+ The following flags are recognized:
+ "allocated" if the partition is already allocated; and
+ "in_use" if the partition is in use; may be cleared after a system reset; and
+ "boot" if partition contains valid boot information; and
+ "allow_read" if partition allows reading; and
+ "allow_write"; if partition allows writing; and
+ "boot_code_is_pic"; if boot code is position independent
+ </entry>
+ </row>
+
+ <row>
<entry>
<literal>volume.partition.media_size</literal> (uint64)
</entry>
@@ -3026,6 +3160,32 @@
</row>
<row>
<entry>
+ <literal>storage.partitioning_scheme</literal> (string)
+ </entry>
+ <entry></entry>
+ <entry>Only when media is inserted and is partitioned</entry>
+ <entry>The partitioning scheme of the media.</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>mbr</entry>
+ <entry></entry>
+ <entry>Master Boot Record partitioning scheme used in most PC's</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>gpt</entry>
+ <entry></entry>
+ <entry>GUID Partitioning Table as defined by UEFI</entry>
+ </row>
+ <row>
+ <entry></entry>
+ <entry>apm</entry>
+ <entry></entry>
+ <entry>Apple Partition Map, used in non-Intel Apple computers</entry>
+ </row>
+ <row>
+ <entry>
<literal>storage.size</literal> (uint64)
</entry>
<entry></entry>
diff --git a/doc/spec/hal-spec.html b/doc/spec/hal-spec.html
index e77fde13..561d03e9 100644
--- a/doc/spec/hal-spec.html
+++ b/doc/spec/hal-spec.html
@@ -609,14 +609,24 @@ HREF="#dbus-api"
><DL
><DT
><A
-HREF="#AEN4036"
+HREF="#AEN4328"
>Interface org.freedesktop.Hal.Manager</A
></DT
><DT
><A
-HREF="#AEN4055"
+HREF="#AEN4347"
>Interface org.freedesktop.Hal.Device</A
></DT
+><DT
+><A
+HREF="#AEN4356"
+>Interface org.freedesktop.Hal.Device.Volume</A
+></DT
+><DT
+><A
+HREF="#AEN4360"
+>Interface org.freedesktop.Hal.Device.Storage</A
+></DT
></DL
></DD
><DT
@@ -3159,6 +3169,120 @@ CLASS="literal"
><TD
>SCSI Logical Unit Number</TD
></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>scsi.type</TT
+> (string)
+ </TD
+><TD
+>Example: disk</TD
+><TD
+>Yes</TD
+><TD
+>SCSI device type</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>cdrom</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI cdrom device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>comm</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI communication device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>disk</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI disk device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>medium_changer</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI media changer (e.g. for CD/Tape).</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>printer</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI printer.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>processor</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI processor device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>raid</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI raid device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>scanner</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI scanner.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>tape</TD
+><TD
+>&nbsp;</TD
+><TD
+>This is a SCSI tape device.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>unknown</TD
+><TD
+>&nbsp;</TD
+><TD
+>The type of this SCSI device is unknwon.</TD
+></TR
></TBODY
></TABLE
><P
@@ -3193,7 +3317,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN804"
+NAME="AEN860"
></A
><TABLE
BORDER="1"
@@ -3318,7 +3442,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN849"
+NAME="AEN905"
></A
><TABLE
BORDER="1"
@@ -3442,7 +3566,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN894"
+NAME="AEN950"
></A
><TABLE
BORDER="1"
@@ -3511,7 +3635,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN915"
+NAME="AEN971"
></A
><TABLE
BORDER="1"
@@ -3580,7 +3704,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN936"
+NAME="AEN992"
></A
><TABLE
BORDER="1"
@@ -3763,7 +3887,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1005"
+NAME="AEN1061"
></A
><TABLE
BORDER="1"
@@ -3953,7 +4077,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1079"
+NAME="AEN1135"
></A
><TABLE
BORDER="1"
@@ -4045,7 +4169,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1111"
+NAME="AEN1167"
></A
><TABLE
BORDER="1"
@@ -4119,7 +4243,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1136"
+NAME="AEN1192"
></A
><TABLE
BORDER="1"
@@ -4230,7 +4354,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1175"
+NAME="AEN1231"
></A
><TABLE
BORDER="1"
@@ -4330,7 +4454,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1209"
+NAME="AEN1265"
></A
><TABLE
BORDER="1"
@@ -4402,7 +4526,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1234"
+NAME="AEN1290"
></A
><TABLE
BORDER="1"
@@ -4687,7 +4811,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1343"
+NAME="AEN1399"
></A
><TABLE
BORDER="1"
@@ -4773,7 +4897,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1374"
+NAME="AEN1430"
></A
><TABLE
BORDER="1"
@@ -4859,7 +4983,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1405"
+NAME="AEN1461"
></A
><TABLE
BORDER="1"
@@ -5016,7 +5140,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1465"
+NAME="AEN1521"
></A
><TABLE
BORDER="1"
@@ -5074,7 +5198,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1484"
+NAME="AEN1540"
></A
><TABLE
BORDER="1"
@@ -5160,7 +5284,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1512"
+NAME="AEN1568"
></A
><TABLE
BORDER="1"
@@ -5339,7 +5463,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1568"
+NAME="AEN1624"
></A
><TABLE
BORDER="1"
@@ -5460,7 +5584,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1606"
+NAME="AEN1662"
></A
><TABLE
BORDER="1"
@@ -5579,15 +5703,7 @@ CLASS="literal"
><TD
>&nbsp;</TD
><TD
->&#13; The volume contains a partitiontable. If an MS-DOS extended
- partition table is found, then <TT
-CLASS="literal"
->volume.fstype</TT
->
- will be <TT
-CLASS="literal"
->msdos_extended_partitiontable</TT
->.
+>&#13; The volume contains a partitiontable.
</TD
></TR
><TR
@@ -5628,7 +5744,7 @@ CLASS="literal"
> (string)
</TD
><TD
->examples: ext3, vfat, msdos_extended_partitiontable</TD
+>examples: ext3, vfat</TD
><TD
>Yes (is blank if the type is unknown)</TD
><TD
@@ -5805,67 +5921,288 @@ CLASS="literal"
><TD
>&#13; <TT
CLASS="literal"
->volume.partition.msdos_part_table_type</TT
-> (int)
+>volume.partition.label</TT
+> (string)
</TD
><TD
->examples: 0x83, 0xfd, 0x8e</TD
+>&nbsp;</TD
><TD
->&#13; No
+>&#13; If, and only if, <TT
+CLASS="literal"
+>volume.is_partition</TT
+>
+ is set to <TT
+CLASS="literal"
+>TRUE</TT
+>.
</TD
><TD
->&#13; If available, this is the partition type if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
+>&#13; Label of partition. Only available for "apm" and "gpt"
+ partition tables. Note that this is not the same as the
+ file system label defined in <TT
+CLASS="literal"
+>volume.label</TT
+>.
</TD
></TR
><TR
><TD
>&#13; <TT
CLASS="literal"
->volume.partition.msdos_part_table_start</TT
-> (uint64)
+>volume.partition.uuid</TT
+> (string)
</TD
><TD
>&nbsp;</TD
><TD
->&#13; No
+>&#13; If, and only if, <TT
+CLASS="literal"
+>volume.is_partition</TT
+>
+ is set to <TT
+CLASS="literal"
+>TRUE</TT
+>.
</TD
><TD
->&#13; If available, this is the partition start offset if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
+>&#13; The UUID or GUID of the partition table entry. Only available for
+ "gpt" partition tables.
</TD
></TR
><TR
><TD
>&#13; <TT
CLASS="literal"
->volume.partition.msdos_part_table_size</TT
-> (uint64)
+>volume.partition.scheme</TT
+> (string)
</TD
><TD
>&nbsp;</TD
><TD
->&#13; No
+>&#13; If, and only if, <TT
+CLASS="literal"
+>volume.is_partition</TT
+>
+ is set to <TT
+CLASS="literal"
+>TRUE</TT
+>.
</TD
><TD
->&#13; If available, this is the partition size if the disk for which
- this volume stems from is using an MS-DOS-style partition table.
- This information is derived from the partition table so it might
- not be reliable and match e.g. <TT
+>&#13; The scheme of the partition table this entry is part of.
+ Note that this is not necessarily the same as
+ <TT
CLASS="literal"
->volume.size</TT
->.
- Specifically, for MS-DOS extended partition tables, this number
- will be larger as the actual volume is only e.g. 1 kilobyte
- (e.g. <TT
+>storage.partitioning_scheme</TT
+> as
+ some partition tables can embed other partition tables.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>mbr</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Master Boot Record
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>embr</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Extended Master Boot Record
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>gpt</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; GUID Partition Table as defined by EFI
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>apm</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Apple Partition Map
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
CLASS="literal"
->volume.size</TT
->) while
+>volume.partition.type</TT
+> (string)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; If, and only if, <TT
+CLASS="literal"
+>volume.is_partition</TT
+>
+ is set to <TT
+CLASS="literal"
+>TRUE</TT
+>.
+ </TD
+><TD
+>&#13; The type of the partition table entry. Depends on
<TT
CLASS="literal"
->volume.partition.msdos_part_table_size</TT
+>volume.partition.scheme</TT
+>.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>mbr</TT
+> and <TT
+CLASS="literal"
+>embr</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; The hexadecimal encoding of the 8-bit partition type, see
+ http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
+ for a list. For example the Linux partition type is represented
+ as the string "0x83".
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>gpt</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; The GUID encoded as a string. See http://en.wikipedia.org/wiki/GUID_Partition_Table
+ for a list of well-known GUID's.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>apm</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Defined in http://developer.apple.com/documentation/mac/Devices/Devices-126.html.
+ Also note that for FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16"
+ and "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf.
+ http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>volume.partition.flags</TT
+> (strlist)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; If, and only if, <TT
+CLASS="literal"
+>volume.is_partition</TT
>
- will be the size enclosing all the logical partitions.
+ is set to <TT
+CLASS="literal"
+>TRUE</TT
+>.
+ </TD
+><TD
+>&#13; Flags conveying specific information about the partition
+ entry. Dependent on the partitioning scheme.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>mbr</TT
+> and <TT
+CLASS="literal"
+>embr</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Only one flag, "boot", is defined. This is used by some BIOS'es and
+ boot loaders to populate a boot menu. It means that a partition is
+ bootable.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>gpt</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; Only the flag "required" is recognized. This corresponds to
+ bit 0 of the attibutes (at offset 48), meaning
+ "Required for the platform to function. The system cannot
+ function normally if this partition is removed. This
+ partition should be considered as part of the hardware of the
+ system, and if it is removed the system may not boot. It may
+ contain diagnostics, recovery tools, or other code or data that is
+ critical to the functioning of a system independent of any OS."
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+><TT
+CLASS="literal"
+>apm</TT
+> entries</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; The following flags are recognized:
+ "allocated" if the partition is already allocated; and
+ "in_use" if the partition is in use; may be cleared after a system reset; and
+ "boot" if partition contains valid boot information; and
+ "allow_read" if partition allows reading; and
+ "allow_write"; if partition allows writing; and
+ "boot_code_is_pic"; if boot code is position independent
</TD
></TR
><TR
@@ -5928,7 +6265,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1781"
+NAME="AEN1915"
></A
><TABLE
BORDER="1"
@@ -6068,7 +6405,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1824"
+NAME="AEN1958"
></A
><TABLE
BORDER="1"
@@ -6242,7 +6579,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN1882"
+NAME="AEN2016"
></A
><TABLE
BORDER="1"
@@ -6624,7 +6961,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2043"
+NAME="AEN2177"
></A
><TABLE
BORDER="1"
@@ -6874,6 +7211,64 @@ CLASS="literal"
><TD
>&#13; <TT
CLASS="literal"
+>storage.removable.media_size</TT
+> (uint64)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>Yes</TD
+><TD
+>Size of media in storage device. Available only if media have been detected in storage device.</TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>storage.partitioning_scheme</TT
+> (string)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>Only when media is inserted and is partitioned</TD
+><TD
+>The partitioning scheme of the media.</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>mbr</TD
+><TD
+>&nbsp;</TD
+><TD
+>Master Boot Record partitioning scheme used in most PC's</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>gpt</TD
+><TD
+>&nbsp;</TD
+><TD
+>GUID Partitioning Table as defined by UEFI</TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>apm</TD
+><TD
+>&nbsp;</TD
+><TD
+>Apple Partition Map, used in non-Intel Apple computers</TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
>storage.size</TT
> (uint64)
</TD
@@ -7153,7 +7548,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2249"
+NAME="AEN2410"
></A
><TABLE
BORDER="1"
@@ -7487,7 +7882,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2383"
+NAME="AEN2544"
></A
><TABLE
BORDER="1"
@@ -7647,7 +8042,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2441"
+NAME="AEN2602"
></A
><TABLE
BORDER="1"
@@ -7783,7 +8178,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2483"
+NAME="AEN2644"
></A
><TABLE
BORDER="1"
@@ -7855,7 +8250,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2505"
+NAME="AEN2666"
></A
><TABLE
BORDER="1"
@@ -7921,7 +8316,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2525"
+NAME="AEN2686"
></A
><TABLE
BORDER="1"
@@ -7985,7 +8380,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2545"
+NAME="AEN2706"
></A
><TABLE
BORDER="1"
@@ -8129,7 +8524,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2595"
+NAME="AEN2756"
></A
><TABLE
BORDER="1"
@@ -8344,7 +8739,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2667"
+NAME="AEN2828"
></A
><TABLE
BORDER="1"
@@ -8455,6 +8850,89 @@ CLASS="literal"
><TD
>&#13; <TT
CLASS="literal"
+>alsa.device_pcm_class</TT
+> (string)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>Yes</TD
+><TD
+>&#13; The PCM class of the device.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>generic</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; A standard PCM sound device (SND_PCM_CLASS_GENERIC).
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>multi</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; A multichannel device PCM sound device (SND_PCM_CLASS_MULTI) which
+ e.g. contains a generic and a modem device.
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>digitizer</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; A PCM digitizer device (SND_PCM_CLASS_DIGITIZER).
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>modem</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; A PCM modem device (SND_PCM_CLASS_MODEM).
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>unknown</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; The value is 'unknown' if the kernel provide no information about the
+ PCM device class of the device (e.g. the file pcm_class is missing).
+ </TD
+></TR
+><TR
+><TD
+>&nbsp;</TD
+><TD
+>none</TD
+><TD
+>&nbsp;</TD
+><TD
+>&#13; The value is 'none' if this there is no PCM class for this device.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
>alsa.physical_device</TT
> (string)
</TD
@@ -8608,7 +9086,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2763"
+NAME="AEN2960"
></A
><TABLE
BORDER="1"
@@ -8860,7 +9338,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2852"
+NAME="AEN3049"
></A
><TABLE
BORDER="1"
@@ -8981,7 +9459,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2894"
+NAME="AEN3091"
></A
><TABLE
BORDER="1"
@@ -9069,7 +9547,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2923"
+NAME="AEN3120"
></A
><TABLE
BORDER="1"
@@ -9166,7 +9644,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN2951"
+NAME="AEN3148"
></A
><TABLE
BORDER="1"
@@ -9316,7 +9794,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3010"
+NAME="AEN3207"
></A
><TABLE
BORDER="1"
@@ -9396,7 +9874,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3036"
+NAME="AEN3233"
></A
><TABLE
BORDER="1"
@@ -9463,7 +9941,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3056"
+NAME="AEN3253"
></A
><TABLE
BORDER="1"
@@ -10325,7 +10803,7 @@ CLASS="literal"
><TD
>&#13; <TT
CLASS="literal"
->battery.technology</TT
+>battery.reporting.technology</TT
> (string)
</TD
><TD
@@ -10333,7 +10811,30 @@ CLASS="literal"
><TD
>No</TD
><TD
->&#13; The technology of the battery.
+>&#13; The technology of the battery as reported by the hardware.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>battery.technology</TT
+> (string)
+ </TD
+><TD
+>&#13; lead-acid, lithium-ion, lithium-polymer,
+ nickel-metal-hydride, unknown
+ </TD
+><TD
+>No</TD
+><TD
+>&#13; The technology of the battery processed to a few standard types.
+ This key is needed as the hardware often does not specify the
+ description text for a battery, and so we have to calculate it
+ from the output of <TT
+CLASS="literal"
+>battery.reporting.technology</TT
+>.
</TD
></TR
><TR
@@ -10381,7 +10882,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3374"
+NAME="AEN3578"
></A
><TABLE
BORDER="1"
@@ -10496,7 +10997,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3418"
+NAME="AEN3622"
></A
><TABLE
BORDER="1"
@@ -10564,7 +11065,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3439"
+NAME="AEN3643"
></A
><TABLE
BORDER="1"
@@ -10659,7 +11160,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3471"
+NAME="AEN3675"
></A
><TABLE
BORDER="1"
@@ -10771,7 +11272,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3513"
+NAME="AEN3717"
></A
><TABLE
BORDER="1"
@@ -10910,7 +11411,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3569"
+NAME="AEN3773"
></A
><TABLE
BORDER="1"
@@ -11048,7 +11549,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3613"
+NAME="AEN3817"
></A
><TABLE
BORDER="1"
@@ -11112,6 +11613,277 @@ CLASS="literal"
><P
></P
></DIV
+><P
+>&#13; The following methods exist on the interface
+ <TT
+CLASS="literal"
+>org.freedesktop.Hal.Device.CPUFreq</TT
+>.
+ </P
+><DIV
+CLASS="informaltable"
+><P
+></P
+><A
+NAME="AEN3840"
+></A
+><TABLE
+BORDER="1"
+BGCOLOR="#E0E0E0"
+CELLSPACING="0"
+CELLPADDING="4"
+CLASS="CALSTABLE"
+><THEAD
+><TR
+><TH
+>Method (parameter types)</TH
+><TH
+>Parameters</TH
+><TH
+>Mandatory</TH
+><TH
+>Description</TH
+></TR
+></THEAD
+><TBODY
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>SetCPUFreqGovernor</TT
+> (string)
+ </TD
+><TD
+>&#13; The name of the governor to set. Get a list of available governors
+ with the GetCPUFreqAvailableGovernors method.
+ </TD
+><TD
+>No</TD
+><TD
+>&#13; Sets a CPU frequency scaling governor for all CPUFreq
+ interfaces the kernel provides. If the userspace governor
+ is set, this interface also contains a proper scaling
+ mechanism. The default performance is set to 50.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>SetCPUFreqPerformance</TT
+> (integer)
+ </TD
+><TD
+>&#13; The performance between 1 and 100 to set in dynamic scaling modes.
+ </TD
+><TD
+>No</TD
+><TD
+>&#13; Sets the performance of the dynamic scaling mechanism. This method
+ summarizes and abstracts all the different settings which can be taken
+ for dynamic frequency adjustments, like at which load to switch up
+ frequency or how many steps the mechanism should traverse until
+ reaching the maximum frequency. The higher the value, the more
+ performance you get. Respectively, the higher the value, the sooner
+ and the more often the frequency is switched up.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>SetCPUFreqConsiderNice</TT
+> (boolean)
+ </TD
+><TD
+>&#13; Whether or not niced processes should be considered on CPU
+ load calculation.
+ </TD
+><TD
+>No</TD
+><TD
+>&#13; Whether or not niced processes should be considered on CPU
+ load calculation. If niced processes are considered, they can cause a
+ frequency increment although their absolute load percentage wouldn't
+ trigger the scaling mechanism to switch up the frequency. The default
+ setting is 'false'.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GetCPUFreqGovernor</TT
+> (void)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>No</TD
+><TD
+>&#13; Get the current active governor for all CPU frequency interfaces (string).
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GetCPUFreqPerformance</TT
+> (void)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>No</TD
+><TD
+>&#13; Get the current active performance setting if a dynamic scaling
+ mechanism is in use (integer between 1 and 100).
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GetCPUFreqConsiderNice</TT
+> (void)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>No</TD
+><TD
+>&#13; Returns whether niced processed are considered during CPU load
+ calculation or not (returns boolean).
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GetCPUFreqAvailableGovernors</TT
+> (void)
+ </TD
+><TD
+>&nbsp;</TD
+><TD
+>No</TD
+><TD
+>&#13; Returns a list of strings of all available governors which
+ could be set with the SetCPUFreqGovernor method.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></DIV
+><P
+>&#13; The following errors maybe raised on the interface
+ <TT
+CLASS="literal"
+>org.freedesktop.Hal.Device.CPUFreq</TT
+>.
+ </P
+><DIV
+CLASS="informaltable"
+><P
+></P
+><A
+NAME="AEN3893"
+></A
+><TABLE
+BORDER="1"
+BGCOLOR="#E0E0E0"
+CELLSPACING="0"
+CELLPADDING="4"
+CLASS="CALSTABLE"
+><THEAD
+><TR
+><TH
+>Error</TH
+><TH
+>Description</TH
+><TH
+>Detail field</TH
+></TR
+></THEAD
+><TBODY
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GeneralError</TT
+>
+ </TD
+><TD
+>&#13; A general error occured.
+ </TD
+><TD
+>&#13; The exact error.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>UnknownGovernor</TT
+>
+ </TD
+><TD
+>&#13; The governor which was tried to be set doesn't exist.
+ </TD
+><TD
+>&#13; The governor which was tried be to set.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>PermissionDenied</TT
+>
+ </TD
+><TD
+>&#13; The caller doesn't have the privilege to execute this
+ method.
+ </TD
+><TD
+>&#13; The privilege the caller needs to execute the method.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>NoSuitableGovernor</TT
+>
+ </TD
+><TD
+>&#13; The method executed doesn't exist for the current active governor.
+ </TD
+><TD
+>&#13; The method which was tried to be executed.
+ </TD
+></TR
+><TR
+><TD
+>&#13; <TT
+CLASS="literal"
+>GovernorInitFailed</TT
+>
+ </TD
+><TD
+>&#13; The initialization of the governor failed.
+ </TD
+><TD
+>&#13; The reason for the failure.
+ </TD
+></TR
+></TBODY
+></TABLE
+><P
+></P
+></DIV
></DIV
><DIV
CLASS="sect2"
@@ -11136,7 +11908,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3639"
+NAME="AEN3931"
></A
><TABLE
BORDER="1"
@@ -11229,7 +12001,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3667"
+NAME="AEN3959"
></A
><TABLE
BORDER="1"
@@ -11397,7 +12169,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3719"
+NAME="AEN4011"
></A
><TABLE
BORDER="1"
@@ -11532,7 +12304,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3760"
+NAME="AEN4052"
></A
><TABLE
BORDER="1"
@@ -11795,7 +12567,7 @@ CLASS="literal"
>&#13; <TT
CLASS="literal"
>empty</TT
-> - can only be used on string properties
+> - can only be used on string or strlist properties
with 'true' and 'false'.
The semantics for 'true' is to match only when the string is non-empty.
</P
@@ -12014,7 +12786,7 @@ CLASS="literal"
string list. For example to remove item 'bla' from property 'foo.bar':
<TT
CLASS="literal"
->&#60;remove key="foo.bar" type="strlist"&#62;bla&#60;/merge&#62;</TT
+>&#60;remove key="foo.bar" type="strlist"&#62;bla&#60;/remove&#62;</TT
>
</P
><P
@@ -12178,7 +12950,7 @@ WIDTH="100%"
><TD
><PRE
CLASS="programlisting"
->&#13; &#60;?xml version="1.0" encoding="ISO-8859-1"?&#62; &#60;!-- -*- SGML -*- --&#62;
+>&#13; &#60;?xml version="1.0" encoding="UTF-8"?&#62;
&#60;!-- Example: This device information file matches an USB Mass Storage based MP3 player
by the matching on the USB vendor and product identifiers. --&#62;
@@ -12226,7 +12998,7 @@ WIDTH="100%"
><TD
><PRE
CLASS="programlisting"
->&#13; &#60;?xml version="1.0" encoding="ISO-8859-1"?&#62; &#60;!-- -*- SGML -*- --&#62;
+>&#13; &#60;?xml version="1.0" encoding="UTF-8"?&#62;
&#60;!-- Example: This device information file matches a Sony digital still
camera by matching on the USB vendor and product identifers. --&#62;
@@ -12272,7 +13044,7 @@ WIDTH="100%"
><TD
><PRE
CLASS="programlisting"
->&#13; &#60;?xml version="1.0" encoding="ISO-8859-1"?&#62; &#60;!-- -*- SGML -*- --&#62;
+>&#13; &#60;?xml version="1.0" encoding="UTF-8"?&#62;
&#60;!-- Example: This device information file matches a memory card reader with
multiple storage ports that can be active at the same time. --&#62;
@@ -12393,7 +13165,7 @@ WIDTH="100%"
><TD
><PRE
CLASS="programlisting"
->&#13; &#60;?xml version="1.0" encoding="ISO-8859-1"?&#62; &#60;!-- -*- SGML -*- --&#62;
+>&#13; &#60;?xml version="1.0" encoding="UTF-8"?&#62;
&#60;deviceinfo version="0.2"&#62;
@@ -12477,7 +13249,7 @@ CLASS="informaltable"
><P
></P
><A
-NAME="AEN3994"
+NAME="AEN4286"
></A
><TABLE
BORDER="1"
@@ -12640,7 +13412,7 @@ CLASS="sect2"
><HR><H3
CLASS="sect2"
><A
-NAME="AEN4036"
+NAME="AEN4328"
>Interface org.freedesktop.Hal.Manager</A
></H3
><P
@@ -12744,7 +13516,7 @@ CLASS="sect3"
><HR><H4
CLASS="sect3"
><A
-NAME="AEN4047"
+NAME="AEN4339"
>Example</A
></H4
><P
@@ -12853,7 +13625,7 @@ CLASS="sect2"
><HR><H3
CLASS="sect2"
><A
-NAME="AEN4055"
+NAME="AEN4347"
>Interface org.freedesktop.Hal.Device</A
></H3
><P
@@ -12999,6 +13771,109 @@ void Condition(string condition, ...)
signals for only a subset of the devices available.
</P
></DIV
+><DIV
+CLASS="sect2"
+><HR><H3
+CLASS="sect2"
+><A
+NAME="AEN4356"
+>Interface org.freedesktop.Hal.Device.Volume</A
+></H3
+><P
+>&#13; The org.freedesktop.Hal.Device.Volume interface is used on objects
+ with the "volume" capability. This interface has the following methods.
+ </P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="programlisting"
+>&#13;# Mount volume
+#
+# @param mountpoint Desired mount point. If NULL, will be generated based on label.
+# @param fstype Filesystem type
+# @param options Mount options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.AlreadyMounted
+# org.freedesktop.Hal.Device.Volume.InvalidMountOption
+# org.freedesktop.Hal.Device.Volume.UnknownFilesystemType
+# org.freedesktop.Hal.Device.Volume.InvalidMountpoint
+# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Mount(string mountpoint, string fstype, array{string} options)
+# Unmount volume
+#
+# @param options Unmount options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.InvalidUnmountOption
+# org.freedesktop.Hal.Device.Volume.InvalidMountpoint
+# org.freedesktop.Hal.Device.Volume.MountPointNotAvailable
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Unmount(array{string} options)
+# Eject volume
+#
+# @param ejectoptions Eject options
+# @raises org.freedesktop.Hal.Device.Volume.NoSuchDevice
+# org.freedesktop.Hal.Device.Volume.PermissionDenied
+# org.freedesktop.Hal.Device.Volume.InvalidEjectOption
+# org.freedesktop.Hal.Device.Volume.PermissionDeniedByPolicy
+#
+void Eject(array{string} options)
+ </PRE
+></TD
+></TR
+></TABLE
+></DIV
+><DIV
+CLASS="sect2"
+><HR><H3
+CLASS="sect2"
+><A
+NAME="AEN4360"
+>Interface org.freedesktop.Hal.Device.Storage</A
+></H3
+><P
+>&#13; The org.freedesktop.Hal.Device.Storage interface is used on objects
+ with the "storage" capability. This interface has the following methods.
+ </P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="programlisting"
+>&#13;# Eject media
+#
+# @param ejectoptions Eject options
+# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice
+# org.freedesktop.Hal.Device.Storage.PermissionDenied
+# org.freedesktop.Hal.Device.Storage.InvalidEjectOption
+# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy
+#
+void Eject(array{string} options)
+# Close media tray
+#
+# @param closetrayoptions Close tray options
+# @raises org.freedesktop.Hal.Device.Storage.NoSuchDevice
+# org.freedesktop.Hal.Device.Storage.PermissionDenied
+# org.freedesktop.Hal.Device.Storage.InvalidCloseTrayOption
+# org.freedesktop.Hal.Device.Storage.PermissionDeniedByPolicy
+#
+void CloseTray(array{string} options)
+ </PRE
+></TD
+></TR
+></TABLE
+></DIV
></DIV
><DIV
CLASS="sect1"
diff --git a/hald/linux/addons/addon-storage.c b/hald/linux/addons/addon-storage.c
index 1660abcd..5d848c54 100644
--- a/hald/linux/addons/addon-storage.c
+++ b/hald/linux/addons/addon-storage.c
@@ -427,7 +427,9 @@ main (int argc, char *argv[])
DBusError error;
HAL_DEBUG (("Media removal detected on %s", device_file));
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
+ libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, NULL);
+ libhal_device_set_property_string (ctx, udi, "storage.partitioning_scheme", "", NULL);
+
/* attempt to unmount all childs */
unmount_childs (ctx, udi);
@@ -449,7 +451,10 @@ main (int argc, char *argv[])
DBusError error;
HAL_DEBUG (("Media insertion detected on %s", device_file));
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error); /* our probe will trigger the appropriate hotplug events */
+
+ /* our probe will trigger the appropriate hotplug events */
+ libhal_device_set_property_bool (
+ ctx, udi, "storage.removable.media_available", TRUE, NULL);
/* could have a fs on the main block device; do a rescan to add it */
dbus_error_init (&error);
diff --git a/hald/linux/blockdev.c b/hald/linux/blockdev.c
index 8fbe0845..3061424b 100644
--- a/hald/linux/blockdev.c
+++ b/hald/linux/blockdev.c
@@ -780,7 +780,6 @@ hotplug_event_begin_add_blockdev (const gchar *sysfs_path, const gchar *device_f
hal_device_property_set_string (d, "storage.physical_device", parent->udi);
hal_device_property_set_bool (d, "storage.removable", TRUE);
hal_device_property_set_bool (d, "storage.removable.media_available", FALSE);
- hal_device_property_set_uint64 (d, "storage.removable.media_size", 0);
hal_device_property_set_bool (d, "storage.hotpluggable", FALSE);
hal_device_property_set_bool (d, "storage.requires_eject", FALSE);
hal_device_property_set_uint64 (d, "storage.size", 0);
@@ -924,7 +923,6 @@ hotplug_event_begin_add_blockdev (const gchar *sysfs_path, const gchar *device_f
}
hal_device_property_set_bool (d, "storage.removable.media_available", FALSE);
- hal_device_property_set_uint64 (d, "storage.removable.media_size", 0);
hal_device_property_set_bool (d, "storage.removable", is_removable);
/* set storage.size only if we have fixed media */
if (!is_removable) {
diff --git a/hald/linux/probing/Makefile.am b/hald/linux/probing/Makefile.am
index a66d858b..5b2d3c23 100644
--- a/hald/linux/probing/Makefile.am
+++ b/hald/linux/probing/Makefile.am
@@ -30,10 +30,10 @@ hald_probe_serial_SOURCES = probe-serial.c ../../logger.c
hald_probe_serial_LDADD = $(top_builddir)/libhal/libhal.la
hald_probe_storage_SOURCES = probe-storage.c linux_dvd_rw_utils.c linux_dvd_rw_utils.h ../../logger.c
-hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ @VOLUME_ID_LIBS@
+hald_probe_storage_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/partutil/libpartutil.la @GLIB_LIBS@ @VOLUME_ID_LIBS@
hald_probe_pc_floppy_SOURCES = probe-pc-floppy.c ../../logger.c
hald_probe_volume_SOURCES = probe-volume.c linux_dvd_rw_utils.c ../../logger.c
-hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la @GLIB_LIBS@ @VOLUME_ID_LIBS@
+hald_probe_volume_LDADD = $(top_builddir)/libhal/libhal.la $(top_builddir)/partutil/libpartutil.la @GLIB_LIBS@ @VOLUME_ID_LIBS@
diff --git a/hald/linux/probing/probe-storage.c b/hald/linux/probing/probe-storage.c
index 7b84a642..9a6b860a 100644
--- a/hald/linux/probing/probe-storage.c
+++ b/hald/linux/probing/probe-storage.c
@@ -46,6 +46,7 @@
#include <libvolume_id.h>
#include "libhal/libhal.h"
+#include "partutil/partutil.h"
#include "linux_dvd_rw_utils.h"
#include "../../logger.h"
@@ -57,7 +58,7 @@ static void vid_log(int priority, const char *file, int line, const char *format
va_start(args, format);
vsnprintf(log_str, sizeof(log_str), format, args);
- logger_forward_debug("%s:%i %s", file, line, log_str);
+ logger_forward_debug("%s:%i %s\n", file, line, log_str);
va_end(args);
}
@@ -95,6 +96,62 @@ out:
return rc;
}
+#define BSIZE 0x200
+#define MSDOS_MAGIC "\x55\xaa"
+#define MSDOS_SIG_OFF 0x01fe
+#define MSDOS_PARTTABLE_OFFSET 0x01be
+
+#define MAC_MAGIC "\x45\x52"
+#define MAC_SIG_OFF 0x0000
+
+enum {
+ PART_TABLE_UNKNOWN,
+ PART_TABLE_MBR,
+ PART_TABLE_APM,
+ PART_TABLE_GPT
+};
+
+/* Detect partition table scheme */
+static int
+probe_for_part_scheme (LibHalChangeSet *changeset, int fd)
+{
+ int res;
+ const uint8_t buf[BSIZE];
+
+ res = PART_TABLE_UNKNOWN;
+
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ dbg("lseek failed (%s)", strerror(errno));
+ goto out;
+ }
+ if (read(fd, &buf, BSIZE) < BSIZE) {
+ dbg("read failed (%s)", strerror(errno));
+ goto out;
+ }
+
+ if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) == 0) {
+ /* if the first partition have type 0xee, it's a GUID Partitioning Table */
+ if (buf[MSDOS_PARTTABLE_OFFSET + 4] == 0xee) {
+ dbg("foo1");
+ res = PART_TABLE_GPT;
+ } else {
+ dbg("foo2");
+ res = PART_TABLE_MBR;
+ }
+ goto out;
+ }
+
+ if (memcmp(&buf[MAC_SIG_OFF], MAC_MAGIC, 2) == 0) {
+ dbg("foo3");
+ res = PART_TABLE_APM;
+ goto out;
+ }
+
+
+out:
+ return res;
+}
+
int
main (int argc, char *argv[])
{
@@ -108,6 +165,8 @@ main (int argc, char *argv[])
char *drive_type;
char *sysfs_path;
dbus_bool_t only_check_for_fs;
+ LibHalChangeSet *cs;
+
fd = -1;
@@ -139,6 +198,12 @@ main (int argc, char *argv[])
if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
goto out;
+ cs = libhal_device_new_changeset (udi);
+ if (cs == NULL) {
+ HAL_DEBUG(("Cannot initialize changeset"));
+ goto out;
+ }
+
HAL_DEBUG (("Doing probe-storage for %s (bus %s) (drive_type %s) (udi=%s) (--only-check-for-fs==%d)",
device_file, bus, drive_type, udi, only_check_for_fs));
@@ -169,83 +234,85 @@ main (int argc, char *argv[])
goto out;
}
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdr", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdrw", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvd", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdr", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdrw", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdram", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusr", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrw", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrwdl", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrdl", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bd", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bdr", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.bdre", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvd", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvdr", FALSE, &error);
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.hddvdrw", FALSE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrwdl", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.bdre", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdr", FALSE);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.hddvdrw", FALSE);
if (capabilities & CDC_CD_R) {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdr", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdr", TRUE);
}
if (capabilities & CDC_CD_RW) {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.cdrw", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.cdrw", TRUE);
}
if (capabilities & CDC_DVD) {
int profile;
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvd", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvd", TRUE);
profile = get_dvd_r_rw_profile (fd);
HAL_DEBUG (("get_dvd_r_rw_profile returned: %d", profile));
if (profile & DRIVE_CDROM_CAPS_DVDRW)
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdrw", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdrw", TRUE);
if (profile & DRIVE_CDROM_CAPS_DVDPLUSR)
- libhal_device_set_property_bool(ctx, udi, "storage.cdrom.dvdplusr", TRUE, &error);
+ libhal_changeset_set_property_bool(cs, "storage.cdrom.dvdplusr", TRUE);
if (profile & DRIVE_CDROM_CAPS_DVDPLUSRW)
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrw", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrw", TRUE);
if (profile & DRIVE_CDROM_CAPS_DVDPLUSRWDL)
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrwdl", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrwdl", TRUE);
if (profile & DRIVE_CDROM_CAPS_DVDPLUSRDL)
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdplusrdl", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdplusrdl", TRUE);
}
if (capabilities & CDC_DVD_R) {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdr", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdr", TRUE);
}
if (capabilities & CDC_DVD_RAM) {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.dvdram", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.dvdram", TRUE);
}
/* while we're at it, check if we support media changed */
if (capabilities & CDC_MEDIA_CHANGED) {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.support_media_changed", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", TRUE);
} else {
- libhal_device_set_property_bool (ctx, udi, "storage.cdrom.support_media_changed", FALSE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.cdrom.support_media_changed", FALSE);
}
if (get_read_write_speed(fd, &read_speed, &write_speed, &write_speeds) >= 0) {
- libhal_device_set_property_int (ctx, udi, "storage.cdrom.read_speed", read_speed, &error);
+ libhal_changeset_set_property_int (cs, "storage.cdrom.read_speed", read_speed);
if (write_speed > 0) {
- libhal_device_set_property_int (ctx, udi, "storage.cdrom.write_speed", write_speed, &error);
+ libhal_changeset_set_property_int (
+ cs, "storage.cdrom.write_speed", write_speed);
+
if (write_speeds != NULL)
{
gchar **wspeeds;
- int i;
- wspeeds = g_strsplit_set (write_speeds, ",", -1);
- for (i = 0 ; wspeeds[i] != NULL; i++) {
- if (strlen (wspeeds[i]) > 0)
- libhal_device_property_strlist_append (ctx, udi, "storage.cdrom.write_speeds", wspeeds[i], &error);
- }
+ wspeeds = g_strsplit_set (write_speeds, ",", -1);
+ libhal_changeset_set_property_strlist (cs,
+ "storage.cdrom.write_speeds",
+ (const char **) wspeeds);
+ g_strfreev (wspeeds);
free (write_speeds);
}
- }
- else
- libhal_device_set_property_int (ctx, udi, "storage.cdrom.write_speed", 0, &error);
+ } else {
+ libhal_changeset_set_property_int (cs, "storage.cdrom.write_speed", 0);
+ libhal_changeset_set_property_strlist (cs, "storage.cdrom.write_speeds", NULL);
+ }
}
-
+
close (fd);
}
@@ -331,13 +398,13 @@ main (int argc, char *argv[])
if (got_media) {
uint64_t size;
ret = 2;
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", TRUE);
if (ioctl (fd, BLKGETSIZE64, &size) == 0) {
HAL_DEBUG (("media size = %llu", size));
- libhal_device_set_property_uint64 (ctx, udi, "storage.removable.media_size", size, &error);
+ libhal_changeset_set_property_uint64 (cs, "storage.removable.media_size", size);
}
} else {
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", FALSE);
}
close (fd);
@@ -360,18 +427,18 @@ main (int argc, char *argv[])
if (fd < 0) {
HAL_DEBUG (("Cannot open %s: %s", device_file, strerror (errno)));
/* no media */
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", FALSE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", FALSE);
goto out;
}
HAL_DEBUG (("Returned from open(2)"));
/* if we get to here, we have media */
- libhal_device_set_property_bool (ctx, udi, "storage.removable.media_available", TRUE, &error);
+ libhal_changeset_set_property_bool (cs, "storage.removable.media_available", TRUE);
if (ioctl (fd, BLKGETSIZE64, &size) != 0)
size = 0;
- libhal_device_set_property_uint64 (ctx, udi, "storage.removable.media_size", size, &error);
+ libhal_changeset_set_property_uint64 (cs, "storage.removable.media_size", size);
/* if the kernel has created partitions, we don't look for a filesystem */
main_device = strrchr (sysfs_path, '/');
@@ -387,13 +454,30 @@ main (int argc, char *argv[])
while ((partition = g_dir_read_name (dir)) != NULL) {
if (strncmp (main_device, partition, main_device_len) == 0 &&
isdigit (partition[main_device_len])) {
+ PartitionTable *p;
+
HAL_DEBUG (("partition %s found, skip probing for filesystem", partition));
g_dir_close (dir);
+
+ /* probe for partition table type */
+ p = part_table_load_from_disk (device_file);
+ if (p != NULL) {
+
+ libhal_changeset_set_property_string (
+ cs,
+ "storage.partitioning_scheme",
+ part_get_scheme_name (part_table_get_scheme (p)));
+
+ part_table_free (p);
+ }
+
goto out;
}
}
g_dir_close (dir);
+ libhal_changeset_set_property_string (cs, "storage.partitioning_scheme", "none");
+
/* probe for file system */
vid = volume_id_open_fd (fd);
if (vid != NULL) {
@@ -416,6 +500,10 @@ main (int argc, char *argv[])
}
out:
+ if (cs != NULL) {
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+ }
if (ctx != NULL) {
dbus_error_init (&error);
diff --git a/hald/linux/probing/probe-volume.c b/hald/linux/probing/probe-volume.c
index 8a57e525..3b6b00b1 100644
--- a/hald/linux/probing/probe-volume.c
+++ b/hald/linux/probing/probe-volume.c
@@ -44,6 +44,7 @@
#include <libvolume_id.h>
#include "libhal/libhal.h"
+#include "partutil/partutil.h"
#include "linux_dvd_rw_utils.h"
#include "../../logger.h"
@@ -54,7 +55,7 @@ static void vid_log(int priority, const char *file, int line, const char *format
va_start(args, format);
vsnprintf(log_str, sizeof(log_str), format, args);
- logger_forward_debug("%s:%i %s", file, line, log_str);
+ logger_forward_debug("%s:%i %s\n", file, line, log_str);
va_end(args);
}
@@ -85,156 +86,9 @@ strdup_valid_utf8 (const char *str)
return newstr;
}
-/* probe_msdos_part_table: return array of partiton type numbers */
-#define BSIZE 0x200
-#define MSDOS_MAGIC "\x55\xaa"
-#define MSDOS_PARTTABLE_OFFSET 0x1be
-#define MSDOS_SIG_OFF 0x1fe
-#define DOS_EXTENDED_PARTITION 0x05
-#define LINUX_EXTENDED_PARTITION 0x85
-#define WIN98_EXTENDED_PARTITION 0x0f
-#define is_extended(type) \
- (type == DOS_EXTENDED_PARTITION || \
- type == WIN98_EXTENDED_PARTITION || \
- type == LINUX_EXTENDED_PARTITION)
-
-struct msdos_part_entry {
- uint8_t part_type;
- uint64_t start;
- uint64_t size;
-};
-
-static struct msdos_part_entry *
-probe_msdos_part_table(int fd)
-{
- static struct msdos_part_entry partition_id_index[256];
- unsigned int partition_count;
- const uint8_t buf[BSIZE];
- int i;
- uint64_t poff;
- uint64_t plen;
- uint64_t extended = 0;
- uint64_t next;
- int limit;
- int empty = 1;
- struct msdos_partition_entry {
- uint8_t boot_ind;
- uint8_t head;
- uint8_t sector;
- uint8_t cyl;
- uint8_t sys_ind;
- uint8_t end_head;
- uint8_t end_sector;
- uint8_t end_cyl;
- uint32_t start_sect;
- uint32_t nr_sects;
- } __attribute__((packed)) *part;
-
- if (lseek(fd, 0, SEEK_SET) < 0) {
- HAL_DEBUG (("lseek failed (%s)", strerror(errno)));
- return NULL;
- }
- if (read(fd, &buf, BSIZE) < BSIZE) {
- HAL_DEBUG (("read failed (%s)", strerror(errno)));
- return NULL;
- }
- if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
- return NULL;
-
- part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
- /* check flags on all entries for a valid partition table */
- for (i = 0; i < 4; i++) {
- if (part[i].boot_ind != 0 &&
- part[i].boot_ind != 0x80)
- return NULL;
-
- if (GINT32_FROM_LE(part[i].nr_sects) != 0)
- empty = 0;
- }
- if (empty == 1)
- return NULL;
-
- memset(partition_id_index, 0x00, sizeof(partition_id_index));
-
- for (i = 0; i < 4; i++) {
- poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE;
- plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE;
-
- if (plen == 0)
- continue;
-
- partition_id_index[i].part_type = part[i].sys_ind;
- partition_id_index[i].start = poff;
- partition_id_index[i].size = plen;
- HAL_DEBUG (("part %d -> type=%d off=%lld size=%lld", i, part[i].sys_ind, poff, plen));
-
- if (is_extended(part[i].sys_ind)) {
- HAL_DEBUG (("found extended partition at 0x%llx", (unsigned long long) poff));
- if (extended == 0)
- extended = poff;
- } else {
- HAL_DEBUG (("found 0x%x primary data partition at 0x%llx, len 0x%llx",
- part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen));
- }
- }
-
- /* follow extended partition chain and add data partitions */
- partition_count = 4;
- limit = 255;
- next = extended;
- while (next != 0) {
- uint64_t oldnext;
-
- if (limit-- == 0) {
- HAL_DEBUG(("extended chain limit reached"));
- break;
- }
-
- HAL_DEBUG (("read 0x%llx (%llu)", next, next));
- if (lseek(fd, next, SEEK_SET) < 0) {
- HAL_DEBUG(("lseek failed (%s)", strerror(errno)));
- return NULL;
- }
- if (read(fd, &buf, BSIZE) < BSIZE) {
- HAL_DEBUG(("read failed (%s)", strerror(errno)));
- return NULL;
- }
- if (memcmp(&buf[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0)
- break;
-
- oldnext = next;
- next = 0;
-
- part = (struct msdos_partition_entry*) &buf[MSDOS_PARTTABLE_OFFSET];
- for (i = 0; i < 4; i++) {
- poff = (uint64_t) GINT32_FROM_LE(part[i].start_sect) * BSIZE;
- plen = (uint64_t) GINT32_FROM_LE(part[i].nr_sects) * BSIZE;
-
- if (plen == 0)
- continue;
-
- if (is_extended(part[i].sys_ind)) {
- HAL_DEBUG(("found extended partition (chain) at 0x%llx", (unsigned long long) poff));
- if (next == 0)
- next = extended + poff;
- } else {
- HAL_DEBUG(("found 0x%x logical data partition at 0x%llx, len 0x%llx",
- part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen));
-
- partition_id_index[partition_count].part_type = part[i].sys_ind;
- partition_id_index[partition_count].start = oldnext + poff;
- partition_id_index[partition_count].size = plen;
-
- partition_count++;
- }
- }
- }
-
- return partition_id_index;
-}
static void
-set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *changes, struct volume_id *vid)
+set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *cs, struct volume_id *vid)
{
char buf[256];
const char *usage;
@@ -257,47 +111,47 @@ set_volume_id_values (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan
usage = "crypto";
break;
case VOLUME_ID_UNUSED:
- libhal_changeset_set_property_string (changes, "info.product", "Volume (unused)");
+ libhal_changeset_set_property_string (cs, "info.product", "Volume (unused)");
usage = "unused";
return;
default:
usage = "";
}
- libhal_changeset_set_property_string (changes, "volume.fsusage", usage);
+ libhal_changeset_set_property_string (cs, "volume.fsusage", usage);
HAL_DEBUG (("volume.fsusage = '%s'", usage));
- libhal_changeset_set_property_string (changes, "volume.fstype", vid->type);
+ libhal_changeset_set_property_string (cs, "volume.fstype", vid->type);
HAL_DEBUG(("volume.fstype = '%s'", vid->type));
if (vid->type_version[0] != '\0') {
- libhal_changeset_set_property_string (changes, "volume.fsversion", vid->type_version);
+ libhal_changeset_set_property_string (cs, "volume.fsversion", vid->type_version);
HAL_DEBUG(("volume.fsversion = '%s'", vid->type_version));
}
- libhal_changeset_set_property_string (changes, "volume.uuid", vid->uuid);
+ libhal_changeset_set_property_string (cs, "volume.uuid", vid->uuid);
HAL_DEBUG(("volume.uuid = '%s'", vid->uuid));
/* we need to be sure for a utf8 valid label, because dbus accept only utf8 valid strings */
volume_label = strdup_valid_utf8 (vid->label);
if( volume_label != NULL ) {
- libhal_changeset_set_property_string (changes, "volume.label", volume_label);
+ libhal_changeset_set_property_string (cs, "volume.label", volume_label);
HAL_DEBUG(("volume.label = '%s'", volume_label));
if (strlen(volume_label) > 0) {
- libhal_changeset_set_property_string (changes, "info.product", volume_label);
+ libhal_changeset_set_property_string (cs, "info.product", volume_label);
}
else {
snprintf (buf, sizeof (buf), "Volume (%s)", vid->type);
- libhal_changeset_set_property_string (changes, "info.product", buf);
+ libhal_changeset_set_property_string (cs, "info.product", buf);
}
g_free(volume_label);
} else {
snprintf (buf, sizeof (buf), "Volume (%s)", vid->type);
- libhal_changeset_set_property_string (changes, "info.product", buf);
+ libhal_changeset_set_property_string (cs, "info.product", buf);
}
}
static void
-advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *changes,
+advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *cs,
int fd, const char *device_file)
{
/* the discs block size */
@@ -323,9 +177,9 @@ advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan
dbus_error_init (&error);
/* set defaults */
- libhal_changeset_set_property_bool (changes, "volume.disc.is_videodvd", FALSE);
- libhal_changeset_set_property_bool (changes, "volume.disc.is_vcd", FALSE);
- libhal_changeset_set_property_bool (changes, "volume.disc.is_svcd", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", FALSE);
/* read the block size */
lseek (fd, 0x8080, SEEK_CUR);
@@ -395,19 +249,19 @@ advanced_disc_detect (LibHalContext *ctx, const char *udi, LibHalChangeSet *chan
{
if (!strcmp (dirname, "VIDEO_TS"))
{
- libhal_changeset_set_property_bool (changes, "volume.disc.is_videodvd", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", TRUE);
HAL_DEBUG(("Disc in %s is a Video DVD", device_file));
break;
}
else if (!strcmp (dirname, "VCD"))
{
- libhal_changeset_set_property_bool (changes, "volume.disc.is_vcd", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", TRUE);
HAL_DEBUG(("Disc in %s is a Video CD", device_file));
break;
}
else if (!strcmp (dirname, "SVCD"))
{
- libhal_changeset_set_property_bool (changes, "volume.disc.is_svcd", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", TRUE);
HAL_DEBUG(("Disc in %s is a Super Video CD", device_file));
break;
}
@@ -445,19 +299,26 @@ main (int argc, char *argv[])
struct volume_id *vid;
char *stordev_dev_file;
char *partition_number_str;
+ char *partition_start_str;
char *is_disc_str;
dbus_bool_t is_disc;
unsigned int partition_number;
+ guint64 partition_start;
unsigned int block_size;
dbus_uint64_t vol_size;
dbus_bool_t should_probe_for_fs;
dbus_uint64_t vol_probe_offset = 0;
- LibHalChangeSet *changeset;
+ LibHalChangeSet *cs;
fd = -1;
+
+ cs = NULL;
+
/* hook in our debug into libvolume_id */
volume_id_log_fn = vid_log;
+ setup_logger ();
+
/* assume failure */
ret = 1;
@@ -475,20 +336,24 @@ main (int argc, char *argv[])
else
partition_number = (unsigned int) -1;
+ partition_start_str = getenv ("HAL_PROP_VOLUME_PARTITION_START");
+ if (partition_start_str != NULL)
+ partition_start = (guint64) strtoll (partition_start_str, NULL, 0);
+ else
+ partition_start = (guint64) 0;
+
is_disc_str = getenv ("HAL_PROP_VOLUME_IS_DISC");
if (is_disc_str != NULL && strcmp (is_disc_str, "true") == 0)
is_disc = TRUE;
else
is_disc = FALSE;
- setup_logger ();
-
dbus_error_init (&error);
if ((ctx = libhal_ctx_init_direct (&error)) == NULL)
goto out;
- changeset = libhal_device_new_changeset (udi);
- if (changeset == NULL) {
+ cs = libhal_device_new_changeset (udi);
+ if (cs == NULL) {
HAL_DEBUG(("Cannot initialize changeset"));
goto out;
}
@@ -502,11 +367,11 @@ main (int argc, char *argv[])
/* block size and total size */
if (ioctl (fd, BLKSSZGET, &block_size) == 0) {
HAL_DEBUG(("volume.block_size = %d", block_size));
- libhal_changeset_set_property_int (changeset, "volume.block_size", block_size);
+ libhal_changeset_set_property_int (cs, "volume.block_size", block_size);
}
if (ioctl (fd, BLKGETSIZE64, &vol_size) == 0) {
HAL_DEBUG(("volume.size = %llu", vol_size));
- libhal_changeset_set_property_uint64 (changeset, "volume.size", vol_size);
+ libhal_changeset_set_property_uint64 (cs, "volume.size", vol_size);
} else
vol_size = 0;
@@ -518,12 +383,12 @@ main (int argc, char *argv[])
struct cdrom_tochdr; /* toc_hdr; */
/* defaults */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "unknown");
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", FALSE);
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", FALSE);
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_blank", FALSE);
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_appendable", FALSE);
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", FALSE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "unknown");
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_data", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", FALSE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", FALSE);
/* Suggested by Alex Larsson to get rid of log spewage
* on Alan's cd changer (RH bug 130649) */
@@ -535,33 +400,33 @@ main (int argc, char *argv[])
type = ioctl (fd, CDROM_DISC_STATUS, CDSL_CURRENT);
switch (type) {
case CDS_AUDIO: /* audio CD */
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", TRUE);
HAL_DEBUG(("Disc in %s has audio", device_file));
should_probe_for_fs = FALSE;
break;
case CDS_MIXED: /* mixed mode CD */
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_audio", TRUE);
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_data", TRUE);
HAL_DEBUG(("Disc in %s has audio+data", device_file));
break;
case CDS_DATA_1: /* data CD */
case CDS_DATA_2:
case CDS_XA_2_1:
case CDS_XA_2_2:
- libhal_changeset_set_property_bool (changeset, "volume.disc.has_data", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.has_data", TRUE);
HAL_DEBUG(("Disc in %s has data", device_file));
- advanced_disc_detect (ctx, udi, changeset, fd, device_file);
+ advanced_disc_detect (ctx, udi, cs, fd, device_file);
break;
case CDS_NO_INFO: /* blank or invalid CD */
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_blank", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", TRUE);
/* set the volume size to 0 if disc is blank and not as 4 from BLKGETSIZE64 */
- libhal_changeset_set_property_int (changeset, "volume.block_size", 0);
+ libhal_changeset_set_property_int (cs, "volume.block_size", 0);
HAL_DEBUG(("Disc in %s is blank", device_file));
should_probe_for_fs = FALSE;
break;
default: /* should never see this */
- libhal_changeset_set_property_string (changeset, "volume.disc_type", "unknown");
+ libhal_changeset_set_property_string (cs, "volume.disc_type", "unknown");
HAL_DEBUG(("Disc in %s returned unknown CDROM_DISC_STATUS", device_file));
should_probe_for_fs = FALSE;
break;
@@ -575,65 +440,65 @@ main (int argc, char *argv[])
if (type != -1) {
switch (type) {
case 0x08: /* CD-ROM */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_rom");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_rom");
break;
case 0x09: /* CD-R */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_r");
break;
case 0x0a: /* CD-RW */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "cd_rw");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "cd_rw");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x10: /* DVD-ROM */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rom");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rom");
break;
case 0x11: /* DVD-R Sequential */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_r");
break;
case 0x12: /* DVD-RAM */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_ram");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_ram");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x13: /* DVD-RW Restricted Overwrite */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rw");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rw");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x14: /* DVD-RW Sequential */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_rw");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_rw");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x1A: /* DVD+RW */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_rw");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_rw");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x1B: /* DVD+R */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_r");
break;
case 0x2B: /* DVD+R Double Layer */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "dvd_plus_r_dl");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "dvd_plus_r_dl");
break;
case 0x40: /* BD-ROM */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_rom");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_rom");
break;
case 0x41: /* BD-R Sequential */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_r");
break;
case 0x42: /* BD-R Random */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_r");
break;
case 0x43: /* BD-RE */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "bd_re");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "bd_re");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
case 0x50: /* HD DVD-ROM */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_rom");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_rom");
break;
case 0x51: /* HD DVD-R */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_r");
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_r");
break;
case 0x52: /* HD DVD-Rewritable */
- libhal_changeset_set_property_string (changeset, "volume.disc.type", "hddvd_rw");
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_string (cs, "volume.disc.type", "hddvd_rw");
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
break;
default:
break;
@@ -642,16 +507,16 @@ main (int argc, char *argv[])
if (get_disc_capacity_for_type (fd, type, &capacity) == 0) {
HAL_DEBUG(("volume.disc.capacity = %llu", capacity));
- libhal_changeset_set_property_uint64 (changeset, "volume.disc.capacity", capacity);
+ libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity);
}
/* On some hardware the get_disc_type call fails, so we use this as a backup */
if (disc_is_rewritable (fd)) {
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_rewritable", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", TRUE);
}
if (disc_is_appendable (fd)) {
- libhal_changeset_set_property_bool (changeset, "volume.disc.is_appendable", TRUE);
+ libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", TRUE);
}
#if 0
@@ -703,14 +568,15 @@ main (int argc, char *argv[])
vid = volume_id_open_fd (fd);
if (vid != NULL) {
if (volume_id_probe_all (vid, vol_probe_offset , vol_size) == 0) {
- set_volume_id_values(ctx, udi, changeset, vid);
+ set_volume_id_values(ctx, udi, cs, vid);
} else {
- libhal_changeset_set_property_string (changeset, "info.product", "Volume");
+ libhal_changeset_set_property_string (cs, "info.product", "Volume");
}
/* VOLUME_ID_UNUSED means vol_id didn't detect anything that it knows about - look if
* it's an extended msdos partition table
*/
+#if 0
if (vid->usage_id == VOLUME_ID_UNUSED) {
unsigned char buf[2];
@@ -724,64 +590,113 @@ main (int argc, char *argv[])
if (memcmp (buf, MSDOS_MAGIC, 2) == 0) {
HAL_DEBUG (("partition is an extended msdos partition table"));
- libhal_changeset_set_property_string (changeset, "volume.fsusage", "partitiontable");
- libhal_changeset_set_property_string (changeset, "volume.fstype", "msdos_extended_partitiontable");
- libhal_changeset_set_property_string (changeset, "volume.fsversion", "");
+ libhal_changeset_set_property_string (cs, "volume.fsusage", "partitiontable");
+ libhal_changeset_set_property_string (cs, "volume.fstype", "msdos_extended_partitiontable");
+ libhal_changeset_set_property_string (cs, "volume.fsversion", "");
}
}
}
+#endif
volume_id_close(vid);
}
/* get partition type number, if we find a msdos partition table */
- if (partition_number_str != NULL && partition_number <= 256 && partition_number > 0) {
+ if (partition_number_str != NULL &&
+ partition_number <= 256 && partition_number > 0 &&
+ partition_start > 0) {
struct msdos_part_entry *idx;
int fd;
+ PartitionTable *p;
if ((stordev_dev_file = libhal_device_get_property_string (
ctx, parent_udi, "block.device", &error)) == NULL) {
goto out;
}
- fd = open(stordev_dev_file, O_RDONLY);
- if (fd >= 0) {
- idx = probe_msdos_part_table(fd);
- if (idx != NULL) {
- uint64_t start;
- uint64_t size;
- unsigned char type;
-
- type = idx[partition_number - 1].part_type;
- start = idx[partition_number - 1].start;
- size = idx[partition_number - 1].size;
- if (type > 0) {
- libhal_changeset_set_property_int (
- changeset, "volume.partition.msdos_part_table_type", type);
- libhal_changeset_set_property_uint64 (
- changeset, "volume.partition.msdos_part_table_start", start);
- libhal_changeset_set_property_uint64 (
- changeset, "volume.partition.msdos_part_table_size", size);
-
- /* NOTE: We trust the type from the partition table
- * if it explicitly got correct entries for RAID and
- * LVM partitions.
- *
- * But in general it's not a good idea to trust the
- * partition table type as many geek^Wexpert users use
- * FAT filesystems on type 0x83 which is Linux.
- *
- * Linux RAID autodetect is 0xfd and Linux LVM is 0x8e
- */
- if (type == 0xfd || type == 0x8e ) {
- libhal_changeset_set_property_string (
- changeset, "volume.fsusage", "raid");
- }
+
+ HAL_INFO (("Loading part table"));
+ p = part_table_load_from_disk (stordev_dev_file);
+ if (p != NULL) {
+ PartitionTable *p2;
+ int entry;
+
+ HAL_INFO (("Looking at part table"));
+ part_table_find (p, partition_start, &p2, &entry);
+ if (entry >= 0) {
+ const char *scheme;
+ char *type;
+ char *label;
+ char *uuid;
+ char **flags;
+
+ scheme = part_get_scheme_name (part_table_get_scheme (p2));
+ type = part_table_entry_get_type (p2, entry);
+ label = part_table_entry_get_label (p2, entry);
+ uuid = part_table_entry_get_uuid (p2, entry);
+ flags = part_table_entry_get_flags (p2, entry);
+
+ if (type == NULL)
+ type = g_strdup ("");
+ if (label == NULL)
+ label = g_strdup ("");
+ if (uuid == NULL)
+ uuid = g_strdup ("");
+ if (flags == NULL) {
+ flags = g_new0 (char *, 2);
+ flags[0] = NULL;
+ }
+
+ libhal_changeset_set_property_string (cs, "volume.partition.scheme", scheme);
+ libhal_changeset_set_property_string (cs, "volume.partition.type", type);
+ libhal_changeset_set_property_string (cs, "volume.partition.label", label);
+ libhal_changeset_set_property_string (cs, "volume.partition.uuid", uuid);
+ libhal_changeset_set_property_strlist (cs, "volume.partition.flags", flags);
+
+ /* NOTE: We trust the type from the partition table
+ * if it explicitly got correct entries for RAID and
+ * LVM partitions.
+ *
+ * But in general it's not a good idea to trust the
+ * partition table type as many geek^Wexpert users use
+ * FAT filesystems on type 0x83 which is Linux.
+ *
+ * For MBR, Linux RAID autodetect is 0xfd and Linux LVM is 0x8e
+ *
+ * For GPT, RAID is A19D880F-05FC-4D3B-A006-743F0F84911E and
+ * LVM is E6D6D379-F507-44C2-A23C-238F2A3DF928.
+ */
+ if (
+ ((strcmp (scheme, "mbr") == 0 || strcmp (scheme, "embr") == 0) &&
+ (0xfd == atoi (type) || 0x8e == atoi (type)))
+ ||
+ ((strcmp (scheme, "gpt") == 0) &&
+ ((strcmp (type, "A19D880F-05FC-4D3B-A006-743F0F84911E") == 0) ||
+ (strcmp (type, "E6D6D379-F507-44C2-A23C-238F2A3DF928")) == 0)) ) {
+
+ libhal_changeset_set_property_string (cs, "volume.fsusage", "raid");
+
}
+
+ /* see if this partition is an embedded partition table */
+ if (part_table_entry_get_nested (p2, entry) != NULL) {
+
+ libhal_changeset_set_property_string (cs, "volume.fsusage", "partitiontable");
+ libhal_changeset_set_property_string (cs, "volume.fstype", "");
+ libhal_changeset_set_property_string (cs, "volume.fsversion", "");
+ }
+
+ g_free (type);
+ g_free (label);
+ g_free (uuid);
+ g_strfreev (flags);
}
- close (fd);
+
+ part_table_free (p);
}
+ HAL_INFO (("Done looking at part table"));
+
libhal_free_string (stordev_dev_file);
}
}
@@ -789,15 +704,17 @@ main (int argc, char *argv[])
/* good so far */
ret = 0;
- /* for testing...
- char *values[4] = {"foo", "bar", "baz", NULL};
- libhal_changeset_set_property_strlist (changeset, "foo.bar", values);
- */
+out:
+ if (cs != NULL) {
+ /* for testing...
+ char *values[4] = {"foo", "bar", "baz", NULL};
+ libhal_changeset_set_property_strlist (cs, "foo.bar", values);
+ */
+ libhal_device_commit_changeset (ctx, cs, &error);
+ libhal_device_free_changeset (cs);
+ }
- libhal_device_commit_changeset (ctx, changeset, &error);
- libhal_device_free_changeset (changeset);
-out:
if (fd >= 0)
close (fd);
diff --git a/libhal-storage/libhal-storage.c b/libhal-storage/libhal-storage.c
index 206ffd3d..b20a5a8d 100644
--- a/libhal-storage/libhal-storage.c
+++ b/libhal-storage/libhal-storage.c
@@ -711,6 +711,7 @@ struct LibHalDrive_s {
dbus_uint64_t drive_size;
dbus_uint64_t drive_media_size;
+ char *partition_scheme;
LibHalContext *hal_ctx;
@@ -738,6 +739,11 @@ struct LibHalVolume_s {
dbus_bool_t is_partition;
unsigned int partition_number;
+ char *partition_scheme;
+ char *partition_type;
+ char *partition_label;
+ char *partition_uuid;
+ char **partition_flags;
int msdos_part_table_type;
dbus_uint64_t msdos_part_table_start;
@@ -806,6 +812,7 @@ libhal_drive_free (LibHalDrive *drive)
libhal_free_string (drive->desired_mount_point);
libhal_free_string (drive->mount_filesystem);
libhal_free_string_array (drive->capabilities);
+ libhal_free_string (drive->partition_scheme);
free (drive);
}
@@ -833,6 +840,12 @@ libhal_volume_free (LibHalVolume *vol)
libhal_free_string (vol->crypto_backing_volume);
libhal_free_string (vol->storage_device);
+ libhal_free_string (vol->partition_scheme);
+ libhal_free_string (vol->partition_type);
+ libhal_free_string (vol->partition_label);
+ libhal_free_string (vol->partition_uuid);
+ libhal_free_string (vol->partition_flags);
+
free (vol);
}
@@ -941,6 +954,8 @@ libhal_drive_from_udi (LibHalContext *hal_ctx, const char *udi)
LIBHAL_PROP_EXTRACT_UINT64 ("storage.removable.media_size", drive->drive_media_size);
LIBHAL_PROP_EXTRACT_BOOL ("storage.requires_eject", drive->requires_eject);
+ LIBHAL_PROP_EXTRACT_STRING ("storage.partitioning_scheme", drive->partition_scheme);
+
LIBHAL_PROP_EXTRACT_STRING ("storage.physical_device", drive->physical_device);
LIBHAL_PROP_EXTRACT_STRING ("storage.firmware_version", drive->firmware_version);
LIBHAL_PROP_EXTRACT_STRING ("storage.serial", drive->serial);
@@ -1114,6 +1129,12 @@ libhal_volume_from_udi (LibHalContext *hal_ctx, const char *udi)
LIBHAL_PROP_EXTRACT_BOOL ("volume.is_partition", vol->is_partition);
LIBHAL_PROP_EXTRACT_INT ("volume.partition.number", vol->partition_number);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.scheme", vol->partition_scheme);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.type", vol->partition_type);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.label", vol->partition_label);
+ LIBHAL_PROP_EXTRACT_STRING ("volume.partition.uuid", vol->partition_uuid);
+ LIBHAL_PROP_EXTRACT_STRLIST ("volume.partition.flags", vol->partition_flags);
+
LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.start", vol->partition_start_offset);
LIBHAL_PROP_EXTRACT_UINT64 ("volume.partition.media_size", vol->partition_media_size);
LIBHAL_PROP_EXTRACT_INT ("volume.partition.msdos_part_table_type", vol->msdos_part_table_type);
@@ -1425,6 +1446,13 @@ libhal_drive_get_media_size (LibHalDrive *drive)
return drive->drive_media_size;
}
+const char *
+libhal_drive_get_partition_scheme (LibHalDrive *drive)
+{
+ return drive->partition_scheme;
+}
+
+
LibHalDriveType
libhal_drive_get_type (LibHalDrive *drive)
{
@@ -1569,6 +1597,37 @@ libhal_volume_get_partition_number (LibHalVolume *volume)
return volume->partition_number;
}
+const char *
+libhal_volume_get_partition_scheme (LibHalVolume *volume)
+{
+ return volume->partition_scheme;
+}
+
+const char *
+libhal_volume_get_partition_type (LibHalVolume *volume)
+{
+ return volume->partition_type;
+}
+
+const char *
+libhal_volume_get_partition_label (LibHalVolume *volume)
+{
+ return volume->partition_label;
+}
+
+const char *
+libhal_volume_get_partition_uuid (LibHalVolume *volume)
+{
+ return volume->partition_uuid;
+}
+
+const char **
+libhal_volume_get_partition_flags (LibHalVolume *volume)
+{
+ return volume->partition_flags;
+}
+
+
dbus_uint64_t
libhal_volume_get_partition_start_offset (LibHalVolume *volume)
{
diff --git a/libhal-storage/libhal-storage.h b/libhal-storage/libhal-storage.h
index 0ce5f2d3..c88a389f 100644
--- a/libhal-storage/libhal-storage.h
+++ b/libhal-storage/libhal-storage.h
@@ -32,6 +32,9 @@
#if defined(__cplusplus)
extern "C" {
+#if 0
+} /* shut up emacs indenting */
+#endif
#endif
struct LibHalDrive_s;
@@ -128,17 +131,17 @@ typedef struct {
const char *icon_path;
} LibHalStoragePolicyIconPair;
-LibHalStoragePolicy *libhal_storage_policy_new (void);
-void libhal_storage_policy_free (LibHalStoragePolicy *policy);
+LibHalStoragePolicy *libhal_storage_policy_new (void) LIBHAL_DEPRECATED;
+void libhal_storage_policy_free (LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
void libhal_storage_policy_set_icon_path (LibHalStoragePolicy *policy,
LibHalStoragePolicyIcon icon,
- const char *path);
+ const char *path) LIBHAL_DEPRECATED;
void libhal_storage_policy_set_icon_mapping (LibHalStoragePolicy *policy,
- LibHalStoragePolicyIconPair *pairs);
+ LibHalStoragePolicyIconPair *pairs) LIBHAL_DEPRECATED;
const char *libhal_storage_policy_lookup_icon (LibHalStoragePolicy *policy,
- LibHalStoragePolicyIcon icon);
+ LibHalStoragePolicyIcon icon) LIBHAL_DEPRECATED;
typedef enum {
LIBHAL_DRIVE_BUS_UNKNOWN = 0x00,
@@ -197,6 +200,7 @@ dbus_bool_t libhal_drive_uses_removable_media (LibHalDrive *dr
dbus_bool_t libhal_drive_is_media_detected (LibHalDrive *drive);
dbus_uint64_t libhal_drive_get_size (LibHalDrive *drive);
dbus_uint64_t libhal_drive_get_media_size (LibHalDrive *drive);
+const char *libhal_drive_get_partition_scheme (LibHalDrive *drive);
dbus_bool_t libhal_drive_no_partitions_hint (LibHalDrive *drive);
dbus_bool_t libhal_drive_requires_eject (LibHalDrive *drive);
LibHalDriveType libhal_drive_get_type (LibHalDrive *drive);
@@ -218,29 +222,29 @@ const char *libhal_drive_get_dedicated_icon_volume (LibHalDrive
char *libhal_drive_policy_compute_display_name (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
char *libhal_drive_policy_compute_icon_name (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
dbus_bool_t libhal_drive_policy_is_mountable (LibHalDrive *drive,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_drive_policy_get_desired_mount_point (LibHalDrive *drive,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_drive_policy_get_mount_options (LibHalDrive *drive,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_drive_policy_get_mount_fs (LibHalDrive *drive,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
char **libhal_drive_find_all_volumes (LibHalContext *hal_ctx,
LibHalDrive *drive,
int *num_volumes);
-char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx);
-dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx);
-char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx);
-char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx);
+char *libhal_drive_policy_default_get_mount_root (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+dbus_bool_t libhal_drive_policy_default_use_managed_keyword (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+char *libhal_drive_policy_default_get_managed_keyword_primary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
+char *libhal_drive_policy_default_get_managed_keyword_secondary (LibHalContext *hal_ctx) LIBHAL_DEPRECATED;
typedef enum {
@@ -290,9 +294,16 @@ dbus_bool_t libhal_volume_is_mounted (LibHalVolume
dbus_bool_t libhal_volume_is_mounted_read_only (LibHalVolume *volume);
dbus_bool_t libhal_volume_is_partition (LibHalVolume *volume);
dbus_bool_t libhal_volume_is_disc (LibHalVolume *volume);
+
+const char *libhal_volume_get_partition_scheme (LibHalVolume *volume);
+const char *libhal_volume_get_partition_type (LibHalVolume *volume);
+const char *libhal_volume_get_partition_label (LibHalVolume *volume);
+const char *libhal_volume_get_partition_uuid (LibHalVolume *volume);
+const char **libhal_volume_get_partition_flags (LibHalVolume *volume);
unsigned int libhal_volume_get_partition_number (LibHalVolume *volume);
dbus_uint64_t libhal_volume_get_partition_start_offset (LibHalVolume *volume);
dbus_uint64_t libhal_volume_get_partition_media_size (LibHalVolume *volume);
+
const char *libhal_volume_get_label (LibHalVolume *volume);
const char *libhal_volume_get_mount_point (LibHalVolume *volume);
const char *libhal_volume_get_uuid (LibHalVolume *volume);
@@ -309,38 +320,39 @@ dbus_bool_t libhal_volume_disc_is_rewritable (LibHalVolume
dbus_bool_t libhal_volume_disc_is_appendable (LibHalVolume *volume);
LibHalVolumeDiscType libhal_volume_get_disc_type (LibHalVolume *volume);
-int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume);
-dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume);
-dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume);
+int libhal_volume_get_msdos_part_table_type (LibHalVolume *volume) LIBHAL_DEPRECATED;
+dbus_uint64_t libhal_volume_get_msdos_part_table_start (LibHalVolume *volume) LIBHAL_DEPRECATED;
+dbus_uint64_t libhal_volume_get_msdos_part_table_size (LibHalVolume *volume) LIBHAL_DEPRECATED;
+
dbus_bool_t libhal_volume_should_ignore (LibHalVolume *volume);
-char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume);
+char *libhal_volume_policy_compute_size_as_string (LibHalVolume *volume) LIBHAL_DEPRECATED;
char *libhal_volume_policy_compute_display_name (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
char *libhal_volume_policy_compute_icon_name (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
dbus_bool_t libhal_volume_policy_should_be_visible (LibHalDrive *drive,
LibHalVolume *volume,
LibHalStoragePolicy *policy,
- const char *target_mount_point);
+ const char *target_mount_point) LIBHAL_DEPRECATED;
dbus_bool_t libhal_volume_policy_is_mountable (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_volume_policy_get_desired_mount_point (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_volume_policy_get_mount_options (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
const char *libhal_volume_policy_get_mount_fs (LibHalDrive *drive,
LibHalVolume *volume,
- LibHalStoragePolicy *policy);
+ LibHalStoragePolicy *policy) LIBHAL_DEPRECATED;
#if defined(__cplusplus)
diff --git a/libhal/libhal.h b/libhal/libhal.h
index 15ee2d4b..ab00e576 100644
--- a/libhal/libhal.h
+++ b/libhal/libhal.h
@@ -35,6 +35,13 @@ extern "C" {
#endif
#endif
+#if defined(__GNUC__)
+#define LIBHAL_DEPRECATED __attribute__ ((deprecated))
+#else
+#define LIBHAL_DEPRECATED
+#endif
+
+
#define LIBHAL_FREE_DBUS_ERROR(_dbus_error_) \
do { \
if (dbus_error_is_set(_dbus_error_)) \
diff --git a/partutil/Makefile.am b/partutil/Makefile.am
new file mode 100644
index 00000000..5d409bbd
--- /dev/null
+++ b/partutil/Makefile.am
@@ -0,0 +1,11 @@
+
+INCLUDES = @GLIB_CFLAGS@
+
+noinst_LTLIBRARIES = libpartutil.la
+
+libpartutil_la_SOURCES = partutil.h partutil.c ../hald/logger.c
+
+libpartutil_la_LIBADD = @GLIB_LIBS@ @PARTED_LIBS@
+
+clean-local :
+ rm -f *~
diff --git a/partutil/partutil.c b/partutil/partutil.c
new file mode 100644
index 00000000..beeaedb1
--- /dev/null
+++ b/partutil/partutil.c
@@ -0,0 +1,1791 @@
+/***************************************************************************
+ *
+ * part.c : library for reading and writing partition tables - uses
+ * libparted for the heavy lifting
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <ctype.h>
+
+#include <linux/hdreg.h>
+
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+
+#include "../hald/logger.h"
+#include "partutil.h"
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+
+#ifdef USE_PARTED
+#include <parted/parted.h>
+#endif
+
+const char *
+part_get_scheme_name (PartitionScheme scheme)
+{
+ const char *s;
+
+ switch (scheme) {
+ case PART_TYPE_GPT:
+ s = "gpt";
+ break;
+ case PART_TYPE_MSDOS:
+ s = "mbr";
+ break;
+ case PART_TYPE_MSDOS_EXTENDED:
+ s = "embr";
+ break;
+ case PART_TYPE_APPLE:
+ s = "apm";
+ break;
+ default:
+ s = NULL;
+ break;
+ }
+
+ return s;
+}
+
+struct PartitionEntry_s;
+typedef struct PartitionEntry_s PartitionEntry;
+
+struct PartitionEntry_s
+{
+ gboolean is_part_table;
+
+ /* NULL iff is_part_table==FALSE */
+ PartitionTable *part_table;
+
+ /* these are always set */
+ guint8 *data;
+ int length;
+
+ /* offset _on disk_ where the entry starts */
+ guint64 offset;
+};
+
+struct PartitionTable_s
+{
+ /* partitioning scheme used */
+ PartitionScheme scheme;
+
+ /* offset of table on disk */
+ guint64 offset;
+ guint64 size;
+
+ /* entries in partition table */
+ GSList *entries;
+};
+
+void
+part_table_find (PartitionTable *p, guint64 offset,
+ PartitionTable **out_part_table, int *out_entry)
+{
+ int n;
+ int num_entries;
+
+ *out_part_table = p;
+ *out_entry = -1;
+
+ num_entries = part_table_get_num_entries (p);
+ for (n = 0; n < num_entries; n++) {
+ guint64 pe_offset;
+ guint64 pe_size;
+
+ pe_offset = part_table_entry_get_offset (p, n);
+ pe_size = part_table_entry_get_size (p, n);
+
+ if ((offset >= pe_offset) && (offset < pe_offset + pe_size)) {
+ PartitionTable *part_table_nested;
+
+ part_table_nested = part_table_entry_get_nested (p, n);
+ /* return the extended partition only if the offset points to it - otherwise
+ * look for a logical partition
+ */
+ if (part_table_nested != NULL && offset > pe_offset) {
+ part_table_find (part_table_nested, offset, out_part_table, out_entry);
+ } else {
+ *out_entry = n;
+ }
+
+ /* and we're done... */
+ break;
+ }
+ }
+}
+
+
+static guint16
+get_le16 (const void *buf)
+{
+ return GUINT16_FROM_LE ( * ((guint16 *) buf) );
+}
+
+
+static guint32
+get_le32 (const void *buf)
+{
+ return GUINT32_FROM_LE ( * ((guint32 *) buf) );
+}
+
+static guint64
+get_le64 (const void *buf)
+{
+ return GUINT64_FROM_LE ( * ((guint64 *) buf) );
+}
+
+
+static guint32
+get_be32 (const void *buf)
+{
+ return GUINT32_FROM_BE ( * ((guint32 *) buf) );
+}
+
+/* see http://en.wikipedia.org/wiki/Globally_Unique_Identifier - excerpt
+ *
+ * Guids are most commonly written in text as a sequence of hexadecimal digits as such:
+ *
+ * 3F2504E0-4F89-11D3-9A0C-0305E82C3301
+ *
+ * This text notation follows from the data structure defined above. The sequence is
+ *
+ * 1. Data1 (8 characters)
+ * 2. Hyphen
+ * 3. Data2 (4 characters)
+ * 4. Hyphen
+ * 5. Data3 (4 characters)
+ * 6. Hyphen
+ * 7. Initial two items from Data4 (4 characters)
+ * 8. Hyphen
+ * 9. Remaining six items from Data4 (12 characters)
+ *
+ * Often braces are added to enclose the above format, as such:
+ *
+ * {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
+ *
+ * When printing fewer characters is desired guids are sometimes encoded
+ * into a base64 string of 22 to 24 characters (depending on
+ * padding). For instance:
+ *
+ * 7QDBkvCA1+B9K/U0vrQx1A
+ * 7QDBkvCA1+B9K/U0vrQx1A==
+ */
+
+typedef struct efi_guid_s {
+ guint32 data1;
+ guint16 data2;
+ guint16 data3;
+ guint8 data4[8];
+} __attribute__ ((packed)) efi_guid;
+
+static char *
+get_le_guid (const guint8 *buf)
+{
+ efi_guid *guid = (efi_guid *) buf;
+
+ return g_strdup_printf("%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ get_le32 (&(guid->data1)),
+ get_le16 (&(guid->data2)),
+ get_le16 (&(guid->data3)),
+ guid->data4[0],
+ guid->data4[1],
+ guid->data4[2],
+ guid->data4[3],
+ guid->data4[4],
+ guid->data4[5],
+ guid->data4[6],
+ guid->data4[7]);
+}
+
+static gboolean
+set_le_guid (guint8 *buf, const char *source)
+{
+ efi_guid *guid = (efi_guid *) buf;
+ guint32 __attribute__((__unused__)) data1;
+ guint16 __attribute__((__unused__)) data2;
+ guint16 __attribute__((__unused__)) data3;
+ guint8 __attribute__((__unused__)) data4[8];
+ gboolean ret;
+ int n;
+
+ n = sscanf (source, "%x-%hx-%hx-%02hhx%02hhx-%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
+ &guid->data1,
+ &guid->data2,
+ &guid->data3,
+ &(guid->data4[0]),
+ &(guid->data4[1]),
+ &(guid->data4[2]),
+ &(guid->data4[3]),
+ &(guid->data4[4]),
+ &(guid->data4[5]),
+ &(guid->data4[6]),
+ &(guid->data4[7]));
+
+ if (n != 11) {
+ HAL_INFO (("guid '%s' is not valid"));
+ goto out;
+ }
+
+#if 0
+ HAL_INFO (("source = %s", source));
+ HAL_INFO (("data1 = %08x", guid->data1));
+ HAL_INFO (("data2 = %04x", guid->data2));
+ HAL_INFO (("data3 = %04x", guid->data3));
+ HAL_INFO (("data4[0] = %02x", guid->data4[0]));
+ HAL_INFO (("data4[1] = %02x", guid->data4[1]));
+ HAL_INFO (("data4[2] = %02x", guid->data4[2]));
+ HAL_INFO (("data4[3] = %02x", guid->data4[3]));
+ HAL_INFO (("data4[4] = %02x", guid->data4[4]));
+ HAL_INFO (("data4[5] = %02x", guid->data4[5]));
+ HAL_INFO (("data4[6] = %02x", guid->data4[6]));
+ HAL_INFO (("data4[7] = %02x", guid->data4[7]));
+#endif
+
+ guid->data1 = GUINT32_TO_LE (guid->data1);
+ guid->data2 = GUINT16_TO_LE (guid->data2);
+ guid->data3 = GUINT16_TO_LE (guid->data3);
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+static PartitionEntry *
+part_entry_new (PartitionTable *e_part_table, const guint8 *data, int length, guint64 offset)
+{
+ PartitionEntry *pe;
+
+ pe = g_new0 (PartitionEntry, 1);
+ pe->is_part_table = (e_part_table != NULL);
+ pe->part_table = e_part_table;
+ pe->offset = offset;
+ pe->length = length;
+ pe->data = g_new0 (guint8, length);
+ memcpy (pe->data, data, length);
+
+ return pe;
+}
+
+static void
+part_entry_free (PartitionEntry *pe)
+{
+ if (pe->part_table != NULL) {
+ part_table_free (pe->part_table);
+ }
+ g_free (pe->data);
+ g_free (pe);
+}
+
+static PartitionTable *
+part_table_new_empty (PartitionScheme scheme)
+{
+ PartitionTable *p;
+
+ p = g_new0 (PartitionTable, 1);
+ p->scheme = scheme;
+ p->offset = 0;
+ p->entries = NULL;
+
+ return p;
+}
+
+void
+part_table_free (PartitionTable *p)
+{
+ GSList *i;
+
+ for (i = p->entries; i != NULL; i = i->next) {
+ PartitionEntry *pe = i->data;
+ part_entry_free (pe);
+ }
+ g_slist_free (p->entries);
+ g_free (p);
+}
+
+#if 0
+static PartitionTable *
+part_table_parse_bsd (int fd, guint64 offset, guint64 size)
+{
+ PartitionTable *p;
+
+ p = NULL;
+
+ /* TODO */
+
+ return p;
+}
+#endif
+
+
+#define MSDOS_MAGIC "\x55\xaa"
+#define MSDOS_PARTTABLE_OFFSET 0x1be
+#define MSDOS_SIG_OFF 0x1fe
+
+#if 0
+static void
+hexdump (const guint8 *mem, int size)
+{
+ int i;
+ int j;
+ int n;
+ const guint8 *buf = (const guint8 *) mem;
+
+ n = 0;
+ printf ("Dumping %d=0x%x bytes\n", size, size);
+ while (n < size) {
+
+ printf ("0x%04x: ", n);
+
+ j = n;
+ for (i = 0; i < 16; i++) {
+ if (j >= size)
+ break;
+ printf ("%02x ", buf[j]);
+ j++;
+ }
+
+ for ( ; i < 16; i++) {
+ printf (" ");
+ }
+
+ printf (" ");
+
+ j = n;
+ for (i = 0; i < 16; i++) {
+ if (j >= size)
+ break;
+ printf ("%c", isprint(buf[j]) ? buf[j] : '.');
+ j++;
+ }
+
+ printf ("\n");
+
+ n += 16;
+ }
+}
+#endif
+
+static PartitionTable *
+part_table_parse_msdos_extended (int fd, guint64 offset, guint64 size)
+{
+ int n;
+ PartitionTable *p;
+ guint64 next;
+
+ //HAL_INFO (("Entering MS-DOS extended parser"));
+
+ p = NULL;
+
+ next = offset;
+
+ while (next != 0) {
+ guint64 readfrom;
+ const guint8 embr[512];
+
+ readfrom = next;
+ next = 0;
+
+ //HAL_INFO (("readfrom = %lld", readfrom));
+
+ if (lseek (fd, readfrom, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &embr, sizeof (embr)) != sizeof (embr)) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+
+ if (memcmp (&embr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) {
+ HAL_INFO (("No MSDOS_MAGIC found"));
+ goto out;
+ }
+
+ //HAL_INFO (("MSDOS_MAGIC found"));
+
+ if (p == NULL) {
+ p = part_table_new_empty (PART_TYPE_MSDOS_EXTENDED);
+ p->offset = offset;
+ p->size = size;
+ }
+
+
+ for (n = 0; n < 2; n++) {
+ PartitionEntry *pe;
+ guint64 pstart;
+ guint64 psize;
+
+ pstart = 0x200 * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
+ psize = 0x200 * ((guint64) get_le32 (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
+
+ if (psize == 0)
+ continue;
+
+ pe = NULL;
+
+ if (n == 0) {
+ //HAL_INFO (("part %d (offset %lld, size %lld, type 0x%02x)",
+ // n, readfrom + pstart, psize, ptype));
+
+ //HAL_INFO (("pstart = %lld", pstart));
+
+ //hexdump (&(embr[MSDOS_PARTTABLE_OFFSET + n * 16]), 16);
+
+ pe = part_entry_new (NULL,
+ &(embr[MSDOS_PARTTABLE_OFFSET + n * 16]),
+ 16,
+ readfrom + MSDOS_PARTTABLE_OFFSET + n * 16);
+ } else {
+ if (pstart != 0) {
+ //HAL_INFO (("found chain at offset %lld", offset + pstart);
+ next = offset + pstart;
+ }
+ }
+
+ //HAL_INFO (("pe = %p", pe));
+
+ if (pe != NULL) {
+ p->entries = g_slist_append (p->entries, pe);
+ }
+ }
+
+ }
+
+out:
+ //HAL_INFO (("Exiting MS-DOS extended parser"));
+ return p;
+}
+
+static PartitionTable *
+part_table_parse_msdos (int fd, guint64 offset, guint64 size, gboolean *found_gpt)
+{
+ int n;
+ const guint8 mbr[512];
+ PartitionTable *p;
+
+ //HAL_INFO (("Entering MS-DOS parser"));
+
+ *found_gpt = FALSE;
+
+ p = NULL;
+
+ if (lseek (fd, offset, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &mbr, sizeof (mbr)) != sizeof (mbr)) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+
+ if (memcmp (&mbr[MSDOS_SIG_OFF], MSDOS_MAGIC, 2) != 0) {
+ HAL_INFO (("No MSDOS_MAGIC found"));
+ goto out;
+ }
+
+ //HAL_INFO (("MSDOS_MAGIC found"));
+
+ /* sanity checks */
+ for (n = 0; n < 4; n++) {
+ if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0 &&
+ mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 0] != 0x80) {
+ HAL_INFO (("partitioning flag for part %d is not 0x00 or 0x80", n));
+ goto out;
+ }
+ /* protective MBR for GPT => GPT, not MS-DOS */
+ if (mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4] == 0xee) {
+ HAL_INFO (("found partition type 0xee => protective MBR for GPT", n));
+ *found_gpt = TRUE;
+ goto out;
+ }
+ }
+
+ p = part_table_new_empty (PART_TYPE_MSDOS);
+ p->offset = offset;
+ p->size = size;
+
+ /* we _always_ want to create four partitions */
+ for (n = 0; n < 4; n++) {
+ PartitionEntry *pe;
+ guint64 pstart;
+ guint64 psize;
+ guint8 ptype;
+ PartitionTable *e_part_table;
+
+ pstart = 0x200 * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 8])));
+ psize = 0x200 * ((guint64) get_le32 (&(mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 12])));
+ ptype = mbr[MSDOS_PARTTABLE_OFFSET + n * 16 + 4];
+
+ //HAL_INFO (("looking at part %d (offset %lld, size %lld, type 0x%02x)", n, pstart, psize, ptype));
+
+ pe = NULL;
+ e_part_table = NULL;
+
+ /* look for embedded partition tables */
+ switch (ptype) {
+
+ /* extended partitions */
+ case 0x05: /* MS-DOS */
+ case 0x0f: /* Win95 */
+ case 0x85: /* Linux */
+ e_part_table = part_table_parse_msdos_extended (fd, pstart, psize);
+ if (e_part_table != NULL) {
+ pe = part_entry_new (e_part_table,
+ &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]),
+ 16,
+ offset + MSDOS_PARTTABLE_OFFSET + n * 16);
+ }
+ break;
+
+ case 0xa5: /* FreeBSD */
+ case 0xa6: /* OpenBSD */
+ case 0xa9: /* NetBSD */
+ //e_part_table = part_table_parse_bsd (fd, pstart, psize);
+ //break;
+
+ default:
+ //HAL_INFO (("new part entry"));
+ pe = part_entry_new (NULL,
+ &(mbr[MSDOS_PARTTABLE_OFFSET + n * 16]),
+ 16,
+ offset + MSDOS_PARTTABLE_OFFSET + n * 16);
+ break;
+ }
+
+ //HAL_INFO (("pe = %p", pe));
+
+ p->entries = g_slist_append (p->entries, pe);
+ }
+
+out:
+ //HAL_INFO (("Exiting MS-DOS parser"));
+ return p;
+}
+
+#define GPT_MAGIC "EFI PART"
+
+#define GPT_PART_TYPE_GUID_EMPTY "00000000-0000-0000-0000-000000000000"
+
+static PartitionTable *
+part_table_parse_gpt (int fd, guint64 offset, guint64 size)
+{
+ int n;
+ PartitionTable *p;
+ guint8 buf[16];
+ guint64 partition_entry_lba;
+ int num_entries;
+ int size_of_entry;
+
+ HAL_INFO (("Entering EFI GPT parser"));
+
+ /* by way of getting here, we've already checked for a protective MBR */
+
+ p = NULL;
+
+ /* Check GPT signature */
+ if (lseek (fd, offset + 512 + 0, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, buf, 8) != 8) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (memcmp (buf, GPT_MAGIC, 8) != 0) {
+ HAL_INFO (("No GPT_MAGIC found"));
+ goto out;
+ }
+
+ HAL_INFO (("GPT magic found"));
+
+ /* Disk UUID */
+ if (lseek (fd, offset + 512 + 56, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, buf, 16) != 16) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ //hexdump ((guint8*) buf, 16);
+
+ if (lseek (fd, offset + 512 + 72, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, buf, 8) != 8) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ partition_entry_lba = get_le64 (buf);
+
+ if (lseek (fd, offset + 512 + 80, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, buf, 4) != 4) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ num_entries = get_le32 (buf);
+
+ if (lseek (fd, offset + 512 + 84, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, buf, 4) != 4) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ size_of_entry = get_le32(buf);
+
+
+ p = part_table_new_empty (PART_TYPE_GPT);
+ p->offset = offset;
+ p->size = size;
+
+ HAL_INFO (("partition_entry_lba=%d", partition_entry_lba));
+ HAL_INFO (("num_entries=%d", num_entries));
+ HAL_INFO (("size_of_entry=%d", size_of_entry));
+
+ for (n = 0; n < num_entries; n++) {
+ PartitionEntry *pe;
+ struct {
+ guint8 partition_type_guid[16];
+ guint8 partition_guid[16];
+ guint8 starting_lba[8];
+ guint8 ending_lba[8];
+ guint8 attributes[8];
+ guint8 partition_name[72];
+ } gpt_part_entry;
+ char *partition_type_guid;
+
+ if (lseek (fd, offset + partition_entry_lba * 512 + n * size_of_entry, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &gpt_part_entry, 128) != 128) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+
+ partition_type_guid = get_le_guid (gpt_part_entry.partition_type_guid);
+
+ if (strcmp (partition_type_guid, GPT_PART_TYPE_GUID_EMPTY) == 0)
+ continue;
+
+ pe = part_entry_new (NULL,
+ (guint8*) &gpt_part_entry,
+ 128,
+ offset + partition_entry_lba * 512 + n * size_of_entry);
+ p->entries = g_slist_append (p->entries, pe);
+
+ g_free (partition_type_guid);
+
+ //hexdump ((guint8 *) &gpt_part_entry, 128);
+
+ }
+
+
+out:
+ HAL_INFO (("Leaving EFI GPT parser"));
+ return p;
+}
+
+#define MAC_MAGIC "ER"
+#define MAC_PART_MAGIC "PM"
+
+static PartitionTable *
+part_table_parse_apple (int fd, guint64 offset, guint64 size)
+{
+ int n;
+ PartitionTable *p;
+ struct {
+ guint16 signature;
+ guint16 block_size;
+ guint32 block_count;
+ /* more stuff */
+ } __attribute__ ((packed)) mac_header;
+ struct {
+ guint16 signature;
+ guint16 res1;
+ guint32 map_count;
+ guint32 start_block;
+ guint32 block_count;
+ char name[32];
+ char type[32];
+ guint32 data_start;
+ guint32 data_count;
+ guint32 status;
+ guint32 boot_start;
+ guint32 boot_size;
+ guint32 boot_load;
+ guint32 boot_load2;
+ guint32 boot_entry;
+ guint32 boot_entry2;
+ guint32 boot_cksum;
+ char processor[16]; /* identifies ISA of boot */
+ /* more stuff */
+ } __attribute__ ((packed)) mac_part;
+ int block_size;
+ int block_count;
+ int map_count;
+
+ HAL_INFO (("Entering Apple parser"));
+
+ p = NULL;
+
+ /* Check Mac start of disk signature */
+ if (lseek (fd, offset + 0, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &mac_header, sizeof (mac_header)) != sizeof (mac_header)) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (memcmp (&(mac_header.signature), MAC_MAGIC, 2) != 0) {
+ HAL_INFO (("No MAC_MAGIC found"));
+ goto out;
+ }
+
+ block_size = GUINT16_FROM_BE (mac_header.block_size);
+ block_count = GUINT32_FROM_BE (mac_header.block_count); /* num blocks on whole disk */
+
+ HAL_INFO (("Mac MAGIC found, block_size=%d", block_size));
+
+ p = part_table_new_empty (PART_TYPE_APPLE);
+ p->offset = offset;
+ p->size = size;
+
+ /* get number of entries from first entry */
+ if (lseek (fd, offset + block_size, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+ map_count = GUINT32_FROM_BE (mac_part.map_count); /* num blocks in part map */
+
+ HAL_INFO (("map_count = %d", map_count));
+
+ for (n = 0; n < map_count; n++) {
+ PartitionEntry *pe;
+
+ if (memcmp (&(mac_part.signature), MAC_PART_MAGIC, 2) != 0) {
+ HAL_INFO (("No MAC_PART_MAGIC found"));
+ break;
+ }
+
+ if (lseek (fd, offset + (n + 1) * block_size, SEEK_SET) < 0) {
+ HAL_INFO (("lseek failed (%s)", strerror (errno)));
+ goto out;
+ }
+ if (read (fd, &mac_part, sizeof (mac_part)) != sizeof (mac_part)) {
+ HAL_INFO (("read failed (%s)", strerror (errno)));
+ goto out;
+ }
+
+ pe = part_entry_new (NULL,
+ (guint8*) &mac_part,
+ sizeof (mac_part),
+ offset + (n + 1) * block_size);
+ p->entries = g_slist_append (p->entries, pe);
+
+ }
+
+out:
+ HAL_INFO (("Leaving Apple parser"));
+ return p;
+}
+
+PartitionTable *
+part_table_load_from_disk (char *device)
+{
+ int fd;
+ guint64 size;
+ PartitionTable *p;
+ gboolean found_gpt;
+
+ p = NULL;
+
+ fd = open (device, O_RDONLY);
+ if (fd < 0) {
+ HAL_INFO (("Cannot open device %s", device));
+ goto out;
+ }
+
+ if (ioctl (fd, BLKGETSIZE64, &size) != 0) {
+ HAL_INFO (("Cannot determine size of device"));
+ goto out;
+ }
+
+ p = part_table_parse_msdos (fd, 0, size, &found_gpt);
+ if (p != NULL) {
+ HAL_INFO (("MSDOS partition table detected"));
+ goto out;
+ }
+
+ if (found_gpt) {
+ p = part_table_parse_gpt (fd, 0, size);
+ if (p != NULL) {
+ HAL_INFO (("EFI GPT partition table detected"));
+ goto out;
+ }
+ }
+
+ p = part_table_parse_apple (fd, 0, size);
+ if (p != NULL) {
+ HAL_INFO (("Apple partition table detected"));
+ goto out;
+ }
+
+ HAL_INFO (("No known partition table found"));
+
+
+out:
+ if (fd >= 0)
+ close (fd);
+
+ return p;
+}
+
+
+
+PartitionScheme
+part_table_get_scheme (PartitionTable *p)
+{
+ return p->scheme;
+}
+
+int
+part_table_get_num_entries (PartitionTable *p)
+{
+ return g_slist_length (p->entries);
+}
+
+guint64
+part_table_get_offset (PartitionTable *p)
+{
+ return p->offset;
+}
+
+guint64
+part_table_get_size (PartitionTable *p)
+{
+ return p->size;
+}
+
+PartitionTable *
+part_table_entry_get_nested (PartitionTable *p, int entry)
+{
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ if (pe->is_part_table)
+ return pe->part_table;
+ else
+ return NULL;
+}
+
+/**************************************************************************/
+
+char *
+part_table_entry_get_type (PartitionTable *p, int entry)
+{
+ char *s = NULL;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ if (p == NULL)
+ goto out;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ s = get_le_guid (&(pe->data[0]));
+ break;
+ case PART_TYPE_MSDOS:
+ case PART_TYPE_MSDOS_EXTENDED:
+ s = g_strdup_printf ("0x%02x", pe->data[4]);
+ break;
+ case PART_TYPE_APPLE:
+ s = g_strdup ((char *) pe->data + 2*2 + 3*4 + 32);
+ g_strchomp (s);
+ break;
+ default:
+ break;
+ }
+out:
+ if (s != NULL) {
+ g_strchomp (s);
+ }
+ return s;
+}
+
+char *
+part_table_entry_get_uuid (PartitionTable *p, int entry)
+{
+ char *s = NULL;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ if (p == NULL)
+ goto out;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ s = get_le_guid (&(pe->data[16]));
+ break;
+ default:
+ break;
+ }
+out:
+ if (s != NULL) {
+ g_strchomp (s);
+ }
+ return s;
+}
+
+char *
+part_table_entry_get_label (PartitionTable *p, int entry)
+{
+ char *s = NULL;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ if (p == NULL)
+ goto out;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ s = g_utf16_to_utf8 ((const gunichar2 *) &(pe->data[56]), 36, NULL, NULL, NULL);
+ break;
+ case PART_TYPE_APPLE:
+ s = g_strdup ((char *) pe->data + 2*2 + 3*4);
+ g_strchomp (s);
+ break;
+ default:
+ break;
+ }
+out:
+ if (s != NULL) {
+ g_strchomp (s);
+ }
+ return s;
+}
+
+char **
+part_table_entry_get_flags (PartitionTable *p, int entry)
+{
+ int n;
+ char **ss = NULL;
+ guint32 apm_status;
+ guint64 gpt_attributes;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ if (p == NULL)
+ goto out;
+
+ ss = g_new0 (char*, 6 + 1); /* hard coded to max items we'll return */
+ ss[0] = NULL;
+ n = 0;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ gpt_attributes = get_le64 (&(pe->data[48]));
+
+ /* From Table 16 of EFI 2.0 spec, bit zero means:
+ *
+ * "Required for the platform to function. The system
+ * cannot function normally if this partition is
+ * removed. This partition should be considered as
+ * part of the hardware of the system, and if it is
+ * removed the system may not boot. It may contain
+ * diagnostics, recovery tools, or other code or data
+ * that is critical to the functioning of a system
+ * independent of any OS."
+ *
+ */
+ if (gpt_attributes & (1<<0)) {
+ ss[n++] = g_strdup ("required");
+ }
+
+ /* TODO: handle partition type specific attributes
+ *
+ * Found on the Internet: "For basic data partitions, the following attribute is
+ * defined:0x8000000000000000 prevents the partition from having a drive letter automatically
+ * assigned. By default, each partition is assigned a new drive letter. Setting this
+ * attribute ensures that when a disk is moved to a new computer, a new drive letter
+ * will not be automatically generated. Instead, the user can manually assign drive
+ * letters. Note: Other attributes can be added at any time."
+ */
+ break;
+
+ case PART_TYPE_MSDOS:
+ case PART_TYPE_MSDOS_EXTENDED:
+ if (pe->data[0] == 0x80) {
+ ss[n++] = g_strdup ("boot");
+ }
+ break;
+
+ case PART_TYPE_APPLE:
+ apm_status = get_be32 (&(pe->data[2*2 + 3*4 + 2*32 + 2*4]));
+ if (apm_status&(1<<1))
+ ss[n++] = g_strdup ("allocated");
+ if (apm_status&(1<<2))
+ ss[n++] = g_strdup ("in_use");
+ if (apm_status&(1<<3))
+ ss[n++] = g_strdup ("boot");
+ if (apm_status&(1<<4))
+ ss[n++] = g_strdup ("allow_read");
+ if (apm_status&(1<<5))
+ ss[n++] = g_strdup ("allow_write");
+ if (apm_status&(1<<6))
+ ss[n++] = g_strdup ("boot_code_is_pic");
+ break;
+ default:
+ break;
+ }
+ ss[n] = NULL;
+
+out:
+ return ss;
+}
+
+guint64
+part_table_entry_get_offset (PartitionTable *p, int entry)
+{
+ guint64 val;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ val = G_MAXUINT64;
+ if (p == NULL)
+ goto out;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ val = 0x200 * ((guint64) get_le64 (pe->data + 32));
+ break;
+
+ case PART_TYPE_MSDOS:
+ val = 0x200 * ((guint64) get_le32 (pe->data + 8));
+ break;
+ case PART_TYPE_MSDOS_EXTENDED:
+ /* tricky here.. the offset in the EMBR is from the start of the EMBR and they are
+ * scattered around the ext partition... Hence, just use the entry's offset and subtract
+ * it's offset from the EMBR..
+ */
+ val = 0x200 * ((guint64) get_le32 (pe->data + 8)) + pe->offset - MSDOS_PARTTABLE_OFFSET;
+ break;
+ case PART_TYPE_APPLE:
+ val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 1*4));
+ break;
+ default:
+ break;
+ }
+out:
+ return val;
+}
+
+guint64
+part_table_entry_get_size (PartitionTable *p, int entry)
+{
+ guint64 val;
+ PartitionEntry *pe = g_slist_nth_data (p->entries, entry);
+
+ val = G_MAXUINT64;
+ if (p == NULL)
+ goto out;
+
+ switch (p->scheme) {
+ case PART_TYPE_GPT:
+ val = 0x200 * (((guint64) get_le64 (pe->data + 40)) - ((guint64) get_le64 (pe->data + 32)) + 1);
+ break;
+ case PART_TYPE_MSDOS:
+ case PART_TYPE_MSDOS_EXTENDED:
+ val = 0x200 * ((guint64) get_le32 (pe->data + 12));
+ break;
+ case PART_TYPE_APPLE:
+ val = 0x200 * ((guint64) get_be32 (pe->data + 2*2 + 2*4));
+ break;
+ default:
+ break;
+ }
+out:
+ return val;
+}
+
+/**************************************************************************/
+
+#ifdef USE_PARTED
+
+/* internal function to both add OR change a partition - if size==0,
+ * then we're changing, otherwise we're adding
+ */
+
+static gboolean
+part_add_change_partition (char *device_file,
+ guint64 start, guint64 size,
+ guint64 new_start, guint64 new_size,
+ guint64 *out_start, guint64 *out_size,
+ char *type, char *label, char **flags,
+ int geometry_hps, int geometry_spt)
+{
+ int n;
+ gboolean is_change;
+ gboolean res;
+ PedDevice *device;
+ PedDisk *disk;
+ PedPartition *part;
+ PedConstraint* constraint;
+ PedPartitionType ped_type;
+ guint64 start_sector;
+ guint64 end_sector;
+ guint64 new_start_sector;
+ guint64 new_end_sector;
+ PartitionTable *p;
+ PartitionTable *container_p;
+ int container_entry;
+ PartitionScheme scheme;
+ guint8 mbr_flags = 0;
+ guint8 mbr_part_type = 0;
+ char *endp;
+ guint64 gpt_attributes = 0;
+ guint32 apm_status = 0;
+
+ res = FALSE;
+
+ is_change = FALSE;
+ if (size == 0) {
+ is_change = TRUE;
+ }
+
+ if (is_change) {
+ HAL_INFO (("In part_change_partition: device_file=%s, start=%lld, new_start=%lld, new_size=%lld, type=%s", device_file, start, new_start, new_size, type));
+ } else {
+ HAL_INFO (("In part_add_partition: device_file=%s, start=%lld, size=%lld, type=%s", device_file, start, size, type));
+ }
+
+ /* first, find the kind of (embedded) partition table the new partition is going to be part of */
+ p = part_table_load_from_disk (device_file);
+ if (p == NULL) {
+ HAL_INFO (("Cannot load partition table from %s", device_file));
+ goto out;
+ }
+
+ part_table_find (p, start + 512, &container_p, &container_entry);
+ scheme = part_table_get_scheme (container_p);
+
+ if (is_change) {
+ /* if changing, make sure there is a partition to change */
+ if (container_entry < 0) {
+ HAL_INFO (("Couldn't find partition to change"));
+ goto out;
+ }
+ } else {
+ /* if adding, make sure there is no partition in the way... */
+ if (container_entry >= 0) {
+ char *part_type;
+
+ /* this might be Apple_Free if we're on PART_TYPE_APPLE */
+ part_type = part_table_entry_get_type (p, container_entry);
+ if (! (p->scheme == PART_TYPE_APPLE && part_type != NULL && (strcmp (part_type, "Apple_Free") == 0))) {
+ part_table_free (p);
+ HAL_INFO (("There is a partition in the way on %s", device_file));
+ goto out;
+ }
+ }
+ }
+
+ HAL_INFO (("containing partition table scheme = %d", scheme));
+
+ part_table_free (p);
+ p = NULL;
+
+ if (!is_change) {
+ if (type == NULL) {
+ HAL_INFO (("No type specified"));
+ goto out;
+ }
+ }
+
+ /* now that we know the partitoning scheme, sanity check type and flags */
+ switch (scheme) {
+ case PART_TYPE_MSDOS:
+ case PART_TYPE_MSDOS_EXTENDED:
+ mbr_flags = 0;
+ if (flags != NULL) {
+ for (n = 0; flags[n] != NULL; n++) {
+ if (strcmp (flags[n], "boot") == 0) {
+ mbr_flags |= 0x80;
+ } else {
+ HAL_INFO (("unknown flag '%s'", flags[n]));
+ goto out;
+ }
+ }
+ }
+
+ if (type != NULL) {
+ mbr_part_type = (guint8) (strtol (type, &endp, 0));
+ if (*endp != '\0') {
+ HAL_INFO (("invalid type '%s' given", type));
+ goto out;
+ }
+ }
+
+ if (label != NULL) {
+ HAL_INFO (("labeled partitions not supported on MSDOS or MSDOS_EXTENDED"));
+ goto out;
+ }
+
+ break;
+
+ case PART_TYPE_GPT:
+ gpt_attributes = 0;
+ if (flags != NULL) {
+ for (n = 0; flags[n] != NULL; n++) {
+ if (strcmp (flags[n], "required") == 0) {
+ gpt_attributes |= 1;
+ } else {
+ HAL_INFO (("unknown flag '%s'", flags[n]));
+ goto out;
+ }
+ }
+ }
+ break;
+
+ case PART_TYPE_APPLE:
+ apm_status = 0;
+ if (flags != NULL) {
+ for (n = 0; flags[n] != NULL; n++) {
+ if (strcmp (flags[n], "allocated") == 0) {
+ apm_status |= (1<<1);
+ } else if (strcmp (flags[n], "in_use") == 0) {
+ apm_status |= (1<<2);
+ } else if (strcmp (flags[n], "boot") == 0) {
+ apm_status |= (1<<3);
+ } else if (strcmp (flags[n], "allow_read") == 0) {
+ apm_status |= (1<<4);
+ } else if (strcmp (flags[n], "allow_write") == 0) {
+ apm_status |= (1<<5);
+ } else if (strcmp (flags[n], "boot_code_is_pic") == 0) {
+ apm_status |= (1<<6);
+ } else {
+ HAL_INFO (("unknown flag '%s'", flags[n]));
+ goto out;
+ }
+ }
+ }
+ break;
+
+ default:
+ HAL_INFO (("partitioning scheme %d not supported", scheme));
+ goto out;
+ }
+
+ switch (scheme) {
+ case PART_TYPE_MSDOS:
+ if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) {
+ ped_type = PED_PARTITION_EXTENDED;
+ } else {
+ ped_type = PED_PARTITION_NORMAL;
+ }
+ break;
+
+ case PART_TYPE_MSDOS_EXTENDED:
+ ped_type = PED_PARTITION_LOGICAL;
+ if (mbr_part_type == 0x05 || mbr_part_type == 0x85 || mbr_part_type == 0x0f) {
+ HAL_INFO (("Cannot create an extended partition inside an extended partition"));
+ goto out;
+ }
+ break;
+
+ default:
+ ped_type = PED_PARTITION_NORMAL;
+ break;
+ }
+
+ /* now, create the partition */
+
+ start_sector = start / 512;
+ end_sector = (start + size) / 512 - 1;
+ new_start_sector = new_start / 512;
+ new_end_sector = (new_start + new_size) / 512 - 1;
+
+ device = ped_device_get (device_file);
+ if (device == NULL) {
+ HAL_INFO (("ped_device_get() failed"));
+ goto out;
+ }
+ HAL_INFO (("got it"));
+
+ /* set drive geometry on libparted object if the user requested it */
+ if (geometry_hps > 0 && geometry_spt > 0 ) {
+ /* not sure this is authorized use of libparted, but, eh, it seems to work */
+ device->hw_geom.cylinders = device->bios_geom.cylinders = device->length / geometry_hps / geometry_spt;
+ device->hw_geom.heads = device->bios_geom.heads = geometry_hps;
+ device->hw_geom.sectors = device->bios_geom.sectors = geometry_spt;
+ }
+
+ disk = ped_disk_new (device);
+ if (disk == NULL) {
+ HAL_INFO (("ped_disk_new() failed"));
+ goto out_ped_device;
+ }
+ HAL_INFO (("got disk"));
+
+ if (!is_change) {
+ part = ped_partition_new (disk,
+ ped_type,
+ NULL,
+ start_sector,
+ end_sector);
+ if (part == NULL) {
+ HAL_INFO (("ped_partition_new() failed"));
+ goto out_ped_disk;
+ }
+ HAL_INFO (("new partition"));
+ } else {
+ part = ped_disk_get_partition_by_sector (disk,
+ start_sector);
+ if (part == NULL) {
+ HAL_INFO (("ped_partition_get_by_sector() failed"));
+ goto out_ped_disk;
+ }
+ HAL_INFO (("got partition"));
+ }
+
+
+ /* TODO HACK XXX FIXME UGLY BAD: This is super ugly abuse of
+ * libparted - we poke at their internal data structures - but
+ * there ain't nothing we can do about it until libparted
+ * provides API for this...
+ */
+ if (scheme == PART_TYPE_GPT) {
+ struct {
+ efi_guid type;
+ efi_guid uuid;
+ char name[37];
+ int lvm;
+ int raid;
+ int boot;
+ int hp_service;
+ int hidden;
+ /* more stuff */
+ } *gpt_data = (void *) part->disk_specific;
+
+ if (type != NULL) {
+ if (!set_le_guid ((guint8*) &gpt_data->type, type)) {
+ HAL_INFO (("type '%s' for GPT appear to be malformed", type));
+ goto out_ped_partition;
+ }
+ }
+
+ if (flags != NULL) {
+ if (gpt_attributes & 1) {
+ gpt_data->hidden = 1;
+ } else {
+ gpt_data->hidden = 0;
+ }
+ }
+
+ } else if (scheme == PART_TYPE_MSDOS || scheme == PART_TYPE_MSDOS_EXTENDED) {
+ struct {
+ unsigned char system;
+ int boot;
+ /* more stuff */
+ } *dos_data = (void *) part->disk_specific;
+
+ if (type != NULL) {
+ dos_data->system = mbr_part_type;
+ }
+ if (flags != NULL) {
+ if (mbr_flags & 0x80) {
+ dos_data->boot = 1;
+ } else {
+ dos_data->boot = 0;
+ }
+ }
+
+ } else if (scheme == PART_TYPE_APPLE) {
+ struct {
+ char volume_name[33]; /* eg: "Games" */
+ char system_name[33]; /* eg: "Apple_Unix_SVR2" */
+ char processor_name[17];
+ int is_boot;
+ int is_driver;
+ int has_driver;
+ int is_root;
+ int is_swap;
+ int is_lvm;
+ int is_raid;
+ PedSector data_region_length;
+ PedSector boot_region_length;
+ guint32 boot_base_address;
+ guint32 boot_entry_address;
+ guint32 boot_checksum;
+ guint32 status;
+ /* more stuff */
+ } *mac_data = (void *) part->disk_specific;
+
+ if (type != NULL) {
+ memset (mac_data->system_name, 0, 33);
+ strncpy (mac_data->system_name, type, 32);
+ }
+
+ if (flags != NULL) {
+ mac_data->status = apm_status;
+ }
+ }
+
+ if (label != NULL) {
+ ped_partition_set_name (part, label);
+ }
+
+ if (geometry_hps > 0 && geometry_spt > 0 ) {
+ /* respect drive geometry */
+ constraint = ped_constraint_any (device);
+ } else if (geometry_hps == -1 && geometry_spt == -1 ) {
+
+ /* undocumented (or is it?) libparted usage again.. it appears that
+ * the probed geometry is stored in hw_geom
+ */
+ device->bios_geom.cylinders = device->hw_geom.cylinders;
+ device->bios_geom.heads = device->hw_geom.heads;
+ device->bios_geom.sectors = device->hw_geom.sectors;
+
+ constraint = ped_constraint_any (device);
+ } else {
+ PedGeometry *geo_start;
+ PedGeometry *geo_end;
+
+ /* ignore drive geometry */
+ if (is_change) {
+ geo_start = ped_geometry_new (device, new_start_sector, 1);
+ geo_end = ped_geometry_new (device, new_end_sector, 1);
+ } else {
+ geo_start = ped_geometry_new (device, start_sector, 1);
+ geo_end = ped_geometry_new (device, end_sector, 1);
+ }
+
+ constraint = ped_constraint_new (ped_alignment_any, ped_alignment_any,
+ geo_start, geo_end, 1, device->length);
+ }
+
+try_change_again:
+ if (is_change) {
+ if (ped_disk_set_partition_geom (disk,
+ part,
+ constraint,
+ new_start_sector, new_end_sector) == 0) {
+ HAL_INFO (("ped_disk_set_partition_geom() failed"));
+ goto out_ped_constraint;
+ }
+ } else {
+ if (ped_disk_add_partition (disk,
+ part,
+ constraint) == 0) {
+ HAL_INFO (("ped_disk_add_partition() failed"));
+ goto out_ped_constraint;
+ }
+ }
+
+ *out_start = part->geom.start * 512;
+ *out_size = part->geom.length * 512;
+
+ if (is_change) {
+ /* make sure the resulting size is never smaller than requested
+ * (this is because one will resize the FS and *then* change the partition table)
+ */
+ if (*out_size < new_size) {
+ HAL_INFO (("new_size=%lld but resulting size, %lld, smaller than requested", new_size, *out_size));
+ new_end_sector++;
+ goto try_change_again;
+ } else {
+ HAL_INFO (("changed partition to start=%lld size=%lld", *out_start, *out_size));
+ }
+ } else {
+ HAL_INFO (("added partition start=%lld size=%lld", *out_start, *out_size));
+ }
+
+
+ /* hmm, if we don't do this libparted crashes.. I assume that
+ * ped_disk_add_partition assumes ownership of the
+ * PedPartition when adding it... sadly this is not documented
+ * anywhere.. sigh..
+ */
+ part = NULL;
+
+ /* use commit_to_dev rather than just commit to avoid
+ * libparted sending BLKRRPART to the kernel - we want to do
+ * this ourselves...
+ */
+ if (ped_disk_commit_to_dev (disk) == 0) {
+ HAL_INFO (("ped_disk_commit_to_dev() failed"));
+ goto out_ped_constraint;
+ }
+ HAL_INFO (("committed to disk"));
+
+ res = TRUE;
+
+ ped_constraint_destroy (constraint);
+ ped_disk_destroy (disk);
+ ped_device_destroy (device);
+ goto out;
+
+out_ped_constraint:
+ ped_constraint_destroy (constraint);
+
+out_ped_partition:
+ if (part != NULL) {
+ ped_partition_destroy (part);
+ }
+
+out_ped_disk:
+ ped_disk_destroy (disk);
+
+out_ped_device:
+ ped_device_destroy (device);
+
+out:
+ return res;
+}
+
+gboolean
+part_add_partition (char *device_file,
+ guint64 start, guint64 size,
+ guint64 *out_start, guint64 *out_size,
+ char *type, char *label, char **flags,
+ int geometry_hps, int geometry_spt)
+{
+ return part_add_change_partition (device_file,
+ start, size,
+ 0, 0,
+ out_start, out_size,
+ type, label, flags,
+ geometry_hps, geometry_spt);
+}
+
+gboolean
+part_change_partition (char *device_file,
+ guint64 start,
+ guint64 new_start, guint64 new_size,
+ guint64 *out_start, guint64 *out_size,
+ char *type, char *label, char **flags,
+ int geometry_hps, int geometry_spt)
+{
+ return part_add_change_partition (device_file,
+ start, 0,
+ new_start, new_size,
+ out_start, out_size,
+ type, label, flags,
+ geometry_hps, geometry_spt);
+}
+
+gboolean
+part_del_partition (char *device_file, guint64 offset)
+{
+ gboolean ret;
+ PedDevice *device;
+ PedDisk *disk;
+ PedPartition *part;
+ PartitionTable *p;
+ gboolean is_extended;
+ int n;
+
+ HAL_INFO (("In part_del_partition: device_file=%s, offset=%lld", device_file, offset));
+
+ ret = FALSE;
+
+
+ /* sigh.. one would think that if you passed the sector of where the
+ * the beginning of the extended partition starts, then _by_sector
+ * would return the same as _extended_partition.
+ *
+ * Sadly it's not so..
+ *
+ * So, check if the passed offset actually corresponds to a nested
+ * partition table...
+ */
+ is_extended = FALSE;
+ p = part_table_load_from_disk (device_file);
+ if (p == NULL) {
+ HAL_INFO (("Cannot load partition table from %s", device_file));
+ goto out;
+ }
+ for (n = 0; n < part_table_get_num_entries (p); n++) {
+ PartitionTable *nested;
+ nested = part_table_entry_get_nested (p, n);
+ if (nested != NULL) {
+ if (part_table_get_offset (nested) == offset) {
+ HAL_INFO (("partition to delete is an extended partition"));
+ is_extended = TRUE;
+ }
+ }
+ }
+ part_table_free (p);
+
+ device = ped_device_get (device_file);
+ if (device == NULL) {
+ HAL_INFO (("ped_device_get() failed"));
+ goto out;
+ }
+ HAL_INFO (("got it"));
+
+ disk = ped_disk_new (device);
+ if (disk == NULL) {
+ HAL_INFO (("ped_disk_new() failed"));
+ goto out_ped_device;
+ }
+ HAL_INFO (("got disk"));
+
+ if (is_extended) {
+ part = ped_disk_extended_partition (disk);
+ } else {
+ part = ped_disk_get_partition_by_sector (disk, offset / 512);
+ }
+
+ if (part == NULL) {
+ HAL_INFO (("ped_disk_get_partition_by_sector() failed"));
+ goto out_ped_disk;
+ }
+
+ HAL_INFO (("got partition - part->type=%d", part->type));
+ /* allow only to delete primary, logical and extended partitions */
+ if (! ((part->type == PED_PARTITION_NORMAL) ||
+ (part->type == PED_PARTITION_LOGICAL) ||
+ (part->type == PED_PARTITION_EXTENDED))) {
+ HAL_INFO (("no data partition at given offset %lld for device %s", offset, device_file));
+ goto out_ped_disk;
+ }
+
+ if (ped_disk_delete_partition (disk, part) == 0) {
+ HAL_INFO (("ped_disk_delete_partition() failed"));
+ goto out_ped_disk;
+ }
+
+ /* use commit_to_dev rather than just commit to avoid
+ * libparted sending BLKRRPART to the kernel - we want to do
+ * this ourselves...
+ */
+
+ if (ped_disk_commit_to_dev (disk) == 0) {
+ HAL_INFO (("ped_disk_commit_to_dev() failed"));
+ goto out_ped_disk;
+ }
+ HAL_INFO (("committed to disk"));
+
+ ret = TRUE;
+
+ ped_disk_destroy (disk);
+ ped_device_destroy (device);
+ goto out;
+
+out_ped_disk:
+ ped_disk_destroy (disk);
+
+out_ped_device:
+ ped_device_destroy (device);
+
+out:
+ return ret;
+}
+
+gboolean
+part_create_partition_table (char *device_file, PartitionScheme scheme)
+{
+ PedDevice *device;
+ PedDisk *disk;
+ PedDiskType *disk_type;
+ gboolean ret;
+
+ ret = FALSE;
+
+ HAL_INFO (("In part_create_partition_table: device_file=%s, scheme=%d", device_file, scheme));
+
+ device = ped_device_get (device_file);
+ if (device == NULL) {
+ HAL_INFO (("ped_device_get() failed"));
+ goto out;
+ }
+ HAL_INFO (("got it"));
+
+ switch (scheme) {
+ case PART_TYPE_MSDOS:
+ disk_type = ped_disk_type_get ("msdos");
+ break;
+ case PART_TYPE_APPLE:
+ disk_type = ped_disk_type_get ("mac");
+ break;
+ case PART_TYPE_GPT:
+ disk_type = ped_disk_type_get ("gpt");
+ break;
+ default:
+ disk_type = NULL;
+ break;
+ }
+
+ if (disk_type == NULL) {
+ HAL_INFO (("Unknown or unsupported partitioning scheme %d", scheme));
+ goto out;
+ }
+
+ disk = ped_disk_new_fresh (device, disk_type);
+ if (disk == NULL) {
+ HAL_INFO (("ped_disk_new_fresh() failed"));
+ goto out_ped_device;
+ }
+ HAL_INFO (("got disk"));
+
+ if (ped_disk_commit_to_dev (disk) == 0) {
+ HAL_INFO (("ped_disk_commit_to_dev() failed"));
+ goto out_ped_disk;
+ }
+ HAL_INFO (("committed to disk"));
+
+ ret = TRUE;
+
+ ped_disk_destroy (disk);
+ ped_device_destroy (device);
+ goto out;
+
+out_ped_disk:
+ ped_disk_destroy (disk);
+
+out_ped_device:
+ ped_device_destroy (device);
+
+out:
+ return ret;
+}
+
+#endif /* USE_PARTED */
+
+/**************************************************************************/
diff --git a/partutil/partutil.h b/partutil/partutil.h
new file mode 100644
index 00000000..61dec2f1
--- /dev/null
+++ b/partutil/partutil.h
@@ -0,0 +1,412 @@
+/***************************************************************************
+ *
+ * part.h : library for reading and writing partition tables - uses
+ * libparted for the heavy lifting
+ *
+ * Copyright (C) 2006 David Zeuthen, <david@fubar.dk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef PARTUTIL_H
+#define PARTUTIL_H
+
+#include <stdio.h>
+#include <glib.h>
+
+/* Partition schemes understood by this library */
+typedef enum {
+ PART_TYPE_MSDOS = 0,
+ PART_TYPE_MSDOS_EXTENDED = 1,
+ PART_TYPE_APPLE = 2,
+ PART_TYPE_GPT = 3
+} PartitionScheme;
+
+/**
+ * part_get_scheme_name:
+ * @scheme: the partitioning scheme
+ *
+ * Get a name for the partitioning scheme. The current mapping is used
+ *
+ * PART_TYPE_MSDOS -> mbr
+ * PART_TYPE_MSDOS_EXTENDED -> embr
+ * PART_TYPE_APPLE -> apm
+ * PART_TYPE_GPT -> gpt
+ *
+ * Returns: Name of scheme or NULL for unknown scheme. Caller shall not free this string.
+ */
+const char *part_get_scheme_name (PartitionScheme scheme);
+
+struct PartitionTable_s;
+typedef struct PartitionTable_s PartitionTable;
+
+
+/**
+ * part_table_load_from_disk:
+ * @device: name of device file for entire disk, e.g. /dev/sda
+ *
+ * Scans a disk and collect all partition entries and nested partition tables.
+ *
+ * Returns: A partition table object. Use part_table_free() to free this object.
+ */
+PartitionTable *part_table_load_from_disk (char *device);
+
+/**
+ * part_table_free:
+ * @part_table: the partition table
+ *
+ * Frees the partition table returned from part_table_load_from_disk().
+ */
+void part_table_free (PartitionTable *part_table);
+
+/* partition table inspection */
+
+/**
+ * part_table_get_scheme:
+ * @part_table: the partition table
+ *
+ * Get partitioning scheme.
+ *
+ * Returns: The partitioning scheme.
+ */
+PartitionScheme part_table_get_scheme (PartitionTable *part_table);
+
+/**
+ * part_table_get_num_entries:
+ * @part_table: the partition table
+ *
+ * Get number of entries in partition table.
+ *
+ * Returns: Number of entries.
+ */
+int part_table_get_num_entries (PartitionTable *part_table);
+
+/**
+ * part_table_get_offset:
+ * @part_table: the partition table
+ *
+ * Get offset from start of disk where partition table starts (as
+ * referenced in the partition table entry if it's an embedded
+ * partition table, otherwise zero for the full disk)
+ *
+ * Returns: offset, from start of disk, in bytes
+ */
+guint64 part_table_get_offset (PartitionTable *part_table);
+
+/**
+ * part_table_get_size:
+ * @part_table: the partition table
+ *
+ * Get size of partition table (as referenced in the partition table
+ * entry if it's an embedded partition table, otherwise the size of
+ * the full disk)
+ *
+ * Returns: size of partition, in bytes
+ */
+guint64 part_table_get_size (PartitionTable *part_table);
+
+/**
+ * part_table_find:
+ * @part_table: the partition table
+ * @offset: the offset to test for
+ * @out_part_table: where the (embedded) enclosing the entry will be stored
+ * @out_entry: there the partition table entry number will be stored
+ *
+ * This function finds the entry that a certain byte of the disk belongs to.
+ * As partition tables can be embedded (think MS-DOS extended partitions)
+ * the returned partition table (out_part_table) might be different from
+ * the one passed. If the offset belongs to a primary partition then the
+ * return partition_table will be the same as the passed one.
+ *
+ * If there is no partition at the given offset (might be free space),
+ * out_entry will be set to -1. Note that out_part_table will always
+ * be set though and free space in the primary disk space and the
+ * extended partition space differs.
+ *
+ * This is a convenience function.
+ */
+void part_table_find (PartitionTable *part_table,
+ guint64 offset,
+ PartitionTable **out_part_table,
+ int *out_entry);
+
+
+/**
+ * part_table_entry_get_nested:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * If the partition table entry points to an embedded partition table this
+ * function will return a PartitionTable object representing it.
+ *
+ * Returns: NULL if the entry does not point to a an embedded partition table.
+ * Do not free with part_table_free() - the object will be freed when
+ * freeing the root object.
+ */
+PartitionTable *part_table_entry_get_nested (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_type:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Get the partition table type - the type itself is partitioning scheme
+ * specific as described below.
+ *
+ * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED, the type is an integer
+ * encoded in a string, e.g. 0x83 is Linux. Use atoi() to convert back to
+ * an integer. See http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
+ * for details.
+ *
+ * For PART_TYPE_GPT, this is the GUID encoded as a string, see
+ * http://en.wikipedia.org/wiki/GUID_Partition_Table for details.
+ *
+ * For PART_TYPE_APPLE, this is a string as defined in
+ * http://developer.apple.com/documentation/mac/Devices/Devices-126.html.
+ * For FAT file systems, it appears that "DOS_FAT_32", "DOS_FAT_16" and
+ * "DOS_FAT_12" are also recognized under Mac OS X (I've tested this too) cf.
+ * http://lists.apple.com/archives/Darwin-drivers/2003/May/msg00021.html
+ *
+ * Returns: The partition table type. Caller shall free this with g_free().
+ */
+char *part_table_entry_get_type (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_label:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Label of the partition. This is only supported for PART_TYPE_APPLE and
+ * PART_TYPE_GPT. Note that this is not the same as the file system label
+ * in a file system in the partition.
+ *
+ * Returns: The label or NULL if the partitioning scheme does not support
+ * labels. Caller shall free this with g_free().
+ */
+char *part_table_entry_get_label (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_uuid:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Some UUID/GUID of the partition. This is only supported for PART_TYPE_GPT.
+ *
+ * Returns: The UUID or NULL if the partitioning scheme does not support
+ * UUID/GUID. Caller shall free this with g_free().
+ */
+char *part_table_entry_get_uuid (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_flags:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Get flags of partition table entry. This is dependent on the partitioning
+ * scheme.
+ *
+ * For PART_TYPE_MSDOS and PART_TYPE_MSDOS_EXTENDED the following flags are
+ * recognized:
+ * - "boot"; meaning that the bootable flag is set. This is used by some
+ * BIOS'es and boot loaders to populate a boot menu.
+ *
+ * For PART_TYPE_GPT the following flags are recognized:
+ * - "required" which corresponds to bit 0 of the attibutes
+ * (offset 48), meaning "Required for the platform to function. The
+ * system cannot function normally if this partition is removed. This
+ * partition should be considered as part of the hardware of the
+ * system, and if it is removed the system may not boot. It may
+ * contain diagnostics, recovery tools, or other code or data that is
+ * critical to the functioning of a system independent of any OS."
+ *
+ *
+ * For PART_TYPE_APPLE the following flags are recognized:
+ * - "allocated"; if the partition is already allocated
+ * - "in_use"; if the partition is in use; may be cleared after a system reset
+ * - "boot"; if partition contains valid boot information
+ * - "allow_read"; if partition allows reading
+ * - "allow_write"; if partition allows writing
+ * - "boot_code_is_pic"; if boot code is position independent
+ *
+ * Returns: An array of strings, one per flag, terminated by NULL. Caller
+ * shall free this with g_strfreev().
+ */
+char **part_table_entry_get_flags (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_offset:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Get offset from start of disk where partition starts (as referenced in the
+ * partition table entry)
+ *
+ * Returns: offset, from start of disk, in bytes
+ */
+guint64 part_table_entry_get_offset (PartitionTable *part_table, int entry);
+
+/**
+ * part_table_entry_get_size:
+ * @part_table: the partition table
+ * @entry: zero-based index of entry in partition table
+ *
+ * Get size of partition (as referenced in the partition table entry)
+ *
+ * Returns: size of partition, in bytes
+ */
+guint64 part_table_entry_get_size (PartitionTable *part_table, int entry);
+
+
+/**
+ * part_create_partition_table:
+ * @device: name of device file for entire disk, e.g. /dev/sda
+ * @scheme: the partitioning scheme
+ *
+ * Create a new fresh partition on a disk.
+ *
+ * Returns: TRUE if the operation was succesful, otherwise FALSE
+ */
+gboolean part_create_partition_table (char *device, PartitionScheme scheme);
+
+
+/**
+ * part_add_partition:
+ * @device: name of device file for entire disk, e.g. /dev/sda
+ * @start: start offset of partition, in bytes
+ * @size: size of partition, in bytes
+ * @out_start: where partition will start, after satisfying disk geometry constraints
+ * @out_size: size of partition, after satisfying disk geometry constraints
+ * @type: the partition type as defined in part_table_entry_get_type()
+ * @flags: the partition flags as defined in part_table_entry_get_flags()
+ * @label: the partition label as defined in part_table_entry_get_label()
+ * @geometry_hps: heads-per-sector used for LBA<->CHS conversions
+ * @geometry_spt: sectors-per-track used for LBA<->CHS conversions
+ *
+ * Adds a new partition to a disk.
+ *
+ * If geometry_hps and geomtry_spt are both positive, they will be
+ * used as the geometry of the disk for CHS<->LBA conversions. Notably
+ * this is only applicable for MSDOS / MSDOS_EXTENDED partition
+ * tables. Also, in this case, geometry is enforced to ensure that
+ * partitions start and end at cylinder boundaries.
+ *
+ * If either geometry_hps or geomtry_spt are zero, geometry is
+ * simply ignored and partitions will only be aligned to blocks, e.g.
+ * normally 512 byte boundaries.
+ *
+ * If both geometry_hps or geomtry_spt are -1, then geometry information
+ * probed from existing partition table entries / file systems on the
+ * disk. This is not always reliable.
+ *
+ * As such, the caller cannot always expect that the partition created
+ * will be at the requested offset and size due to e.g. geometry and
+ * block boundary alignment. Therefore, the start and size where the
+ * partition ends up is passed in the out_start and out_size
+ * arguments.
+ *
+ * As embedded partition tables are supported, the caller should use
+ * part_table_find() in advance to make sure that the passed type,
+ * label and flags match the (embedded) partition table that this
+ * partition will be part of.
+ *
+ * To create an MSDOS extended partition table in a MSDOS partition
+ * table, simply pass 0x05, 0x0f or 0x85 as the partition type.
+ *
+ * In order for changes to take effect, the caller needs to poke the
+ * OS kernel himself to make it reload the partition table. It is not
+ * automatically done by this function.
+ *
+ * NOTE: After calling this function you need to discard any partition table
+ * obtained with part_table_load_from_disk() since the in-memory data structure
+ * is not updated.
+ *
+ * Returns: TRUE if the operation was succesful, otherwise FALSE
+ */
+gboolean part_add_partition (char *device,
+ guint64 start, guint64 size,
+ guint64 *out_start, guint64 *out_size,
+ char *type, char *label, char **flags,
+ int geometry_hps, int geometry_spt);
+
+/**
+ * @device: name of device file for entire disk, e.g. /dev/sda
+ * @start: start offset of existing partition, in bytes
+ * @new_start: new start offset of partition, in bytes
+ * @new_size: new size of partition, in bytes
+ * @out_start: where partition will start, after satisfying disk geometry constraints
+ * @out_size: size of partition, after satisfying disk geometry constraints
+ * @type: the partition type as defined in part_table_entry_get_type() or NULL to not change
+ * @flags: the partition flags as defined in part_table_entry_get_flags() or NULL to not change
+ * @label: the partition label as defined in part_table_entry_get_label() or NULL to not change
+ * @geometry_hps: heads-per-sector used for LBA<->CHS conversions
+ * @geometry_spt: sectors-per-track used for LBA<->CHS conversions
+ *
+ * Changes an existing partition table entry on disk. The contents of
+ * the partition will not be touched.
+ *
+ * XXX TODO FIXME: probably be careful with overlapping partitions as
+ * e.g. extended MS-DOS partitions have the partition information just
+ * before the partition data itself. Need to look into this.
+ *
+ * If new_start and new_size matches the existing start and size, only
+ * flags, label and type are changed. Any of flags, label and type can
+ * be set to NULL to signal there should be no change. Thus, this
+ * function serves two purposes. It can be used to both change offset and/or
+ * size and it can be used to change type and/or flags and/or label.
+ *
+ * See part_add_partition() for information about geometry_hps and
+ * geometry_spt and how it affects the resulting partition offset and
+ * size. This function gives one guarantee though: the resulting size
+ * will never be smaller than the requested size. This is useful for
+ * two-step operations by which a file system is first shrinked and
+ * then the partition table is updated.
+ *
+ * In order for changes to take effect, the caller needs to poke the
+ * OS kernel himself to make it reload the partition table. It is not
+ * automatically done by this function.
+ *
+ * NOTE: After calling this function you need to discard any partition
+ * table obtained with part_table_load_from_disk() since the in-memory
+ * data structure is not updated.
+ *
+ * Returns: TRUE if the operation was succesful, otherwise FALSE
+ */
+gboolean part_change_partition (char *device_file,
+ guint64 start,
+ guint64 new_start, guint64 new_size,
+ guint64 *out_start, guint64 *out_size,
+ char *type, char *label, char **flags,
+ int geometry_hps, int geometry_spt);
+
+/**
+ * part_del_partition:
+ * @device: name of device file for entire disk, e.g. /dev/sda
+ * @offset: offset of somewhere within the partition to delete, in bytes
+ *
+ * Deletes a partition. Just pass the offset of the partition. If you
+ * delete an extended partition all logical partitions will be deleted
+ * too.
+ *
+ * NOTE: After calling this function you need to discard any partition table
+ * obtained with part_table_load_from_disk() since the in-memory data structure
+ * is not updated.
+ *
+ * Returns: TRUE if the operation was succesful, otherwise FALSE
+ */
+gboolean part_del_partition (char *device, guint64 offset);
+
+
+#endif /* PARTUTIL_H */