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