mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-26 19:33:31 +00:00
[RAPPS] Don't display duplicate uninstall entries when WoW64 keys are unsupported (#8253)
This only happens on 64-bit because 32-bit was being conservative.
This commit is contained in:
@@ -18,6 +18,48 @@ static HKEY g_RootKeyEnum[3] = {HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_LOCA
|
||||
static REGSAM g_RegSamEnum[3] = {0, KEY_WOW64_32KEY, KEY_WOW64_64KEY};
|
||||
#define UNINSTALL_SUBKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
|
||||
|
||||
static inline HKEY
|
||||
GetRootKeyInfo(UINT Index, REGSAM &RegSam)
|
||||
{
|
||||
C_ASSERT(_countof(g_RootKeyEnum) == _countof(g_RegSamEnum));
|
||||
if (Index < _countof(g_RootKeyEnum))
|
||||
{
|
||||
RegSam = g_RegSamEnum[Index];
|
||||
return g_RootKeyEnum[Index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class CEnumInstalledRootKey
|
||||
{
|
||||
// HKCU + HKLM (Native) + HKLM (WoW64)
|
||||
// Note that HKEY_CURRENT_USER\Software does not have a redirect
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64
|
||||
|
||||
UINT m_Count;
|
||||
UINT m_Index = 0;
|
||||
|
||||
public:
|
||||
CEnumInstalledRootKey()
|
||||
{
|
||||
// We don't want to display duplicate entries on systems without WoW64 keys support.
|
||||
// When ROS starts supporting the WOW REGSAM flags,
|
||||
// this code can be changed back to IsSystem64Bit() ? 3 : 2.
|
||||
m_Count = 2 + !IsSameRegKey(HKEY_LOCAL_MACHINE, UNINSTALL_SUBKEY, KEY_WOW64_64KEY,
|
||||
UNINSTALL_SUBKEY, KEY_WOW64_32KEY);
|
||||
}
|
||||
|
||||
HKEY GetNext(REGSAM &RegSam)
|
||||
{
|
||||
return m_Index < m_Count ? GetRootKeyInfo(m_Index++, RegSam) : NULL;
|
||||
}
|
||||
|
||||
UINT GetKeyIndex() const
|
||||
{
|
||||
return m_Index;
|
||||
}
|
||||
};
|
||||
|
||||
static VOID
|
||||
ClearList(CAtlList<CAppInfo *> &list)
|
||||
{
|
||||
@@ -150,30 +192,6 @@ CAppDB::UpdateAvailable()
|
||||
EnumerateFiles();
|
||||
}
|
||||
|
||||
static inline HKEY
|
||||
GetRootKeyInfo(UINT Index, REGSAM &RegSam)
|
||||
{
|
||||
C_ASSERT(_countof(g_RootKeyEnum) == _countof(g_RegSamEnum));
|
||||
if (Index < _countof(g_RootKeyEnum))
|
||||
{
|
||||
RegSam = g_RegSamEnum[Index];
|
||||
return g_RootKeyEnum[Index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HKEY
|
||||
CAppDB::EnumInstalledRootKey(UINT Index, REGSAM &RegSam)
|
||||
{
|
||||
// Loop for through all combinations.
|
||||
// Note that HKEY_CURRENT_USER\Software does not have a redirect
|
||||
// https://learn.microsoft.com/en-us/windows/win32/winprog64/shared-registry-keys#redirected-shared-and-reflected-keys-under-wow64
|
||||
if (Index < (IsSystem64Bit() ? 3 : 2))
|
||||
return GetRootKeyInfo(Index, RegSam);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CInstalledApplicationInfo *
|
||||
CAppDB::CreateInstalledAppByRegistryKey(LPCWSTR KeyName, HKEY hKeyParent, UINT KeyIndex)
|
||||
{
|
||||
@@ -209,7 +227,7 @@ CAppDB::EnumerateRegistry(CAtlList<CAppInfo *> *List, LPCWSTR SearchOnly)
|
||||
ATLASSERT(List || SearchOnly);
|
||||
REGSAM wowsam;
|
||||
HKEY hRootKey;
|
||||
for (UINT rki = 0; (hRootKey = EnumInstalledRootKey(rki, wowsam)); ++rki)
|
||||
for (CEnumInstalledRootKey RootEnum; (hRootKey = RootEnum.GetNext(wowsam)) != NULL;)
|
||||
{
|
||||
CRegKey hKey;
|
||||
if (hKey.Open(hRootKey, UNINSTALL_SUBKEY, KEY_READ | wowsam) != ERROR_SUCCESS)
|
||||
@@ -227,7 +245,7 @@ CAppDB::EnumerateRegistry(CAtlList<CAppInfo *> *List, LPCWSTR SearchOnly)
|
||||
if (List || !StrCmpIW(SearchOnly, szKeyName))
|
||||
{
|
||||
CInstalledApplicationInfo *Info;
|
||||
Info = CreateInstalledAppByRegistryKey(szKeyName, hKey, rki);
|
||||
Info = CreateInstalledAppByRegistryKey(szKeyName, hKey, RootEnum.GetKeyIndex());
|
||||
if (Info)
|
||||
{
|
||||
if (List)
|
||||
|
||||
@@ -47,8 +47,6 @@ class CAppDB
|
||||
CreateInstalledAppByRegistryKey(LPCWSTR Name);
|
||||
static CInstalledApplicationInfo *
|
||||
CreateInstalledAppInstance(LPCWSTR KeyName, BOOL User, REGSAM WowSam);
|
||||
static HKEY
|
||||
EnumInstalledRootKey(UINT Index, REGSAM &RegSam);
|
||||
|
||||
size_t GetAvailableCount() const
|
||||
{
|
||||
|
||||
@@ -97,6 +97,8 @@ UnixTimeToFileTime(DWORD dwUnixTime, LPFILETIME pFileTime);
|
||||
BOOL
|
||||
SearchPatternMatch(LPCWSTR szHaystack, LPCWSTR szNeedle);
|
||||
|
||||
BOOL
|
||||
IsSameRegKey(HKEY hRoot, LPCWSTR Path1, REGSAM Sam1, LPCWSTR Path2, REGSAM Sam2);
|
||||
HRESULT
|
||||
RegKeyHasValues(HKEY hKey, LPCWSTR Path, REGSAM wowsam = 0);
|
||||
LPCWSTR
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "rapps.h"
|
||||
#include "misc.h"
|
||||
|
||||
EXTERN_C NTSTATUS WINAPI NtQueryObject(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
||||
|
||||
static HANDLE hLog = NULL;
|
||||
|
||||
UINT
|
||||
@@ -452,6 +454,32 @@ UnixTimeToFileTime(DWORD dwUnixTime, LPFILETIME pFileTime)
|
||||
pFileTime->dwHighDateTime = ll >> 32;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
IsSameRegKey(HKEY hKey1, HKEY hKey2)
|
||||
{
|
||||
// CompareObjectHandles is Win10+ so we check the path instead.
|
||||
struct NameInfo : UNICODE_STRING
|
||||
{
|
||||
WCHAR Allocation[MAX_PATH];
|
||||
NameInfo() { MaximumLength = sizeof(Allocation); Buffer = Allocation; }
|
||||
};
|
||||
NameInfo Name1, Name2;
|
||||
ULONG Length;
|
||||
return NT_SUCCESS(NtQueryObject(hKey1, ObjectNameInformation, &Name1, sizeof(Name1), &Length)) &&
|
||||
NT_SUCCESS(NtQueryObject(hKey2, ObjectNameInformation, &Name2, sizeof(Name2), &Length)) &&
|
||||
RtlCompareUnicodeString(&Name1, &Name2, TRUE) == 0;
|
||||
}
|
||||
|
||||
BOOL
|
||||
IsSameRegKey(HKEY hRoot, LPCWSTR Path1, REGSAM Sam1, LPCWSTR Path2, REGSAM Sam2)
|
||||
{
|
||||
REGSAM WowMask = KEY_WOW64_32KEY | KEY_WOW64_64KEY;
|
||||
CRegKey key1, key2;
|
||||
return key1.Open(hRoot, Path1, MAXIMUM_ALLOWED | (Sam1 & WowMask)) == ERROR_SUCCESS &&
|
||||
key2.Open(hRoot, Path2, MAXIMUM_ALLOWED | (Sam2 & WowMask)) == ERROR_SUCCESS &&
|
||||
IsSameRegKey(key1, key2);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
RegKeyHasValues(HKEY hKey, LPCWSTR Path, REGSAM wowsam)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user