Update inspection and example programs to use new hivex* APIs (RHBZ#852394).

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
This commit is contained in:
Richard W.M. Jones
2012-08-28 18:54:27 +01:00
parent 288cc74d77
commit b2378a81bb
12 changed files with 164 additions and 428 deletions

8
TODO
View File

@@ -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).

View File

@@ -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

View File

@@ -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);
root = guestfs_hivex_root (g);
if (root == -1)
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);
/* 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");
exit (EXIT_FAILURE);
}
root = hivex_root (h);
if (root == 0) {
perror ("hivex_root");
exit (EXIT_FAILURE);
}
/* Get ControlSetXXX\Services\Tcpip\Parameters\Interfaces. */
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

View File

@@ -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)

View File

@@ -34,10 +34,6 @@
#include <pcre.h>
#ifdef HAVE_HIVEX
#include <hivex.h>
#endif
#include "c-ctype.h"
#include "ignore-value.h"

View File

@@ -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

View File

@@ -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_Programs#Optional_values
*/
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 */

View File

@@ -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) */

View File

@@ -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) */

View File

@@ -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");
goto out;
}
/* Get the CurrentControlSet. */
errno = 0;
node = hivex_node_get_child (h, root, "Select");
node = guestfs_hivex_node_get_child (g, root, "Select");
if (node == -1)
goto out;
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)
{

View File

@@ -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) */

View File

@@ -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)
{