From 64bc4495031a1942472038db7aee0bf3b746949d Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 31 Mar 2011 15:51:00 +0100 Subject: [PATCH] inspect: Detect 32 bit applications running on WOW64 emulator (RHBZ#692545). These applications are located along a different Registry path. See http://support.microsoft.com/kb/896459 for all the details. Thanks Jinxin Zheng for finding the bug and the solution. --- images/guest-aux/windows-software | Bin 12288 -> 12288 bytes images/guest-aux/windows-software.reg | 16 ++++++ inspector/example-windows.xml | 7 +++ src/inspect.c | 98 +++++++++++++++++++--------------- 4 files changed, 79 insertions(+), 42 deletions(-) diff --git a/images/guest-aux/windows-software b/images/guest-aux/windows-software index e9358860b11053be0b52ce0222e9a14aa986afc8..d936ea884f4caec85dcd0a977b417366346a0b1d 100755 GIT binary patch delta 641 zcmZut&o2W}5T4zXSfVzH&@OpYHzE>=HccHQLV^$+_u5J~Df&aSIME&)ghaw~agaDV zN_z1RNL<_-2XPW7oLu?lwHpp*^LFN&`R1E>uac}JZxiOAPIY_hBl?ChVqaY?x%Qi$GG4Tvonlr!e&SQ|oT)rrTV6Zt~gRi!tGWivVnblQ(p zKEj}<aRHHQ7Lh0mne_Xx{ zb+`Ya-Grnbo@=Qgb@dfF;0^o?JQ>rH+u=E5Aw;xsI$)?dK}MeO!?5{~5SDxo_bgsC zYEAGZw^)k7dwblWwYGF=@Dn5~qHCNQj_9v9)sWxaY@;|}(vmB~wic7i_N4Sjn)L_h z+jb|{>O6ISqJH^2GF@&V9=re{UY^fvA(wOWr6NLQ8HhWyN)F^>6r~BuQ-RXtlAv`e z;=e~3ply}mx}Y^wO7Je_Xos?t0&>wK5N+Y(t`v7nAy|iC5rh;< PWB4BUxV>K0^a1?`kDQ?* delta 49 zcmZojXh_&#A;87R009jGlUHeKP0kTeVdUC8QQ$rQC:\Program Files\Red Hat\test3 Red Hat Inc. + + test4 + Test4 is not real software + 1.2.6 + Red Hat Inc. + WOW6432node is where 32 bit emulated apps are installed on 64 bit Windows + diff --git a/src/inspect.c b/src/inspect.c index 3a8ede6..238e6e5 100644 --- a/src/inspect.c +++ b/src/inspect.c @@ -2460,15 +2460,17 @@ list_applications_deb (guestfs_h *g, struct inspect_fs *fs) return ret; } -/* XXX We already download the SOFTWARE hive when doing general - * inspection. We could avoid this second download of the same file - * by caching these entries in the handle. - */ +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 struct guestfs_application_list * list_applications_windows (guestfs_h *g, struct inspect_fs *fs) { TMP_TEMPLATE_ON_STACK (software_local); + /* XXX We already download the SOFTWARE hive when doing general + * inspection. We could avoid this second download of the same file + * by caching these entries in the handle. + */ size_t len = strlen (fs->windows_systemroot) + 64; char software[len]; snprintf (software, len, "%s/system32/config/software", @@ -2481,45 +2483,72 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) */ return 0; - struct guestfs_application_list *apps = NULL, *ret = NULL; + struct guestfs_application_list *ret = NULL; hive_h *h = NULL; - hive_node_h *children = NULL; if (download_to_tmp (g, software_path, software_local, MAX_REGISTRY_SIZE) == -1) goto out; + free (software_path); + software_path = NULL; + h = hivex_open (software_local, g->verbose ? HIVEX_OPEN_VERBOSE : 0); if (h == NULL) { perrorf (g, "hivex_open"); goto out; } - hive_node_h node = hivex_root (h); + /* Allocate apps list. */ + ret = safe_malloc (g, sizeof *ret); + ret->len = 0; + ret->val = NULL; + + /* Ordinary native applications. */ const char *hivepath[] = { "Microsoft", "Windows", "CurrentVersion", "Uninstall" }; + list_applications_windows_from_path (g, h, ret, hivepath, + sizeof hivepath / sizeof hivepath[0]); + + /* 32-bit emulated Windows apps running on the WOW64 emulator. + * http://support.microsoft.com/kb/896459 (RHBZ#692545). + */ + const char *hivepath2[] = + { "WOW6432node", "Microsoft", "Windows", "CurrentVersion", "Uninstall" }; + list_applications_windows_from_path (g, h, ret, hivepath2, + sizeof hivepath2 / sizeof hivepath2[0]); + + out: + if (h) hivex_close (h); + free (software_path); + + /* Delete the temporary file. */ + unlink (software_local); +#undef software_local_len + + 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) +{ + hive_node_h *children = NULL; + hive_node_h node; size_t i; - for (i = 0; - node != 0 && i < sizeof hivepath / sizeof hivepath[0]; - ++i) { - node = hivex_node_get_child (h, node, hivepath[i]); - } - if (node == 0) { - perrorf (g, "hivex: cannot locate HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall"); - goto out; - } + node = hivex_root (h); - children = hivex_node_children (h, node); - if (children == NULL) { - perrorf (g, "hivex_node_children"); - goto out; - } + for (i = 0; node != 0 && i < path_len; ++i) + node = hivex_node_get_child (h, node, path[i]); - /* Allocate 'apps' list. */ - apps = safe_malloc (g, sizeof *apps); - apps->len = 0; - apps->val = NULL; + if (node == 0) + return; + + children = hivex_node_children (h, node); + if (children == NULL) + return; /* Consider any child node that has a DisplayName key. * See also: @@ -2539,10 +2568,8 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) * display name is not language-independent, so it cannot be used. */ name = hivex_node_name (h, children[i]); - if (name == NULL) { - perrorf (g, "hivex_node_get_name"); - goto out; - } + if (name == NULL) + continue; value = hivex_node_get_value (h, children[i], "DisplayName"); if (value) { @@ -2583,20 +2610,7 @@ list_applications_windows (guestfs_h *g, struct inspect_fs *fs) free (comments); } - ret = apps; - - out: - if (ret == NULL && apps != NULL) - guestfs_free_application_list (apps); - if (h) hivex_close (h); free (children); - free (software_path); - - /* Free up the temporary file. */ - unlink (software_local); -#undef software_local_len - - return ret; } static void -- 1.8.3.1