[Libguestfs] [PATCH 7/8] New APIs: guestfs_inspect_get_windows_software_hive and guestfs_inspect_get_windows_system_hive.

Richard W.M. Jones rjones at redhat.com
Sat Feb 18 08:05:34 UTC 2017


The inspection code already computed the paths of the software hive
(twice!) and the system hive, plus we also recompute the same paths
elsewhere, in virt-v2v for example.  Therefore it makes sense to store
the paths from the inspection code and make them available through two
new APIs.
---
 generator/actions.ml     |  34 +++++++++++++++
 lib/guestfs-internal.h   |   2 +
 lib/inspect-apps.c       |   8 +---
 lib/inspect-fs-windows.c | 110 ++++++++++++++++++++++++++++++-----------------
 lib/inspect.c            |  30 +++++++++++++
 5 files changed, 139 insertions(+), 45 deletions(-)

diff --git a/generator/actions.ml b/generator/actions.ml
index 67db08c..8a897a8 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -3756,6 +3756,40 @@ Searches all the entries associated with the given inode.
 For each entry, a C<tsk_dirent> structure is returned.
 See C<filesystem_walk> for more information about C<tsk_dirent> structures." };
 
+  { defaults with
+    name = "inspect_get_windows_software_hive"; added = (1, 35, 26);
+    style = RString "path", [Mountable "root"], [];
+    shortdesc = "get the path of the Windows software hive";
+    longdesc = "\
+This returns the path to the hive (binary Windows Registry file)
+corresponding to HKLM\\SOFTWARE.
+
+This call assumes that the guest is Windows and that the guest
+has a software hive file with the right name.  If this is not the
+case then an error is returned.  This call does not check that the
+hive is a valid Windows Registry hive.
+
+You can use C<guestfs_hivex_open> to read or write to the hive.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
+  { defaults with
+    name = "inspect_get_windows_system_hive"; added = (1, 35, 26);
+    style = RString "path", [Mountable "root"], [];
+    shortdesc = "get the path of the Windows system hive";
+    longdesc = "\
+This returns the path to the hive (binary Windows Registry file)
+corresponding to HKLM\\SYSTEM.
+
+This call assumes that the guest is Windows and that the guest
+has a system hive file with the right name.  If this is not the
+case then an error is returned.  This call does not check that the
+hive is a valid Windows Registry hive.
+
+You can use C<guestfs_hivex_open> to read or write to the hive.
+
+Please read L<guestfs(3)/INSPECTION> for more details." };
+
 ]
 
 (* daemon_functions are any functions which cause some action
diff --git a/lib/guestfs-internal.h b/lib/guestfs-internal.h
index 04d087b..7126b88 100644
--- a/lib/guestfs-internal.h
+++ b/lib/guestfs-internal.h
@@ -659,6 +659,8 @@ struct inspect_fs {
   char *arch;
   char *hostname;
   char *windows_systemroot;
+  char *windows_software_hive;
+  char *windows_system_hive;
   char *windows_current_control_set;
   char **drive_mappings;
   enum inspect_os_format format;
diff --git a/lib/inspect-apps.c b/lib/inspect-apps.c
index 0f2b505..1216c52 100644
--- a/lib/inspect-apps.c
+++ b/lib/inspect-apps.c
@@ -782,16 +782,12 @@ static void list_applications_windows_from_path (guestfs_h *g, struct guestfs_ap
 static struct guestfs_application2_list *
 list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
 {
-  CLEANUP_FREE char *software =
-    safe_asprintf (g, "%s/system32/config/software", fs->windows_systemroot);
-  CLEANUP_FREE char *software_path;
   struct guestfs_application2_list *ret = NULL;
 
-  software_path = guestfs_case_sensitive_path (g, software);
-  if (!software_path)
+  if (!fs->windows_software_hive)
     return NULL;
 
-  if (guestfs_hivex_open (g, software_path,
+  if (guestfs_hivex_open (g, fs->windows_software_hive,
                           GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose,
                           GUESTFS_HIVEX_OPEN_UNSAFE, 1,
                           -1) == -1)
diff --git a/lib/inspect-fs-windows.c b/lib/inspect-fs-windows.c
index fc0b42b..35f7cc8 100644
--- a/lib/inspect-fs-windows.c
+++ b/lib/inspect-fs-windows.c
@@ -55,6 +55,7 @@ COMPILE_REGEXP (re_boot_ini_os,
                 "^(multi|scsi)\\((\\d+)\\)disk\\((\\d+)\\)rdisk\\((\\d+)\\)partition\\((\\d+)\\)([^=]+)=", 0)
 
 static int check_windows_arch (guestfs_h *g, struct inspect_fs *fs);
+static int check_windows_registry_paths (guestfs_h *g, struct inspect_fs *fs);
 static int check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs);
 static int check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs);
 static char *map_registry_disk_blob (guestfs_h *g, const void *blob);
@@ -218,6 +219,10 @@ guestfs_int_check_windows_root (guestfs_h *g, struct inspect_fs *fs,
   if (check_windows_arch (g, fs) == -1)
     return -1;
 
+  /* Get system and software registry paths. */
+  if (check_windows_registry_paths (g, fs) == -1)
+    return -1;
+
   /* Product name and version. */
   if (check_windows_software_registry (g, fs) == -1)
     return -1;
@@ -249,6 +254,58 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs)
   return 0;
 }
 
+static int
+check_windows_registry_paths (guestfs_h *g, struct inspect_fs *fs)
+{
+  int r;
+  CLEANUP_FREE char *software = NULL, *system = NULL;
+
+  if (!fs->windows_systemroot)
+    return 0;
+
+  software = safe_asprintf (g, "%s/system32/config/software",
+                            fs->windows_systemroot);
+
+  fs->windows_software_hive = guestfs_case_sensitive_path (g, software);
+  if (!fs->windows_software_hive)
+    return -1;
+
+  r = guestfs_is_file (g, fs->windows_software_hive);
+  if (r == -1) {
+    free (fs->windows_software_hive);
+    fs->windows_software_hive = NULL;
+    return -1;
+  }
+
+  if (r == 0) {                 /* doesn't exist, or not a file */
+    free (fs->windows_software_hive);
+    fs->windows_software_hive = NULL;
+    /*FALLTHROUGH*/
+  }
+
+  system = safe_asprintf (g, "%s/system32/config/system",
+                          fs->windows_systemroot);
+
+  fs->windows_system_hive = guestfs_case_sensitive_path (g, system);
+  if (!fs->windows_system_hive)
+    return -1;
+
+  r = guestfs_is_file (g, fs->windows_system_hive);
+  if (r == -1) {
+    free (fs->windows_system_hive);
+    fs->windows_system_hive = NULL;
+    return -1;
+  }
+
+  if (r == 0) {                 /* doesn't exist, or not a file */
+    free (fs->windows_system_hive);
+    fs->windows_system_hive = NULL;
+    /*FALLTHROUGH*/
+  }
+
+  return 0;
+}
+
 /* At the moment, pull just the ProductName and version numbers from
  * the registry.  In future there is a case for making many more
  * registry fields available to callers.
@@ -257,24 +314,6 @@ static int
 check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
 {
   int ret = -1;
-  int r;
-
-  CLEANUP_FREE char *software =
-    safe_asprintf (g, "%s/system32/config/software", fs->windows_systemroot);
-
-  CLEANUP_FREE char *software_path = guestfs_case_sensitive_path (g, software);
-  if (!software_path)
-    return -1;
-
-  r = guestfs_is_file (g, software_path);
-  if (r == -1)
-    return -1;
-  /* If the software hive doesn't exist, just accept that we cannot
-   * find product_name etc.
-   */
-  if (r == 0)
-    return 0;
-
   int64_t node;
   const char *hivepath[] =
     { "Microsoft", "Windows NT", "CurrentVersion" };
@@ -282,7 +321,13 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
   CLEANUP_FREE_HIVEX_VALUE_LIST struct guestfs_hivex_value_list *values = NULL;
   bool ignore_currentversion = false;
 
-  if (guestfs_hivex_open (g, software_path,
+  /* If the software hive doesn't exist, just accept that we cannot
+   * find product_name etc.
+   */
+  if (!fs->windows_software_hive)
+    return 0;
+
+  if (guestfs_hivex_open (g, fs->windows_software_hive,
                           GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose,
                           GUESTFS_HIVEX_OPEN_UNSAFE, 1,
                           -1) == -1)
@@ -375,26 +420,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
 static int
 check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
 {
-  int r;
   static const char gpt_prefix[] = "DMIO:ID:";
-
-  CLEANUP_FREE char *system =
-    safe_asprintf (g, "%s/system32/config/system",
-                   fs->windows_systemroot);
-
-  CLEANUP_FREE char *system_path = guestfs_case_sensitive_path (g, system);
-  if (!system_path)
-    return -1;
-
-  r = guestfs_is_file (g, system_path);
-  if (r == -1)
-    return -1;
-  /* If the system hive doesn't exist, just accept that we cannot
-   * find hostname etc.
-   */
-  if (r == 0)
-    return 0;
-
   int ret = -1;
   int64_t root, node, value;
   CLEANUP_FREE_HIVEX_VALUE_LIST struct guestfs_hivex_value_list *values = NULL;
@@ -406,7 +432,13 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
   const char *hivepath[] =
     { NULL /* current control set */, "Services", "Tcpip", "Parameters" };
 
-  if (guestfs_hivex_open (g, system_path,
+  /* If the system hive doesn't exist, just accept that we cannot
+   * find hostname etc.
+   */
+  if (!fs->windows_system_hive)
+    return 0;
+
+  if (guestfs_hivex_open (g, fs->windows_system_hive,
                           GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose,
                           GUESTFS_HIVEX_OPEN_UNSAFE, 1,
                           -1) == -1)
diff --git a/lib/inspect.c b/lib/inspect.c
index da80e47..24ee6fe 100644
--- a/lib/inspect.c
+++ b/lib/inspect.c
@@ -432,6 +432,36 @@ guestfs_impl_inspect_get_windows_systemroot (guestfs_h *g, const char *root)
 }
 
 char *
+guestfs_impl_inspect_get_windows_software_hive (guestfs_h *g, const char *root)
+{
+  struct inspect_fs *fs = guestfs_int_search_for_root (g, root);
+  if (!fs)
+    return NULL;
+
+  if (!fs->windows_software_hive) {
+    error (g, _("not a Windows guest, or software hive not found"));
+    return NULL;
+  }
+
+  return safe_strdup (g, fs->windows_software_hive);
+}
+
+char *
+guestfs_impl_inspect_get_windows_system_hive (guestfs_h *g, const char *root)
+{
+  struct inspect_fs *fs = guestfs_int_search_for_root (g, root);
+  if (!fs)
+    return NULL;
+
+  if (!fs->windows_system_hive) {
+    error (g, _("not a Windows guest, or system hive not found"));
+    return NULL;
+  }
+
+  return safe_strdup (g, fs->windows_system_hive);
+}
+
+char *
 guestfs_impl_inspect_get_windows_current_control_set (guestfs_h *g,
 						      const char *root)
 {
-- 
2.10.2




More information about the Libguestfs mailing list