From 1eed7ca9a9e3b416f9108cf21eb2710bb560092d Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Tue, 15 Mar 2022 21:56:01 +0100 Subject: [PATCH] [RAPPS] Fix uninstalling applications - 'WindowsInstaller' setups do not fill the UninstallString and ModifyPath with the needed info, so manually calculate those. - Fix the case where REG_EXPAND_SZ is used instead of REG_SZ - Take NoModify into account --- base/applications/rapps/installed.cpp | 66 +++++++++++++++++++++++++-- base/applications/rapps/misc.cpp | 2 +- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/base/applications/rapps/installed.cpp b/base/applications/rapps/installed.cpp index fed899e9448..3528c2c3aaa 100644 --- a/base/applications/rapps/installed.cpp +++ b/base/applications/rapps/installed.cpp @@ -71,8 +71,40 @@ void CInstalledApplicationInfo::EnsureDetailsLoaded() } GetApplicationRegString(L"InstallLocation", szInstallLocation); GetApplicationRegString(L"InstallSource", szInstallSource); - GetApplicationRegString(L"UninstallString", szUninstallString); - GetApplicationRegString(L"ModifyPath",szModifyPath); + DWORD dwWindowsInstaller = 0; + if (GetApplicationRegDword(L"WindowsInstaller", &dwWindowsInstaller) && dwWindowsInstaller) + { + // MSI has the same info in Uninstall / modify, so manually build it + szUninstallString.Format(L"msiexec /x%s", m_szKeyName.GetString()); + } + else + { + GetApplicationRegString(L"UninstallString", szUninstallString); + } + DWORD dwNoModify = 0; + if (!GetApplicationRegDword(L"NoModify", &dwNoModify)) + { + CStringW Tmp; + if (GetApplicationRegString(L"NoModify", Tmp)) + { + dwNoModify = Tmp.GetLength() > 0 ? (Tmp[0] == '1') : 0; + } + else + { + dwNoModify = 0; + } + } + if (!dwNoModify) + { + if (dwWindowsInstaller) + { + szModifyPath.Format(L"msiexec /i%s", m_szKeyName.GetString()); + } + else + { + GetApplicationRegString(L"ModifyPath", szModifyPath); + } + } CloseHandle(m_hSubKey); m_hSubKey = NULL; @@ -84,8 +116,13 @@ BOOL CInstalledApplicationInfo::GetApplicationRegString(LPCWSTR lpKeyName, ATL:: DWORD dwAllocated = 0, dwSize, dwType; // retrieve the size of value first. - if (RegQueryValueExW(m_hSubKey, lpKeyName, NULL, &dwType, NULL, &dwAllocated) != ERROR_SUCCESS || - dwType != REG_SZ) + if (RegQueryValueExW(m_hSubKey, lpKeyName, NULL, &dwType, NULL, &dwAllocated) != ERROR_SUCCESS) + { + String.Empty(); + return FALSE; + } + + if (dwType != REG_SZ && dwType != REG_EXPAND_SZ) { String.Empty(); return FALSE; @@ -106,6 +143,27 @@ BOOL CInstalledApplicationInfo::GetApplicationRegString(LPCWSTR lpKeyName, ATL:: return FALSE; } + if (dwType == REG_EXPAND_SZ) + { + CStringW Tmp; + + DWORD dwLen = ExpandEnvironmentStringsW(String, NULL, 0); + if (dwLen > 0) + { + BOOL bSuccess = ExpandEnvironmentStringsW(String, Tmp.GetBuffer(dwLen), dwLen) == dwLen; + Tmp.ReleaseBuffer(dwLen - 1); + if (bSuccess) + { + String = Tmp; + } + else + { + String.Empty(); + return FALSE; + } + } + } + return TRUE; } diff --git a/base/applications/rapps/misc.cpp b/base/applications/rapps/misc.cpp index 80bd875008a..da350ad1210 100644 --- a/base/applications/rapps/misc.cpp +++ b/base/applications/rapps/misc.cpp @@ -247,7 +247,7 @@ BOOL GetInstalledVersion_WowUser(ATL::CStringW* szVersionResult, BOOL bHasSucceded = FALSE; ATL::CRegKey key; ATL::CStringW szVersion; - ATL::CStringW szPath = ATL::CStringW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%ls") + szRegName; + ATL::CStringW szPath = ATL::CStringW(L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\") + szRegName; if (key.Open(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, szPath.GetString(),