-(* This is the common function implementing Get_volumes. Test if a
- * particular partition contains a mountable filesystem. We do this
- * simply by trying to mount it. If it does, get the rest of the
- * information for the volume, and call the callback.
- *)
-and if_mountable_vol g cb dev =
- try
- with_mount_ro g dev (
- fun () ->
- let vol_type = G.vfs_type g dev in
- let vol_label = G.vfs_label g dev in
- let vol_uuid = G.vfs_uuid g dev in
- let vol_statvfs = G.statvfs g "/" in
- let vol = {
- vol_device = dev; vol_type = vol_type; vol_label = vol_label;
- vol_uuid = vol_uuid; vol_statvfs = vol_statvfs
- } in
- GtkThread.async cb vol
- )
- with G.Error msg ->
- debug "is_mountable: %s: not mountable because: %s" dev msg
-
-(* guestfs_lstatlist has a "hidden" limit of the protocol message size.
- * Call this function, but split the list of names into chunks.
- *)
-and lstatlist_wrapper g dir = function
- | [] -> []
- | names ->
- let names', names = List.take 1000 names, List.drop 1000 names in
- let xs = G.lstatlist g dir (Array.of_list names') in
- let xs = Array.to_list xs in
- xs @ lstatlist_wrapper g dir names
-
-(* Same as above for guestfs_readlinklist. *)
-and readlinklist_wrapper g dir = function
- | [] -> []
- | names ->
- let names', names = List.take 1000 names, List.drop 1000 names in
- let xs = G.readlinklist g dir (Array.of_list names') in
- let xs = Array.to_list xs in
- xs @ readlinklist_wrapper g dir names
+ (* Create most of the OS object that we're going to return. We
+ * have to pass this to with_mount_ro below which is why we need
+ * to partially create it here.
+ *)
+ let os = {
+ insp_root = root;
+ insp_arch = g#inspect_get_arch root;
+ insp_distro = g#inspect_get_distro root;
+ insp_filesystems = g#inspect_get_filesystems root;
+ insp_hostname = g#inspect_get_hostname root;
+ insp_major_version = g#inspect_get_major_version root;
+ insp_minor_version = g#inspect_get_minor_version root;
+ insp_mountpoints = g#inspect_get_mountpoints root;
+ insp_package_format = g#inspect_get_package_format root;
+ insp_package_management = g#inspect_get_package_management root;
+ insp_product_name = g#inspect_get_product_name root;
+ insp_type = typ;
+ insp_windows_systemroot = windows_systemroot;
+ insp_winreg_DEFAULT = None; (* incomplete, see below *)
+ insp_winreg_SAM = None;
+ insp_winreg_SECURITY = None;
+ insp_winreg_SOFTWARE = None;
+ insp_winreg_SYSTEM = None;
+ } in
+
+ (* We need to mount the root in order to look for Registry hives. *)
+ let winreg_DEFAULT, winreg_SAM, winreg_SECURITY, winreg_SOFTWARE,
+ winreg_SYSTEM =
+ match windows_systemroot with
+ | None -> None, None, None, None, None
+ | Some sysroot ->
+ with_mount_ro g (OS os) (
+ fun () ->
+ let check_for_hive filename =
+ let path =
+ sprintf "%s/system32/config/%s" sysroot filename in
+ try Some (g#case_sensitive_path path)
+ with G.Error _ -> None
+ in
+ check_for_hive "default",
+ check_for_hive "sam",
+ check_for_hive "security",
+ check_for_hive "software",
+ check_for_hive "system"
+ ) in
+
+ (* Fill in the remaining struct fields. *)
+ let os = { os with
+ insp_winreg_DEFAULT = winreg_DEFAULT;
+ insp_winreg_SAM = winreg_SAM;
+ insp_winreg_SECURITY = winreg_SECURITY;
+ insp_winreg_SOFTWARE = winreg_SOFTWARE;
+ insp_winreg_SYSTEM = winreg_SYSTEM
+ } in
+ os
+ ) roots in
+
+ let data = {
+ insp_all_filesystems = fses;
+ insp_oses = oses;
+ } in
+
+ status "Finished opening disk";
+ callback_if_not_discarded cb data