diff options
author | Richard W.M. Jones <rjones@redhat.com> | 2011-04-05 12:44:34 +0100 |
---|---|---|
committer | Richard W.M. Jones <rjones@redhat.com> | 2011-04-05 20:01:15 +0100 |
commit | 9e7c6a548353bde925c16434711bcc6208038d83 (patch) | |
tree | b1b46b05e7319a36c38813a3b1eb15eb277ed948 /src | |
parent | 9b945cfa781a0f25c3b81239e2fcddceeede6e44 (diff) | |
download | libguestfs-9e7c6a548353bde925c16434711bcc6208038d83.tar.gz libguestfs-9e7c6a548353bde925c16434711bcc6208038d83.tar.xz libguestfs-9e7c6a548353bde925c16434711bcc6208038d83.zip |
New API: inspect-get-windows-current-control-set
This returns the actual registry key corresponding to
CurrentControlSet (eg. it might be "ControlSet001").
Previously the inspection code was hard-coding ControlSet001. Now we
use the correct control set, and also make it available to callers
through the API.
This commit also updates the virt-dhcp-address example so it uses this
new API.
virt-inspector displays the current control set when available.
Diffstat (limited to 'src')
-rw-r--r-- | src/guestfs-internal.h | 1 | ||||
-rw-r--r-- | src/inspect.c | 74 |
2 files changed, 66 insertions, 9 deletions
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index 3a63f2e3..b29fa577 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -251,6 +251,7 @@ struct inspect_fs { char *arch; char *hostname; char *windows_systemroot; + char *windows_current_control_set; enum inspect_os_format format; int is_live_disk; int is_netinst_disk; diff --git a/src/inspect.c b/src/inspect.c index a4f0f987..154207b9 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -25,6 +25,7 @@ #include <unistd.h> #include <string.h> #include <sys/stat.h> +#include <errno.h> #ifdef HAVE_PCRE #include <pcre.h> @@ -1612,7 +1613,10 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) int ret = -1; hive_h *h = NULL; - hive_value_h *values = NULL; + hive_node_h root, node; + hive_value_h value, *values = NULL; + int32_t dword; + size_t i; if (download_to_tmp (g, system_path, system_local, MAX_REGISTRY_SIZE) == -1) goto out; @@ -1623,21 +1627,49 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) goto out; } - hive_node_h node = hivex_root (h); - /* XXX Don't hard-code ControlSet001. The current control set would - * be another good thing to expose up through the inspection API. - */ + root = hivex_root (h); + if (root == 0) { + perrorf (g, "hivex_root"); + goto out; + } + + /* Get the CurrentControlSet. */ + errno = 0; + node = hivex_node_get_child (h, root, "Select"); + if (node == 0) { + if (errno != 0) + perrorf (g, "hivex_node_get_child"); + else + error (g, "hivex: could not locate HKLM\\SYSTEM\\Select"); + goto out; + } + + errno = 0; + value = hivex_node_get_value (h, node, "Current"); + if (value == 0) { + if (errno != 0) + perrorf (g, "hivex_node_get_value"); + else + error (g, "hivex: HKLM\\System\\Select Default entry not found."); + goto out; + } + + /* XXX Should check the type. */ + dword = hivex_value_dword (h, value); + fs->windows_current_control_set = safe_asprintf (g, "ControlSet%03d", dword); + + /* Get the hostname. */ const char *hivepath[] = - { "ControlSet001", "Services", "Tcpip", "Parameters" }; - size_t i; - for (i = 0; + { fs->windows_current_control_set, "Services", "Tcpip", "Parameters" }; + for (node = root, i = 0; node != 0 && i < sizeof hivepath / sizeof hivepath[0]; ++i) { node = hivex_node_get_child (h, node, hivepath[i]); } if (node == 0) { - perrorf (g, "hivex: cannot locate HKLM\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters"); + perrorf (g, "hivex: cannot locate HKLM\\SYSTEM\\%s\\Services\\Tcpip\\Parameters", + fs->windows_current_control_set); goto out; } @@ -2011,6 +2043,22 @@ guestfs__inspect_get_windows_systemroot (guestfs_h *g, const char *root) } char * +guestfs__inspect_get_windows_current_control_set (guestfs_h *g, + const char *root) +{ + struct inspect_fs *fs = search_for_root (g, root); + if (!fs) + return NULL; + + if (!fs->windows_current_control_set) { + error (g, _("not a Windows guest, or CurrentControlSet could not be determined")); + return NULL; + } + + return safe_strdup (g, fs->windows_current_control_set); +} + +char * guestfs__inspect_get_format (guestfs_h *g, const char *root) { struct inspect_fs *fs = search_for_root (g, root); @@ -2905,6 +2953,13 @@ guestfs__inspect_get_windows_systemroot (guestfs_h *g, const char *root) NOT_IMPL(NULL); } +char * +guestfs__inspect_get_windows_current_control_set (guestfs_h *g, + const char *root) +{ + NOT_IMPL(NULL); +} + char ** guestfs__inspect_get_mountpoints (guestfs_h *g, const char *root) { @@ -2978,6 +3033,7 @@ guestfs___free_inspect_info (guestfs_h *g) free (g->fses[i].arch); free (g->fses[i].hostname); free (g->fses[i].windows_systemroot); + free (g->fses[i].windows_current_control_set); size_t j; for (j = 0; j < g->fses[i].nr_fstab; ++j) { free (g->fses[i].fstab[j].device); |