#include <errno.h>
#include <endian.h>
-#ifdef HAVE_PCRE
#include <pcre.h>
-#endif
#ifdef HAVE_HIVEX
#include <hivex.h>
#include "guestfs-internal-actions.h"
#include "guestfs_protocol.h"
-#if defined(HAVE_PCRE) && defined(HAVE_HIVEX)
+#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
* essentially didn't do anything for modern Windows guests.
* Therefore I've omitted all that code.
*/
+
+/* Try to find Windows systemroot using some common locations.
+ *
+ * Notes:
+ *
+ * (1) We check for some directories inside to see if it is a real
+ * systemroot, and not just a directory that happens to have the same
+ * name.
+ *
+ * (2) If a Windows guest has multiple disks and applications are
+ * installed on those other disks, then those other disks will contain
+ * "/Program Files" and "/System Volume Information". Those would
+ * *not* be Windows root disks. (RHBZ#674130)
+ */
+static const char *systemroots[] =
+ { "/windows", "/winnt", "/win32", "/win", NULL };
+
+int
+guestfs___has_windows_systemroot (guestfs_h *g)
+{
+ size_t i;
+ char *systemroot, *p;
+ char path[256];
+
+ for (i = 0; i < sizeof systemroots / sizeof systemroots[0]; ++i) {
+ systemroot = guestfs___case_sensitive_path_silently (g, systemroots[i]);
+ if (!systemroot)
+ continue;
+
+ snprintf (path, sizeof path, "%s/system32", systemroot);
+ if (!guestfs___is_dir_nocase (g, path)) {
+ free (systemroot);
+ continue;
+ }
+
+ snprintf (path, sizeof path, "%s/system32/config", systemroot);
+ if (!guestfs___is_dir_nocase (g, path)) {
+ free (systemroot);
+ continue;
+ }
+
+ snprintf (path, sizeof path, "%s/system32/cmd.exe", systemroot);
+ if (!guestfs___is_file_nocase (g, path)) {
+ free (systemroot);
+ continue;
+ }
+
+ free (systemroot);
+
+ return (int)i;
+ }
+
+ return -1; /* not found */
+}
+
int
guestfs___check_windows_root (guestfs_h *g, struct inspect_fs *fs)
{
+ int i;
+ char *systemroot;
+
fs->type = OS_TYPE_WINDOWS;
fs->distro = OS_DISTRO_WINDOWS;
- /* Try to find Windows systemroot using some common locations. */
- const char *systemroots[] =
- { "/windows", "/winnt", "/win32", "/win" };
- size_t i;
- char *systemroot = NULL;
- for (i = 0;
- systemroot == NULL && i < sizeof systemroots / sizeof systemroots[0];
- ++i) {
- systemroot = guestfs___case_sensitive_path_silently (g, systemroots[i]);
+ i = guestfs___has_windows_systemroot (g);
+ if (i == -1) {
+ error (g, "check_windows_root: has_windows_systemroot unexpectedly returned -1");
+ return -1;
}
+ systemroot = guestfs___case_sensitive_path_silently (g, systemroots[i]);
if (!systemroot) {
error (g, _("cannot resolve Windows %%SYSTEMROOT%%"));
return -1;
static int
check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs)
{
- const char *basename = "software";
- char tmpdir_basename[strlen (g->tmpdir) + strlen (basename) + 2];
- snprintf (tmpdir_basename, sizeof tmpdir_basename, "%s/%s",
- g->tmpdir, basename);
-
size_t len = strlen (fs->windows_systemroot) + 64;
char software[len];
snprintf (software, len, "%s/system32/config/software",
*/
return 0;
+ char *software_hive = NULL;
int ret = -1;
hive_h *h = NULL;
hive_value_h *values = NULL;
- if (guestfs___download_to_tmp (g, software_path, basename,
- MAX_REGISTRY_SIZE) == -1)
+ software_hive = guestfs___download_to_tmp (g, fs, software_path, "software",
+ MAX_REGISTRY_SIZE);
+ if (software_hive == NULL)
goto out;
- h = hivex_open (tmpdir_basename, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
+ h = hivex_open (software_hive, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
if (h == NULL) {
perrorf (g, "hivex_open");
goto out;
if (h) hivex_close (h);
free (values);
free (software_path);
+ free (software_hive);
return ret;
}
static int
check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs)
{
- const char *basename = "system";
- char tmpdir_basename[strlen (g->tmpdir) + strlen (basename) + 2];
- snprintf (tmpdir_basename, sizeof tmpdir_basename, "%s/%s",
- g->tmpdir, basename);
-
size_t len = strlen (fs->windows_systemroot) + 64;
char system[len];
snprintf (system, len, "%s/system32/config/system",
*/
return 0;
+ char *system_hive = NULL;
int ret = -1;
hive_h *h = NULL;
hive_node_h root, node;
int32_t dword;
size_t i, count;
- if (guestfs___download_to_tmp (g, system_path, basename,
- MAX_REGISTRY_SIZE) == -1)
+ system_hive =
+ guestfs___download_to_tmp (g, fs, system_path, "system",
+ MAX_REGISTRY_SIZE);
+ if (system_hive == NULL)
goto out;
- h = hivex_open (tmpdir_basename, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
+ h = hivex_open (system_hive, g->verbose ? HIVEX_OPEN_VERBOSE : 0);
if (h == NULL) {
perrorf (g, "hivex_open");
goto out;
if (h) hivex_close (h);
free (values);
free (system_path);
+ free (system_hive);
return ret;
}
return ret;
}
-#endif /* defined(HAVE_PCRE) && defined(HAVE_HIVEX) */
+#endif /* defined(HAVE_HIVEX) */