X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Finspect_fs_windows.c;h=0fd7965a7cdb98e45546a97672a626e814b2ea1f;hb=6088d6167df49a52e67ae2eb0957e47d0545dceb;hp=9a2e1fb08e2afb0b9035fd9743e7846ad31dbb50;hpb=8e6e547af32116accfe4aa9cae36d3cd073f1c66;p=libguestfs.git diff --git a/src/inspect_fs_windows.c b/src/inspect_fs_windows.c index 9a2e1fb..0fd7965 100644 --- a/src/inspect_fs_windows.c +++ b/src/inspect_fs_windows.c @@ -91,23 +91,77 @@ static char *map_registry_disk_blob (guestfs_h *g, const char *blob); * 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; @@ -159,11 +213,6 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs) 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", @@ -176,15 +225,17 @@ 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; - 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; @@ -268,6 +319,7 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs) if (h) hivex_close (h); free (values); free (software_path); + free (software_hive); return ret; } @@ -275,11 +327,6 @@ check_windows_software_registry (guestfs_h *g, struct inspect_fs *fs) 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", @@ -292,6 +339,7 @@ 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; @@ -299,11 +347,13 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) 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; @@ -449,6 +499,7 @@ check_windows_system_registry (guestfs_h *g, struct inspect_fs *fs) if (h) hivex_close (h); free (values); free (system_path); + free (system_hive); return ret; }