From: "Richard W.M. Jones" <rjones(a)redhat.com>
I tested this by comparing the output of virt-inspector over Windows
guests before and after the change, which was identical:
$ md5sum `ls -1 /tmp/*.before /tmp/*.after`
c292d6629b5a761eccb4a279754399b4 /tmp/Win2003.after
c292d6629b5a761eccb4a279754399b4 /tmp/Win2003.before
eb1e1ff29208a9ee46e9c100dfec26b2 /tmp/Win2012.after
eb1e1ff29208a9ee46e9c100dfec26b2 /tmp/Win2012.before
d060a95d7ffe5dce6c4e66feb80c2837 /tmp/Win7x32.after
d060a95d7ffe5dce6c4e66feb80c2837 /tmp/Win7x32.before
8914eee70ac4f8a0317659e09e00dcdc /tmp/Win7x32Dynamic.after
8914eee70ac4f8a0317659e09e00dcdc /tmp/Win7x32Dynamic.before
a2dcdfc0f9d64054640875aa791889e0 /tmp/Win7x32TwoDisks.after
a2dcdfc0f9d64054640875aa791889e0 /tmp/Win7x32TwoDisks.before
5ed49568a5147dce7517c99de41ebf2e /tmp/Win8previewx64.after
5ed49568a5147dce7517c99de41ebf2e /tmp/Win8previewx64.before
fdfc7d272b79a665ae3313ae1ae30660 /tmp/WinXP.after
fdfc7d272b79a665ae3313ae1ae30660 /tmp/WinXP.before
3c705444be664f1316b21c5d8d3cb0be /tmp/WinXPRecConsole.after
3c705444be664f1316b21c5d8d3cb0be /tmp/WinXPRecConsole.before
---
TODO | 8 ++
examples/Makefile.am | 4 +-
examples/virt-dhcp-address.c | 97 ++++++++------------
src/Makefile.am | 4 +-
src/dbdump.c | 4 -
src/guestfs-internal.h | 8 --
src/inspect-apps.c | 92 ++++++-------------
src/inspect-fs-cd.c | 8 --
src/inspect-fs-unix.c | 8 --
src/inspect-fs-windows.c | 206 ++++++++++++++++++------------------------
src/inspect-fs.c | 8 --
src/inspect.c | 143 -----------------------------
12 files changed, 163 insertions(+), 427 deletions(-)
diff --git a/TODO b/TODO
index 7561c3d..026c94a 100644
--- a/TODO
+++ b/TODO
@@ -570,3 +570,11 @@ mke2fs
Add a mke2fs API call allowing full configuration of filesystems.
Then fix tests/bigdirs/test-big-dirs.pl to use it.
+
+hivex
+-----
+
+Add more of hivex to the API, especially for writing.
+
+Reimplement virt-win-reg to use this API. (This is difficult because
+the Perl libraries underneath access the hivex API directly).
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 35bf765..c79a1db 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -95,10 +95,8 @@ virt_dhcp_address_SOURCES = virt-dhcp-address.c
virt_dhcp_address_CFLAGS = \
-DGUESTFS_WARN_DEPRECATED=1 \
-I$(top_srcdir)/src -I$(top_builddir)/src \
- $(WARN_CFLAGS) $(WERROR_CFLAGS) \
- $(HIVEX_CFLAGS)
+ $(WARN_CFLAGS) $(WERROR_CFLAGS)
virt_dhcp_address_LDADD = \
- $(HIVEX_LIBS) \
$(top_builddir)/src/libguestfs.la
endif
diff --git a/examples/virt-dhcp-address.c b/examples/virt-dhcp-address.c
index c6f25c6..c4e3647 100644
--- a/examples/virt-dhcp-address.c
+++ b/examples/virt-dhcp-address.c
@@ -17,7 +17,6 @@
#include <assert.h>
#include <guestfs.h>
-#include <hivex.h>
static int compare_keys_len (const void *p1, const void *p2);
static size_t count_strings (char *const *argv);
@@ -198,11 +197,8 @@ static void
print_dhcp_address_windows (guestfs_h *g, char *root_fs)
{
char *system_path;
- char tmpfile[] = "/tmp/systemXXXXXX";
- int fd, err;
- hive_h *h;
- hive_node_h root, node, *nodes;
- hive_value_h value;
+ int64_t root, node, value;
+ struct guestfs_hivex_node_list *nodes;
char *controlset;
size_t i;
char *p;
@@ -215,71 +211,52 @@ print_dhcp_address_windows (guestfs_h *g, char *root_fs)
exit (EXIT_FAILURE);
}
- fd = mkstemp (tmpfile);
- if (fd == -1) {
- perror ("mkstemp");
- exit (EXIT_FAILURE);
- }
-
- /* Download the SYSTEM hive. */
- if (guestfs_download (g, system_path, tmpfile) == -1)
+ /* Open the hive to parse it. Note that before libguestfs 1.19.35
+ * you had to download the file and parse it using hivex(3). Since
+ * libguestfs 1.19.35, parts of the hivex(3) API are now exposed
+ * through libguestfs, and that is what we'll use here because it is
+ * more convenient and avoids having to download the hive.
+ */
+ if (guestfs_hivex_open (g, system_path, -1) == -1)
exit (EXIT_FAILURE);
free (system_path);
- controlset = guestfs_inspect_get_windows_current_control_set (g, root_fs);
- if (controlset == NULL)
- exit (EXIT_FAILURE);
-
- /* Open the hive to parse it. */
- h = hivex_open (tmpfile, 0);
- err = errno;
- close (fd);
- unlink (tmpfile);
-
- if (h == NULL) {
- errno = err;
- perror ("hivex_open");
+ root = guestfs_hivex_root (g);
+ if (root == -1)
exit (EXIT_FAILURE);
- }
-
- root = hivex_root (h);
- if (root == 0) {
- perror ("hivex_root");
- exit (EXIT_FAILURE);
- }
/* Get ControlSetXXX\Services\Tcpip\Parameters\Interfaces. */
+ controlset = guestfs_inspect_get_windows_current_control_set (g, root_fs);
+ if (controlset == NULL)
+ exit (EXIT_FAILURE);
const char *path[] = { controlset, "Services", "Tcpip",
"Parameters",
"Interfaces" };
node = root;
- errno = 0;
- for (i = 0; node != 0 && i < sizeof path / sizeof path[0]; ++i)
- node = hivex_node_get_child (h, node, path[i]);
+ for (i = 0; node > 0 && i < sizeof path / sizeof path[0]; ++i)
+ node = guestfs_hivex_node_get_child (g, node, path[i]);
+
+ if (node == -1)
+ exit (EXIT_FAILURE);
if (node == 0) {
- if (errno != 0)
- perror ("hivex_node_get_child");
- else
- fprintf (stderr, "virt-dhcp-address:
HKLM\\System\\%s\\Services\\Tcpip\\Parameters\\Interfaces not found.", controlset);
+ fprintf (stderr, "virt-dhcp-address:
HKLM\\System\\%s\\Services\\Tcpip\\Parameters\\Interfaces not found.", controlset);
exit (EXIT_FAILURE);
}
+ free (controlset);
+
/* Look for a node under here which has a "DhcpIPAddress" entry in it. */
- nodes = hivex_node_children (h, node);
- if (nodes == NULL) {
- perror ("hivex_node_children");
+ nodes = guestfs_hivex_node_children (g, node);
+ if (nodes == NULL)
exit (EXIT_FAILURE);
- }
value = 0;
- for (i = 0; value == 0 && nodes[i] != 0; ++i) {
- errno = 0;
- value = hivex_node_get_value (h, nodes[i], "DhcpIPAddress");
- if (value == 0 && errno != 0) {
- perror ("hivex_node_get_value");
+ for (i = 0; value == 0 && i < nodes->len; ++i) {
+ value = guestfs_hivex_node_get_value (g, nodes->val[i].hivex_node_h,
+ "DhcpIPAddress");
+ if (value == -1)
exit (EXIT_FAILURE);
- }
}
if (value == 0) {
@@ -287,21 +264,21 @@ print_dhcp_address_windows (guestfs_h *g, char *root_fs)
exit (EXIT_FAILURE);
}
- /* Get the string and use hivex's auto-conversion to convert it to UTF-8
- * for output.
+ guestfs_free_hivex_node_list (nodes);
+
+ /* Get the string and use libguestfs's auto-conversion to convert it
+ * to UTF-8 for output.
*/
- p = hivex_value_string (h, value);
- if (!p) {
- perror ("hivex_value_string");
+ p = guestfs_hivex_value_utf8 (g, value);
+ if (!p)
exit (EXIT_FAILURE);
- }
printf ("%s\n", p);
- /* Close the hive handle. */
- hivex_close (h);
+ free (p);
- free (controlset);
+ /* Close the hive handle. */
+ guestfs_hivex_close (g);
}
static int
diff --git a/src/Makefile.am b/src/Makefile.am
index 5d3639a..5e79662 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -148,7 +148,7 @@ libguestfs_la_SOURCES = \
libguestfs.syms
libguestfs_la_LIBADD = \
- $(HIVEX_LIBS) $(PCRE_LIBS) $(MAGIC_LIBS) \
+ $(PCRE_LIBS) $(MAGIC_LIBS) \
$(LIBVIRT_LIBS) $(LIBXML2_LIBS) \
../gnulib/lib/libgnu.la \
$(GETADDRINFO_LIB) \
@@ -167,7 +167,7 @@ libguestfs_la_LIBADD += liberrnostring.la libprotocol.la
libguestfs_la_CFLAGS = \
-DGUESTFS_DEFAULT_PATH='"$(libdir)/guestfs"' \
-DGUESTFS_WARN_DEPRECATED=1 \
- $(HIVEX_CFLAGS) $(PCRE_CFLAGS) \
+ $(PCRE_CFLAGS) \
$(LIBVIRT_CFLAGS) $(LIBXML2_CFLAGS) \
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
$(GCC_VISIBILITY_HIDDEN)
diff --git a/src/dbdump.c b/src/dbdump.c
index ac20b67..0bdd9f4 100644
--- a/src/dbdump.c
+++ b/src/dbdump.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h
index 2355f13..b2f7518 100644
--- a/src/guestfs-internal.h
+++ b/src/guestfs-internal.h
@@ -107,11 +107,6 @@
#define MAX_SMALL_FILE_SIZE (2 * 1000 * 1000)
#define MAX_AUGEAS_FILE_SIZE (100 * 1000)
-/* Maximum Windows Registry hive that we will download to /tmp. Some
- * registries can be legitimately very large.
- */
-#define MAX_REGISTRY_SIZE (100 * 1000 * 1000)
-
/* Maximum RPM or dpkg database we will download to /tmp. RPM
* 'Packages' database can get very large: 70 MB is roughly the
* standard size for a new Fedora install, and after lots of package
@@ -474,8 +469,6 @@ extern char *guestfs___download_to_tmp (guestfs_h *g, struct
inspect_fs *fs, con
extern char *guestfs___case_sensitive_path_silently (guestfs_h *g, const char *);
extern struct inspect_fs *guestfs___search_for_root (guestfs_h *g, const char *root);
extern char *guestfs___drive_name (size_t index, char *ret);
-
-#if defined(HAVE_HIVEX)
extern int guestfs___check_for_filesystem_on (guestfs_h *g, const char *device, int
is_block, int is_partnum);
extern int guestfs___parse_unsigned_int (guestfs_h *g, const char *str);
extern int guestfs___parse_unsigned_int_ignore_trailing (guestfs_h *g, const char *str);
@@ -491,7 +484,6 @@ extern int guestfs___check_netbsd_root (guestfs_h *g, struct
inspect_fs *fs);
extern int guestfs___check_hurd_root (guestfs_h *g, struct inspect_fs *fs);
extern int guestfs___has_windows_systemroot (guestfs_h *g);
extern int guestfs___check_windows_root (guestfs_h *g, struct inspect_fs *fs);
-#endif
#define error(g,...) guestfs_error_errno((g),0,__VA_ARGS__)
#define perrorf guestfs_perrorf
diff --git a/src/inspect-apps.c b/src/inspect-apps.c
index 1b0b5a5..06a02e2 100644
--- a/src/inspect-apps.c
+++ b/src/inspect-apps.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -47,8 +43,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
#ifdef DB_DUMP
static struct guestfs_application_list *list_applications_rpm (guestfs_h *g, struct
inspect_fs *fs);
#endif
@@ -414,7 +408,7 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs)
return ret;
}
-static void list_applications_windows_from_path (guestfs_h *g, hive_h *h, struct
guestfs_application_list *apps, const char **path, size_t path_len);
+static void list_applications_windows_from_path (guestfs_h *g, struct
guestfs_application_list *apps, const char **path, size_t path_len);
static struct guestfs_application_list *
list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
@@ -431,24 +425,12 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
return NULL;
}
- char *software_hive = NULL;
struct guestfs_application_list *ret = NULL;
- hive_h *h = NULL;
- software_hive = guestfs___download_to_tmp (g, fs, software_path, "software",
- MAX_REGISTRY_SIZE);
- if (software_hive == NULL)
+ if (guestfs_hivex_open (g, software_path,
+ GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose, -1) == -1)
goto out;
- free (software_path);
- software_path = NULL;
-
- h = hivex_open (software_hive, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
- if (h == NULL) {
- perrorf (g, "hivex_open");
- goto out;
- }
-
/* Allocate apps list. */
ret = safe_malloc (g, sizeof *ret);
ret->len = 0;
@@ -457,7 +439,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
/* Ordinary native applications. */
const char *hivepath[] =
{ "Microsoft", "Windows", "CurrentVersion",
"Uninstall" };
- list_applications_windows_from_path (g, h, ret, hivepath,
+ list_applications_windows_from_path (g, ret, hivepath,
sizeof hivepath / sizeof hivepath[0]);
/* 32-bit emulated Windows apps running on the WOW64 emulator.
@@ -465,35 +447,34 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs)
*/
const char *hivepath2[] =
{ "WOW6432node", "Microsoft", "Windows",
"CurrentVersion", "Uninstall" };
- list_applications_windows_from_path (g, h, ret, hivepath2,
+ list_applications_windows_from_path (g, ret, hivepath2,
sizeof hivepath2 / sizeof hivepath2[0]);
out:
- if (h) hivex_close (h);
+ guestfs_hivex_close (g);
free (software_path);
- free (software_hive);
return ret;
}
static void
-list_applications_windows_from_path (guestfs_h *g, hive_h *h,
+list_applications_windows_from_path (guestfs_h *g,
struct guestfs_application_list *apps,
const char **path, size_t path_len)
{
- hive_node_h *children = NULL;
- hive_node_h node;
+ struct guestfs_hivex_node_list *children = NULL;
+ int64_t node;
size_t i;
- node = hivex_root (h);
+ node = guestfs_hivex_root (g);
for (i = 0; node != 0 && i < path_len; ++i)
- node = hivex_node_get_child (h, node, path[i]);
+ node = guestfs_hivex_node_get_child (g, node, path[i]);
if (node == 0)
return;
- children = hivex_node_children (h, node);
+ children = guestfs_hivex_node_children (g, node);
if (children == NULL)
return;
@@ -501,8 +482,9 @@ list_applications_windows_from_path (guestfs_h *g, hive_h *h,
* See also:
*
http://nsis.sourceforge.net/Add_uninstall_information_to_Add/Remove_Progr...
*/
- for (i = 0; children[i] != 0; ++i) {
- hive_value_h value;
+ for (i = 0; i < children->len; ++i) {
+ int64_t child = children->val[i].hivex_node_h;
+ int64_t value;
char *name = NULL;
char *display_name = NULL;
char *version = NULL;
@@ -514,29 +496,29 @@ list_applications_windows_from_path (guestfs_h *g, hive_h *h,
/* Use the node name as a proxy for the package name in Linux. The
* display name is not language-independent, so it cannot be used.
*/
- name = hivex_node_name (h, children[i]);
+ name = guestfs_hivex_node_name (g, child);
if (name == NULL)
continue;
- value = hivex_node_get_value (h, children[i], "DisplayName");
+ value = guestfs_hivex_node_get_value (g, child, "DisplayName");
if (value) {
- display_name = hivex_value_string (h, value);
+ display_name = guestfs_hivex_value_utf8 (g, value);
if (display_name) {
- value = hivex_node_get_value (h, children[i], "DisplayVersion");
+ value = guestfs_hivex_node_get_value (g, child, "DisplayVersion");
if (value)
- version = hivex_value_string (h, value);
- value = hivex_node_get_value (h, children[i], "InstallLocation");
+ version = guestfs_hivex_value_utf8 (g, value);
+ value = guestfs_hivex_node_get_value (g, child, "InstallLocation");
if (value)
- install_path = hivex_value_string (h, value);
- value = hivex_node_get_value (h, children[i], "Publisher");
+ install_path = guestfs_hivex_value_utf8 (g, value);
+ value = guestfs_hivex_node_get_value (g, child, "Publisher");
if (value)
- publisher = hivex_value_string (h, value);
- value = hivex_node_get_value (h, children[i], "URLInfoAbout");
+ publisher = guestfs_hivex_value_utf8 (g, value);
+ value = guestfs_hivex_node_get_value (g, child, "URLInfoAbout");
if (value)
- url = hivex_value_string (h, value);
- value = hivex_node_get_value (h, children[i], "Comments");
+ url = guestfs_hivex_value_utf8 (g, value);
+ value = guestfs_hivex_node_get_value (g, child, "Comments");
if (value)
- comments = hivex_value_string (h, value);
+ comments = guestfs_hivex_value_utf8 (g, value);
add_application (g, apps, name, display_name, 0,
version ? : "",
@@ -557,7 +539,7 @@ list_applications_windows_from_path (guestfs_h *g, hive_h *h,
free (comments);
}
- free (children);
+ guestfs_free_hivex_node_list (children);
}
static void
@@ -606,19 +588,3 @@ sort_applications (struct guestfs_application_list *apps)
qsort (apps->val, apps->len, sizeof (struct guestfs_application),
compare_applications);
}
-
-#else /* no hivex at compile time */
-
-/* XXX These functions should be in an optgroup. */
-
-#define NOT_IMPL(r) \
- error (g, _("inspection API not available since this version of libguestfs was
compiled without the hivex library")); \
- return r
-
-struct guestfs_application_list *
-guestfs__inspect_list_applications (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-#endif /* no hivex at compile time */
diff --git a/src/inspect-fs-cd.c b/src/inspect-fs-cd.c
index 6fec8a5..614f9a4 100644
--- a/src/inspect-fs-cd.c
+++ b/src/inspect-fs-cd.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -47,8 +43,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
/* Debian/Ubuntu install disks are easy ...
*
* These files are added by the debian-cd program, and it is worth
@@ -484,5 +478,3 @@ guestfs___check_installer_root (guestfs_h *g, struct inspect_fs *fs)
return 0;
}
-
-#endif /* defined(HAVE_HIVEX) */
diff --git a/src/inspect-fs-unix.c b/src/inspect-fs-unix.c
index 433ef5c..c00e69b 100644
--- a/src/inspect-fs-unix.c
+++ b/src/inspect-fs-unix.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -49,8 +45,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
/* Compile all the regular expressions once when the shared library is
* loaded. PCRE is thread safe so we're supposedly OK here if
* multiple threads call into the libguestfs API functions below
@@ -1536,5 +1530,3 @@ is_partition (guestfs_h *g, const char *partition)
return 1;
}
-
-#endif /* defined(HAVE_HIVEX) */
diff --git a/src/inspect-fs-windows.c b/src/inspect-fs-windows.c
index cd2bd6c..e972e97 100644
--- a/src/inspect-fs-windows.c
+++ b/src/inspect-fs-windows.c
@@ -35,10 +35,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -48,8 +44,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
/* Compile all the regular expressions once when the shared library is
* loaded. PCRE is thread safe so we're supposedly OK here if
* multiple threads call into the libguestfs API functions below
@@ -215,6 +209,8 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs)
static int
check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
{
+ int ret = -1;
+
size_t len = strlen (fs->windows_systemroot) + 64;
char software[len];
snprintf (software, len, "%s/system32/config/software",
@@ -227,60 +223,46 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs
*fs)
*/
return 0;
- char *software_hive = NULL;
- int ret = -1;
- hive_h *h = NULL;
- hive_value_h *values = NULL;
-
- software_hive = guestfs___download_to_tmp (g, fs, software_path, "software",
- MAX_REGISTRY_SIZE);
- if (software_hive == NULL)
+ if (guestfs_hivex_open (g, software_path,
+ GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose, -1) == -1)
goto out;
- h = hivex_open (software_hive, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
- if (h == NULL) {
- perrorf (g, "hivex_open");
- goto out;
- }
-
- hive_node_h node = hivex_root (h);
+ int64_t node = guestfs_hivex_root (g);
const char *hivepath[] =
{ "Microsoft", "Windows NT", "CurrentVersion" };
size_t i;
- for (i = 0;
- node != 0 && i < sizeof hivepath / sizeof hivepath[0];
- ++i) {
- node = hivex_node_get_child (h, node, hivepath[i]);
- }
+ for (i = 0; node > 0 && i < sizeof hivepath / sizeof hivepath[0]; ++i)
+ node = guestfs_hivex_node_get_child (g, node, hivepath[i]);
+
+ if (node == -1)
+ goto out;
if (node == 0) {
perrorf (g, "hivex: cannot locate HKLM\\SOFTWARE\\Microsoft\\Windows
NT\\CurrentVersion");
goto out;
}
- values = hivex_node_values (h, node);
+ struct guestfs_hivex_value_list *values = NULL;
+ values = guestfs_hivex_node_values (g, node);
- for (i = 0; values[i] != 0; ++i) {
- char *key = hivex_value_key (h, values[i]);
- if (key == NULL) {
- perrorf (g, "hivex_value_key");
- goto out;
- }
+ for (i = 0; i < values->len; ++i) {
+ int64_t value = values->val[i].hivex_value_h;
+ char *key = guestfs_hivex_value_key (g, value);
+ if (key == NULL)
+ goto out2;
if (STRCASEEQ (key, "ProductName")) {
- fs->product_name = hivex_value_string (h, values[i]);
+ fs->product_name = guestfs_hivex_value_utf8 (g, value);
if (!fs->product_name) {
- perrorf (g, "hivex_value_string");
free (key);
- goto out;
+ goto out2;
}
}
else if (STRCASEEQ (key, "CurrentVersion")) {
- char *version = hivex_value_string (h, values[i]);
+ char *version = guestfs_hivex_value_utf8 (g, value);
if (!version) {
- perrorf (g, "hivex_value_string");
free (key);
- goto out;
+ goto out2;
}
char *major, *minor;
if (match2 (g, version, re_windows_version, &major, &minor)) {
@@ -290,25 +272,24 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs
*fs)
free (minor);
free (key);
free (version);
- goto out;
+ goto out2;
}
fs->minor_version = guestfs___parse_unsigned_int (g, minor);
free (minor);
if (fs->minor_version == -1) {
free (key);
free (version);
- goto out;
+ goto out2;
}
}
free (version);
}
else if (STRCASEEQ (key, "InstallationType")) {
- fs->product_variant = hivex_value_string (h, values[i]);
+ fs->product_variant = guestfs_hivex_value_utf8 (g, value);
if (!fs->product_variant) {
- perrorf (g, "hivex_value_string");
free (key);
- goto out;
+ goto out2;
}
}
@@ -317,11 +298,11 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs
*fs)
ret = 0;
+ out2:
+ guestfs_free_hivex_value_list (values);
out:
- if (h) hivex_close (h);
- free (values);
+ guestfs_hivex_close (g);
free (software_path);
- free (software_hive);
return ret;
}
@@ -341,110 +322,94 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs
*fs)
*/
return 0;
- char *system_hive = NULL;
int ret = -1;
- hive_h *h = NULL;
- hive_node_h root, node;
- hive_value_h value, *values = NULL;
+ int64_t root, node, value;
+ struct guestfs_hivex_value_list *values = NULL;
int32_t dword;
size_t i, count;
+ char *buf = NULL;
+ size_t buflen;
- system_hive =
- guestfs___download_to_tmp (g, fs, system_path, "system",
- MAX_REGISTRY_SIZE);
- if (system_hive == NULL)
+ if (guestfs_hivex_open (g, system_path,
+ GUESTFS_HIVEX_OPEN_VERBOSE, g->verbose, -1) == -1)
goto out;
- h = hivex_open (system_hive, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
- if (h == NULL) {
- perrorf (g, "hivex_open");
+ root = guestfs_hivex_root (g);
+ if (root == 0)
goto out;
- }
- root = hivex_root (h);
- if (root == 0) {
- perrorf (g, "hivex_root");
+ /* Get the CurrentControlSet. */
+ node = guestfs_hivex_node_get_child (g, root, "Select");
+ if (node == -1)
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");
+ error (g, "hivex: could not locate HKLM\\SYSTEM\\Select");
goto out;
}
- errno = 0;
- value = hivex_node_get_value (h, node, "Current");
+ value = guestfs_hivex_node_get_value (g, node, "Current");
+ if (value == -1)
+ goto out;
+
if (value == 0) {
- if (errno != 0)
- perrorf (g, "hivex_node_get_value");
- else
- error (g, "hivex: HKLM\\System\\Select Default entry not found.");
+ error (g, "hivex: HKLM\\System\\Select Default entry not found");
goto out;
}
/* XXX Should check the type. */
- dword = hivex_value_dword (h, value);
+ buf = guestfs_hivex_value_value (g, value, &buflen);
+ if (buflen != 4) {
+ error (g, "hivex: HKLM\\System\\Select\\Current expected to be DWORD");
+ goto out;
+ }
+ dword = le32toh (*(int32_t *)buf);
fs->windows_current_control_set = safe_asprintf (g, "ControlSet%03d",
dword);
/* Get the drive mappings.
* This page explains the contents of HKLM\System\MountedDevices:
*
http://www.goodells.net/multiboot/partsigs.shtml
*/
- errno = 0;
- node = hivex_node_get_child (h, root, "MountedDevices");
- if (node == 0) {
- if (errno == 0)
- /* Not found: skip getting drive letter mappings (RHBZ#803664). */
- goto skip_drive_letter_mappings;
- /* errno != 0, so it's some other error from hivex */
- perrorf (g, "hivex_node_get_child");
+ node = guestfs_hivex_node_get_child (g, root, "MountedDevices");
+ if (node == -1)
goto out;
- }
- values = hivex_node_values (h, node);
+ if (node == 0)
+ /* Not found: skip getting drive letter mappings (RHBZ#803664). */
+ goto skip_drive_letter_mappings;
+
+ values = guestfs_hivex_node_values (g, node);
/* Count how many DOS drive letter mappings there are. This doesn't
* ignore removable devices, so it overestimates, but that doesn't
* matter because it just means we'll allocate a few bytes extra.
*/
- for (i = count = 0; values[i] != 0; ++i) {
- char *key = hivex_value_key (h, values[i]);
- if (key == NULL) {
- perrorf (g, "hivex_value_key");
+ for (i = count = 0; i < values->len; ++i) {
+ char *key = guestfs_hivex_value_key (g, values->val[i].hivex_value_h);
+ if (key == NULL)
goto out;
- }
if (STRCASEEQLEN (key, "\\DosDevices\\", 12) &&
c_isalpha (key[12]) && key[13] == ':')
count++;
free (key);
}
- fs->drive_mappings = calloc (2*count + 1, sizeof (char *));
- if (fs->drive_mappings == NULL) {
- perrorf (g, "calloc");
- goto out;
- }
+ fs->drive_mappings = safe_calloc (g, 2*count + 1, sizeof (char *));
- for (i = count = 0; values[i] != 0; ++i) {
- char *key = hivex_value_key (h, values[i]);
- if (key == NULL) {
- perrorf (g, "hivex_value_key");
+ for (i = count = 0; i < values->len; ++i) {
+ int64_t v = values->val[i].hivex_value_h;
+ char *key = guestfs_hivex_value_key (g, v);
+ if (key == NULL)
goto out;
- }
if (STRCASEEQLEN (key, "\\DosDevices\\", 12) &&
c_isalpha (key[12]) && key[13] == ':') {
/* Get the binary value. Is it a fixed disk? */
char *blob, *device;
size_t len;
- hive_type type;
+ int64_t type;
- blob = hivex_value_value (h, values[i], &type, &len);
+ type = guestfs_hivex_value_type (g, v);
+ blob = guestfs_hivex_value_value (g, v, &len);
if (blob != NULL && type == 3 && len == 12) {
/* Try to map the blob to a known disk and partition. */
device = map_registry_disk_blob (g, blob);
@@ -463,31 +428,34 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
const char *hivepath[] =
{ fs->windows_current_control_set, "Services", "Tcpip",
"Parameters" };
for (node = root, i = 0;
- node != 0 && i < sizeof hivepath / sizeof hivepath[0];
+ node > 0 && i < sizeof hivepath / sizeof hivepath[0];
++i) {
- node = hivex_node_get_child (h, node, hivepath[i]);
+ node = guestfs_hivex_node_get_child (g, node, hivepath[i]);
}
+ if (node == -1)
+ goto out;
+
if (node == 0) {
perrorf (g, "hivex: cannot locate
HKLM\\SYSTEM\\%s\\Services\\Tcpip\\Parameters",
fs->windows_current_control_set);
goto out;
}
- free (values);
- values = hivex_node_values (h, node);
+ guestfs_free_hivex_value_list (values);
+ values = guestfs_hivex_node_values (g, node);
+ if (values == NULL)
+ goto out;
- for (i = 0; values[i] != 0; ++i) {
- char *key = hivex_value_key (h, values[i]);
- if (key == NULL) {
- perrorf (g, "hivex_value_key");
+ for (i = 0; i < values->len; ++i) {
+ int64_t v = values->val[i].hivex_value_h;
+ char *key = guestfs_hivex_value_key (g, v);
+ if (key == NULL)
goto out;
- }
if (STRCASEEQ (key, "Hostname")) {
- fs->hostname = hivex_value_string (h, values[i]);
+ fs->hostname = guestfs_hivex_value_utf8 (g, v);
if (!fs->hostname) {
- perrorf (g, "hivex_value_string");
free (key);
goto out;
}
@@ -500,10 +468,10 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
ret = 0;
out:
- if (h) hivex_close (h);
- free (values);
+ guestfs_hivex_close (g);
+ if (values) guestfs_free_hivex_value_list (values);
free (system_path);
- free (system_hive);
+ free (buf);
return ret;
}
@@ -577,8 +545,6 @@ map_registry_disk_blob (guestfs_h *g, const char *blob)
return ret;
}
-#endif /* defined(HAVE_HIVEX) */
-
char *
guestfs___case_sensitive_path_silently (guestfs_h *g, const char *path)
{
diff --git a/src/inspect-fs.c b/src/inspect-fs.c
index 33aff35..456a546 100644
--- a/src/inspect-fs.c
+++ b/src/inspect-fs.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -47,8 +43,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
/* Compile all the regular expressions once when the shared library is
* loaded. PCRE is thread safe so we're supposedly OK here if
* multiple threads call into the libguestfs API functions below
@@ -603,5 +597,3 @@ guestfs___first_egrep_of_file (guestfs_h *g, const char *filename,
return 1;
}
-
-#endif /* defined(HAVE_HIVEX) */
diff --git a/src/inspect.c b/src/inspect.c
index 44826c3..8cba6b1 100644
--- a/src/inspect.c
+++ b/src/inspect.c
@@ -34,10 +34,6 @@
#include <pcre.h>
-#ifdef HAVE_HIVEX
-#include <hivex.h>
-#endif
-
#include "c-ctype.h"
#include "ignore-value.h"
#include "xstrtol.h"
@@ -47,8 +43,6 @@
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_HIVEX)
-
/* The main inspection code. */
char **
guestfs__inspect_os (guestfs_h *g)
@@ -540,143 +534,6 @@ guestfs__inspect_get_hostname (guestfs_h *g, const char *root)
return safe_strdup (g, fs->hostname ? : "unknown");
}
-#else /* no hivex at compile time */
-
-/* XXX These functions should be in an optgroup. */
-
-#define NOT_IMPL(r) \
- guestfs_error_errno (g, ENOTSUP, _("inspection API not available since this
version of libguestfs was compiled without the hivex library")); \
- return r
-
-char **
-guestfs__inspect_os (guestfs_h *g)
-{
- NOT_IMPL(NULL);
-}
-
-char **
-guestfs__inspect_get_roots (guestfs_h *g)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_type (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_arch (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_distro (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-int
-guestfs__inspect_get_major_version (guestfs_h *g, const char *root)
-{
- NOT_IMPL(-1);
-}
-
-int
-guestfs__inspect_get_minor_version (guestfs_h *g, const char *root)
-{
- NOT_IMPL(-1);
-}
-
-char *
-guestfs__inspect_get_product_name (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_product_variant (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-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)
-{
- NOT_IMPL(NULL);
-}
-
-char **
-guestfs__inspect_get_filesystems (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char **
-guestfs__inspect_get_drive_mappings (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_package_format (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_package_management (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_hostname (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-char *
-guestfs__inspect_get_format (guestfs_h *g, const char *root)
-{
- NOT_IMPL(NULL);
-}
-
-int
-guestfs__inspect_is_live (guestfs_h *g, const char *root)
-{
- NOT_IMPL(-1);
-}
-
-int
-guestfs__inspect_is_netinst (guestfs_h *g, const char *root)
-{
- NOT_IMPL(-1);
-}
-
-int
-guestfs__inspect_is_multipart (guestfs_h *g, const char *root)
-{
- NOT_IMPL(-1);
-}
-
-#endif /* no hivex at compile time */
-
void
guestfs___free_inspect_info (guestfs_h *g)
{
--
1.7.10.4