>From 2b38ae9db560523c1b417e5888295cb1016ee930 Mon Sep 17 00:00:00 2001 From: Richard W.M. Jones Date: Wed, 27 Oct 2010 16:47:33 +0100 Subject: [PATCH 2/4] New API: inspect-get-windows-systemroot to get systemroot. We are already using heuristics in the C inspection code to determine the Windows %SYSTEMROOT% directory. This change just exposes this information through the API. --- generator/generator_actions.ml | 16 ++++++++++++ src/guestfs-internal.h | 1 + src/inspect.c | 53 ++++++++++++++++++++++----------------- 3 files changed, 47 insertions(+), 23 deletions(-) diff --git a/generator/generator_actions.ml b/generator/generator_actions.ml index 63ece15..086584c 100644 --- a/generator/generator_actions.ml +++ b/generator/generator_actions.ml @@ -1002,6 +1002,22 @@ deprecated C call (q.v.) =back"); + ("inspect_get_windows_systemroot", (RString "systemroot", [Device "root"], []), -1, [], + [], + "get Windows systemroot of inspected operating system", + "\ +This function should only be called with a root device string +as returned by C. + +This returns the Windows systemroot of the inspected guest. +The systemroot is a directory path such as C. + +This call assumes that the guest is Windows and that the +systemroot could be determined by inspection. If this is not +the case then an error is returned. + +Please read L for more details."); + ] (* daemon_functions are any functions which cause some action diff --git a/src/guestfs-internal.h b/src/guestfs-internal.h index a42375f..6fc9412 100644 --- a/src/guestfs-internal.h +++ b/src/guestfs-internal.h @@ -180,6 +180,7 @@ struct inspect_fs { int major_version; int minor_version; char *arch; + char *windows_systemroot; struct inspect_fstab_entry *fstab; size_t nr_fstab; }; diff --git a/src/inspect.c b/src/inspect.c index 992573a..5bd332f 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -456,6 +456,7 @@ guestfs___free_inspect_info (guestfs_h *g) free (g->fses[i].device); free (g->fses[i].product_name); free (g->fses[i].arch); + free (g->fses[i].windows_systemroot); size_t j; for (j = 0; j < g->fses[i].nr_fstab; ++j) { free (g->fses[i].fstab[j].device); @@ -502,10 +503,8 @@ static int check_filesystem (guestfs_h *g, const char *device); static int check_linux_root (guestfs_h *g, struct inspect_fs *fs); static int check_fstab (guestfs_h *g, struct inspect_fs *fs); static int check_windows_root (guestfs_h *g, struct inspect_fs *fs); -static int check_windows_arch (guestfs_h *g, struct inspect_fs *fs, - const char *systemroot); -static int check_windows_registry (guestfs_h *g, struct inspect_fs *fs, - const char *systemroot); +static int check_windows_arch (guestfs_h *g, struct inspect_fs *fs); +static int check_windows_registry (guestfs_h *g, struct inspect_fs *fs); static char *resolve_windows_path_silently (guestfs_h *g, const char *); static int extend_fses (guestfs_h *g); static int parse_unsigned_int (guestfs_h *g, const char *str); @@ -962,34 +961,27 @@ check_windows_root (guestfs_h *g, struct inspect_fs *fs) return -1; } - /* XXX There is a case for exposing systemroot and many variables - * from the registry through the libguestfs API. - */ - if (g->verbose) fprintf (stderr, "windows %%SYSTEMROOT%% = %s", systemroot); - if (check_windows_arch (g, fs, systemroot) == -1) { - free (systemroot); + /* Freed by guestfs___free_inspect_info. */ + fs->windows_systemroot = systemroot; + + if (check_windows_arch (g, fs) == -1) return -1; - } - if (check_windows_registry (g, fs, systemroot) == -1) { - free (systemroot); + if (check_windows_registry (g, fs) == -1) return -1; - } - free (systemroot); return 0; } static int -check_windows_arch (guestfs_h *g, struct inspect_fs *fs, - const char *systemroot) +check_windows_arch (guestfs_h *g, struct inspect_fs *fs) { - size_t len = strlen (systemroot) + 32; + size_t len = strlen (fs->windows_systemroot) + 32; char cmd_exe[len]; - snprintf (cmd_exe, len, "%s/system32/cmd.exe", systemroot); + snprintf (cmd_exe, len, "%s/system32/cmd.exe", fs->windows_systemroot); char *cmd_exe_path = resolve_windows_path_silently (g, cmd_exe); if (!cmd_exe_path) @@ -1009,8 +1001,7 @@ check_windows_arch (guestfs_h *g, struct inspect_fs *fs, * registry fields available to callers. */ static int -check_windows_registry (guestfs_h *g, struct inspect_fs *fs, - const char *systemroot) +check_windows_registry (guestfs_h *g, struct inspect_fs *fs) { TMP_TEMPLATE_ON_STACK (dir); #define dir_len (strlen (dir)) @@ -1019,9 +1010,10 @@ check_windows_registry (guestfs_h *g, struct inspect_fs *fs, #define cmd_len (dir_len + 16) char cmd[cmd_len]; - size_t len = strlen (systemroot) + 64; + size_t len = strlen (fs->windows_systemroot) + 64; char software[len]; - snprintf (software, len, "%s/system32/config/software", systemroot); + snprintf (software, len, "%s/system32/config/software", + fs->windows_systemroot); char *software_path = resolve_windows_path_silently (g, software); if (!software_path) @@ -1275,6 +1267,21 @@ guestfs__inspect_get_product_name (guestfs_h *g, const char *root) return safe_strdup (g, fs->product_name ? : "unknown"); } +char * +guestfs__inspect_get_windows_systemroot (guestfs_h *g, const char *root) +{ + struct inspect_fs *fs = search_for_root (g, root); + if (!fs) + return NULL; + + if (!fs->windows_systemroot) { + error (g, _("not a Windows guest, or systemroot could not be determined")); + return NULL; + } + + return safe_strdup (g, fs->windows_systemroot); +} + char ** guestfs__inspect_get_mountpoints (guestfs_h *g, const char *root) { -- 1.7.3.1