https://git.reactos.org/?p=reactos.git;a=commitdiff;h=143b2a50350b3c9608d65fbd2675f32e06c3babe

commit 143b2a50350b3c9608d65fbd2675f32e06c3babe
Author:     Mark Jansen <[email protected]>
AuthorDate: Sun Oct 3 20:35:13 2021 +0200
Commit:     Mark Jansen <[email protected]>
CommitDate: Wed Oct 13 19:27:40 2021 +0200

    [RAPPS] Speed up installed application loading
    
    Only load in details when we are going to display them
---
 base/applications/rapps/appview.cpp         |   2 +
 base/applications/rapps/gui.cpp             |   4 +-
 base/applications/rapps/include/appview.h   |   1 -
 base/applications/rapps/include/dialogs.h   |   2 +-
 base/applications/rapps/include/installed.h |  57 ++++---
 base/applications/rapps/installed.cpp       | 241 ++++++++++++----------------
 base/applications/rapps/loaddlg.cpp         |   4 +-
 7 files changed, 140 insertions(+), 171 deletions(-)

diff --git a/base/applications/rapps/appview.cpp 
b/base/applications/rapps/appview.cpp
index 631eecbad9c..a9fe2922254 100644
--- a/base/applications/rapps/appview.cpp
+++ b/base/applications/rapps/appview.cpp
@@ -398,6 +398,8 @@ BOOL 
CAppRichEdit::ShowInstalledAppInfo(CInstalledApplicationInfo *Info)
     SetText(Info->szDisplayName, CFE_BOLD);
     InsertText(L"\n", 0);
 
+    Info->EnsureDetailsLoaded();
+
     InsertTextWithString(IDS_INFO_VERSION, CFE_BOLD, Info->szDisplayVersion, 
0);
     InsertTextWithString(IDS_INFO_PUBLISHER, CFE_BOLD, Info->szPublisher, 0);
     InsertTextWithString(IDS_INFO_REGOWNER, CFE_BOLD, Info->szRegOwner, 0);
diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp
index f0616c08aff..80cd779bed1 100644
--- a/base/applications/rapps/gui.cpp
+++ b/base/applications/rapps/gui.cpp
@@ -567,7 +567,7 @@ VOID CMainWindow::OnCommand(WPARAM wParam, LPARAM lParam)
                     CAvailableApplicationInfo *FocusedApps = 
(CAvailableApplicationInfo *)m_ApplicationView->GetFocusedItemData();
                     if (FocusedApps)
                     {
-                        if (DownloadApplication(FocusedApps, FALSE))
+                        if (DownloadApplication(FocusedApps))
                         {
                             UpdateApplicationsList(-1);
                         }
@@ -782,7 +782,7 @@ BOOL 
CMainWindow::InstallApplication(CAvailableApplicationInfo *Info)
 {
     if (Info)
     {
-        if (DownloadApplication(Info, FALSE))
+        if (DownloadApplication(Info))
         {
             UpdateApplicationsList(-1);
             return TRUE;
diff --git a/base/applications/rapps/include/appview.h 
b/base/applications/rapps/include/appview.h
index b625d5ed296..9042a361d33 100644
--- a/base/applications/rapps/include/appview.h
+++ b/base/applications/rapps/include/appview.h
@@ -191,7 +191,6 @@ public:
     HWND Create(HWND hwndParent);
 
     BOOL ShowAvailableAppInfo(CAvailableApplicationInfo *Info);
-
     BOOL ShowInstalledAppInfo(CInstalledApplicationInfo *Info);
 
     VOID SetWelcomeText();
diff --git a/base/applications/rapps/include/dialogs.h 
b/base/applications/rapps/include/dialogs.h
index 917effd8c6e..79d7d494017 100644
--- a/base/applications/rapps/include/dialogs.h
+++ b/base/applications/rapps/include/dialogs.h
@@ -13,5 +13,5 @@ VOID MainWindowLoop(INT nShowCmd);
 
 // Download dialogs
 VOID DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial);
-BOOL DownloadApplication(CAvailableApplicationInfo* pAppInfo, BOOL bIsModal);
+BOOL DownloadApplication(CAvailableApplicationInfo* pAppInfo);
 BOOL DownloadListOfApplications(const 
ATL::CSimpleArray<CAvailableApplicationInfo>& AppsList, BOOL bIsModal);
diff --git a/base/applications/rapps/include/installed.h 
b/base/applications/rapps/include/installed.h
index 6e950056481..68ada9da094 100644
--- a/base/applications/rapps/include/installed.h
+++ b/base/applications/rapps/include/installed.h
@@ -5,41 +5,48 @@
 
 class CInstalledApplicationInfo
 {
+private:
+    BOOL m_IsUserKey;
+    REGSAM m_WowKey;
+    HKEY m_hSubKey;
+
+    CStringW m_szKeyName;
+
 public:
-    BOOL IsUserKey;
-    REGSAM WowKey;
-    HKEY hSubKey;
-    BOOL bIsUpdate = FALSE;
+    CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM RegWowKey, HKEY hKey, 
const CStringW& szKeyName);
+    ~CInstalledApplicationInfo();
 
-    ATL::CStringW szKeyName;
+    VOID EnsureDetailsLoaded();
 
-    CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM RegWowKey, HKEY hKey);
     BOOL GetApplicationRegString(LPCWSTR lpKeyName, ATL::CStringW& String);
     BOOL GetApplicationRegDword(LPCWSTR lpKeyName, DWORD *lpValue);
     BOOL RetrieveIcon(ATL::CStringW& IconLocation);
     BOOL UninstallApplication(BOOL bModify);
     LSTATUS RemoveFromRegistry();
 
-    ATL::CStringW szDisplayIcon;
-    ATL::CStringW szDisplayName;
-    ATL::CStringW szDisplayVersion;
-    ATL::CStringW szPublisher;
-    ATL::CStringW szRegOwner;
-    ATL::CStringW szProductID;
-    ATL::CStringW szHelpLink;
-    ATL::CStringW szHelpTelephone;
-    ATL::CStringW szReadme;
-    ATL::CStringW szContact;
-    ATL::CStringW szURLUpdateInfo;
-    ATL::CStringW szURLInfoAbout;
-    ATL::CStringW szComments;
-    ATL::CStringW szInstallDate;
-    ATL::CStringW szInstallLocation;
-    ATL::CStringW szInstallSource;
-    ATL::CStringW szUninstallString;
-    ATL::CStringW szModifyPath;
+    // These fields are always loaded
+    BOOL bIsUpdate;
+    CStringW szDisplayIcon;
+    CStringW szDisplayName;
+    CStringW szDisplayVersion;
+    CStringW szComments;
+
+    // These details are loaded on demand
+    CStringW szPublisher;
+    CStringW szRegOwner;
+    CStringW szProductID;
+    CStringW szHelpLink;
+    CStringW szHelpTelephone;
+    CStringW szReadme;
+    CStringW szContact;
+    CStringW szURLUpdateInfo;
+    CStringW szURLInfoAbout;
+    CStringW szInstallDate;
+    CStringW szInstallLocation;
+    CStringW szInstallSource;
+    CStringW szUninstallString;
+    CStringW szModifyPath;
 
-    ~CInstalledApplicationInfo();
 };
 
 typedef BOOL(CALLBACK *APPENUMPROC)(CInstalledApplicationInfo * Info, PVOID 
param);
diff --git a/base/applications/rapps/installed.cpp 
b/base/applications/rapps/installed.cpp
index eaec4429480..fed899e9448 100644
--- a/base/applications/rapps/installed.cpp
+++ b/base/applications/rapps/installed.cpp
@@ -2,123 +2,122 @@
  * PROJECT:     ReactOS Applications Manager
  * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
  * PURPOSE:     Classes for working with installed applications
- * COPYRIGHT:   Copyright 2009 Dmitry Chapyshev         ([email protected])
- *              Copyright 2017 Alexander Shaposhnikov   ([email protected])
- *              Copyright 2020 He Yang                  ([email protected])
+ * COPYRIGHT:   Copyright 2009 Dmitry Chapyshev <[email protected]>
+ *              Copyright 2017 Alexander Shaposhnikov <[email protected]>
+ *              Copyright 2020 He Yang <[email protected]>
+ *              Copyright 2021 Mark Jansen <[email protected]>
  */
-#include "rapps.h"
 
+#include "rapps.h"
 #include "installed.h"
-
 #include "misc.h"
 
-CInstalledApplicationInfo::CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM 
RegWowKey, HKEY hKey)
-    : IsUserKey(bIsUserKey), WowKey(RegWowKey), hSubKey(hKey)
+CInstalledApplicationInfo::CInstalledApplicationInfo(BOOL bIsUserKey, REGSAM 
RegWowKey, HKEY hKey, const CStringW& szKeyName)
+    : m_IsUserKey(bIsUserKey)
+    , m_WowKey(RegWowKey)
+    , m_hSubKey(hKey)
+    , m_szKeyName(szKeyName)
 {
-    // if Initialize failed, hSubKey will be closed automatically and set to 
zero
-
-    DWORD dwSize = MAX_PATH, dwType, dwValue;
-    BOOL bIsSystemComponent;
-    ATL::CStringW szParentKeyName;
-
-    dwType = REG_DWORD;
-    dwSize = sizeof(DWORD);
+    DWORD dwSize = 0;
+    bIsUpdate = (RegQueryValueExW(m_hSubKey, L"ParentKeyName", NULL, NULL, 
NULL, &dwSize) == ERROR_SUCCESS);
+}
 
-    if (RegQueryValueExW(hSubKey,
-        L"SystemComponent",
-        NULL,
-        &dwType,
-        (LPBYTE)&dwValue,
-        &dwSize) == ERROR_SUCCESS)
+CInstalledApplicationInfo::~CInstalledApplicationInfo()
+{
+    if (m_hSubKey)
     {
-        bIsSystemComponent = (dwValue == 0x1);
+        CloseHandle(m_hSubKey);
+        m_hSubKey = NULL;
     }
-    else
+}
+
+void CInstalledApplicationInfo::EnsureDetailsLoaded()
+{
+    // Key not closed, so we have not loaded details yet
+    if (m_hSubKey)
     {
-        bIsSystemComponent = FALSE;
-    }
+        GetApplicationRegString(L"Publisher", szPublisher);
+        GetApplicationRegString(L"RegOwner", szRegOwner);
+        GetApplicationRegString(L"ProductID", szProductID);
+        GetApplicationRegString(L"HelpLink", szHelpLink);
+        GetApplicationRegString(L"HelpTelephone", szHelpTelephone);
+        GetApplicationRegString(L"Readme", szReadme);
+        GetApplicationRegString(L"Contact", szContact);
+        GetApplicationRegString(L"URLUpdateInfo", szURLUpdateInfo);
+        GetApplicationRegString(L"URLInfoAbout", szURLInfoAbout);
+        if (GetApplicationRegString(L"InstallDate", szInstallDate) == FALSE)
+        {
+            // It might be a DWORD (Unix timestamp). try again.
+            DWORD dwInstallTimeStamp;
+            if (GetApplicationRegDword(L"InstallDate", &dwInstallTimeStamp))
+            {
+                FILETIME InstallFileTime;
+                SYSTEMTIME InstallSystemTime, InstallLocalTime;
 
-    dwType = REG_SZ;
-    dwSize = MAX_PATH * sizeof(WCHAR);
-    bIsUpdate = (RegQueryValueExW(hSubKey,
-        L"ParentKeyName",
-        NULL,
-        &dwType,
-        (LPBYTE)szParentKeyName.GetBuffer(MAX_PATH),
-        &dwSize) == ERROR_SUCCESS);
-    szParentKeyName.ReleaseBuffer();
+                UnixTimeToFileTime(dwInstallTimeStamp, &InstallFileTime);
+                FileTimeToSystemTime(&InstallFileTime, &InstallSystemTime);
 
-    if (bIsSystemComponent)
-    {
-        CloseHandle(hSubKey);
-        hSubKey = NULL;
-    }
+                // convert to localtime
+                SystemTimeToTzSpecificLocalTime(NULL, &InstallSystemTime, 
&InstallLocalTime);
 
-}
+                // convert to readable date string
+                int cchTimeStrLen = GetDateFormatW(LOCALE_USER_DEFAULT, 0, 
&InstallLocalTime, NULL, 0, 0);
 
-CInstalledApplicationInfo::~CInstalledApplicationInfo()
-{
-    if (hSubKey)
-    {
-        CloseHandle(hSubKey);
-        hSubKey = NULL;
+                GetDateFormatW(
+                    LOCALE_USER_DEFAULT, // use default locale for current user
+                    0, &InstallLocalTime, NULL, 
szInstallDate.GetBuffer(cchTimeStrLen), cchTimeStrLen);
+                szInstallDate.ReleaseBuffer();
+            }
+        }
+        GetApplicationRegString(L"InstallLocation", szInstallLocation);
+        GetApplicationRegString(L"InstallSource", szInstallSource);
+        GetApplicationRegString(L"UninstallString", szUninstallString);
+        GetApplicationRegString(L"ModifyPath",szModifyPath);
+
+        CloseHandle(m_hSubKey);
+        m_hSubKey = NULL;
     }
 }
 
 BOOL CInstalledApplicationInfo::GetApplicationRegString(LPCWSTR lpKeyName, 
ATL::CStringW& String)
 {
-    DWORD dwSize = 0;
-    String.Empty();
-    DWORD dwType;
+    DWORD dwAllocated = 0, dwSize, dwType;
 
     // retrieve the size of value first.
-    if (RegQueryValueExW(hSubKey,
-        lpKeyName,
-        NULL,
-        &dwType,
-        NULL,
-        &dwSize) != ERROR_SUCCESS)
+    if (RegQueryValueExW(m_hSubKey, lpKeyName, NULL, &dwType, NULL, 
&dwAllocated) != ERROR_SUCCESS ||
+        dwType != REG_SZ)
     {
+        String.Empty();
         return FALSE;
     }
 
-    // TODO: I assume the type as REG_SZ. but I think REG_EXPAND_SZ should be 
handled correctly too.
-    if (dwType != REG_SZ)
-    {
-        return FALSE;
-    }
+    // query the value
+    dwSize = dwAllocated;
+    LSTATUS Result =
+        RegQueryValueExW(m_hSubKey, lpKeyName, NULL, NULL, 
(LPBYTE)String.GetBuffer(dwAllocated / sizeof(WCHAR)), &dwSize);
 
-    // allocate buffer.
-    // attention: dwSize is size in bytes, and RegQueryValueExW does not 
guarantee the terminating null character.
-    String.GetBuffer(dwSize + sizeof(WCHAR));
+    dwSize = min(dwAllocated, dwSize);
+    // CString takes care of zero-terminating it
+    String.ReleaseBuffer(dwSize / sizeof(WCHAR));
 
-    // query the value
-    if (RegQueryValueExW(hSubKey,
-        lpKeyName,
-        NULL,
-        NULL,
-        (LPBYTE)String.GetBuffer(),
-        &dwSize) != ERROR_SUCCESS)
+    if (Result != ERROR_SUCCESS)
     {
-        String.ReleaseBuffer();
         String.Empty();
         return FALSE;
     }
-    String.GetBuffer()[dwSize / sizeof(WCHAR)] = L'\0'; // ensure zero 
terminated
-    String.ReleaseBuffer();
+
     return TRUE;
 }
 
 BOOL CInstalledApplicationInfo::GetApplicationRegDword(LPCWSTR lpKeyName, 
DWORD *lpValue)
 {
-    DWORD dwType = REG_DWORD;
-    DWORD dwSize = sizeof(DWORD);
-    if (RegQueryValueExW(hSubKey,
+    DWORD dwSize = sizeof(DWORD), dwType;
+    if (RegQueryValueExW(m_hSubKey,
         lpKeyName,
         NULL,
         &dwType,
         (LPBYTE)lpValue,
-        &dwSize) != ERROR_SUCCESS)
+        &dwSize) != ERROR_SUCCESS || dwType != REG_DWORD)
     {
         return FALSE;
     }
@@ -148,7 +147,7 @@ typedef LSTATUS (WINAPI *RegDeleteKeyExWProc)(HKEY, 
LPCWSTR, REGSAM, DWORD);
 
 LSTATUS CInstalledApplicationInfo::RemoveFromRegistry()
 {
-    ATL::CStringW szFullName = 
L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + szKeyName;
+    ATL::CStringW szFullName = 
L"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + m_szKeyName;
     HMODULE hMod = GetModuleHandleW(L"advapi32.dll");
     RegDeleteKeyExWProc pRegDeleteKeyExW;
 
@@ -166,12 +165,12 @@ LSTATUS CInstalledApplicationInfo::RemoveFromRegistry()
         if (pRegDeleteKeyExW)
         {
             /* Return it */
-            return pRegDeleteKeyExW(IsUserKey ? HKEY_CURRENT_USER : 
HKEY_LOCAL_MACHINE, szFullName, WowKey, 0);
+            return pRegDeleteKeyExW(m_IsUserKey ? HKEY_CURRENT_USER : 
HKEY_LOCAL_MACHINE, szFullName, m_WowKey, 0);
         }
     }
 
     /* Otherwise, return non-Ex function */
-    return RegDeleteKeyW(IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 
szFullName);
+    return RegDeleteKeyW(m_IsUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, 
szFullName);
 }
 
 BOOL CInstalledApps::Enum(INT EnumType, APPENUMPROC lpEnumProc, PVOID param)
@@ -225,72 +224,34 @@ BOOL CInstalledApps::Enum(INT EnumType, APPENUMPROC 
lpEnumProc, PVOID param)
             ItemIndex++;
 
             szKeyName.ReleaseBuffer();
-            if (RegOpenKeyW(hKey, szKeyName.GetString(), &hSubKey) == 
ERROR_SUCCESS)
+            if (RegOpenKeyW(hKey, szKeyName, &hSubKey) == ERROR_SUCCESS)
             {
-                BOOL bSuccess = FALSE;
-                CInstalledApplicationInfo *Info = new 
CInstalledApplicationInfo(RootKeyEnum[i] == HKEY_CURRENT_USER, RegSamEnum[i], 
hSubKey);
-                Info->szKeyName = szKeyName;
+                DWORD dwValue = 0;
+                BOOL bIsSystemComponent = FALSE;
 
-                // check for failure. if failed to init, Info->hSubKey will be 
set to NULL
-                if (Info->hSubKey)
+                dwSize = sizeof(DWORD);
+                if (RegQueryValueExW(hSubKey, L"SystemComponent", NULL, NULL, 
(LPBYTE)&dwValue, &dwSize) == ERROR_SUCCESS)
                 {
-                    // those items without display name are ignored
-                    if (Info->GetApplicationRegString(L"DisplayName", 
Info->szDisplayName))
-                    {
-                        Info->GetApplicationRegString(L"DisplayIcon", 
Info->szDisplayIcon);
-                        Info->GetApplicationRegString(L"DisplayVersion", 
Info->szDisplayVersion);
-                        Info->GetApplicationRegString(L"Publisher", 
Info->szPublisher);
-                        Info->GetApplicationRegString(L"RegOwner", 
Info->szRegOwner);
-                        Info->GetApplicationRegString(L"ProductID", 
Info->szProductID);
-                        Info->GetApplicationRegString(L"HelpLink", 
Info->szHelpLink);
-                        Info->GetApplicationRegString(L"HelpTelephone", 
Info->szHelpTelephone);
-                        Info->GetApplicationRegString(L"Readme", 
Info->szReadme);
-                        Info->GetApplicationRegString(L"Contact", 
Info->szContact);
-                        Info->GetApplicationRegString(L"URLUpdateInfo", 
Info->szURLUpdateInfo);
-                        Info->GetApplicationRegString(L"URLInfoAbout", 
Info->szURLInfoAbout);
-                        Info->GetApplicationRegString(L"Comments", 
Info->szComments);
-                        if (Info->GetApplicationRegString(L"InstallDate", 
Info->szInstallDate) == FALSE)
-                        {
-                            // It might be a DWORD (Unix timestamp). try again.
-                            DWORD dwInstallTimeStamp;
-                            if (Info->GetApplicationRegDword(L"InstallDate", 
&dwInstallTimeStamp))
-                            {
-                                FILETIME InstallFileTime;
-                                SYSTEMTIME InstallSystemTime, InstallLocalTime;
-
-                                UnixTimeToFileTime(dwInstallTimeStamp, 
&InstallFileTime);
-                                FileTimeToSystemTime(&InstallFileTime, 
&InstallSystemTime);
-
-                                // convert to localtime
-                                SystemTimeToTzSpecificLocalTime(NULL, 
&InstallSystemTime, &InstallLocalTime);
-
-                                // convert to readable date string
-                                int cchTimeStrLen = 
GetDateFormatW(LOCALE_USER_DEFAULT,
-                                    0,
-                                    &InstallLocalTime,
-                                    NULL, 0, 0);
-
-                                GetDateFormatW(LOCALE_USER_DEFAULT, // use 
default locale for current user
-                                    0,
-                                    &InstallLocalTime,
-                                    NULL, 
Info->szInstallDate.GetBuffer(cchTimeStrLen), cchTimeStrLen);
-                                Info->szInstallDate.ReleaseBuffer();
-                            }
-                        }
-                        Info->GetApplicationRegString(L"InstallLocation", 
Info->szInstallLocation);
-                        Info->GetApplicationRegString(L"InstallSource", 
Info->szInstallSource);
-                        Info->GetApplicationRegString(L"UninstallString", 
Info->szUninstallString);
-                        Info->GetApplicationRegString(L"ModifyPath", 
Info->szModifyPath);
-
-                        bSuccess = TRUE;
-                    }
+                    bIsSystemComponent = (dwValue == 0x1);
+                }
+                // Ignore system components
+                if (bIsSystemComponent)
+                {
+                    RegCloseKey(hSubKey);
+                    continue;
                 }
 
-                // close handle
-                if (Info->hSubKey)
+                BOOL bSuccess = FALSE;
+                CInstalledApplicationInfo *Info = new 
CInstalledApplicationInfo(RootKeyEnum[i] == HKEY_CURRENT_USER, RegSamEnum[i], 
hSubKey, szKeyName);
+
+                // items without display name are ignored
+                if (Info->GetApplicationRegString(L"DisplayName", 
Info->szDisplayName))
                 {
-                    CloseHandle(Info->hSubKey);
-                    Info->hSubKey = NULL;
+                    Info->GetApplicationRegString(L"DisplayIcon", 
Info->szDisplayIcon);
+                    Info->GetApplicationRegString(L"DisplayVersion", 
Info->szDisplayVersion);
+                    Info->GetApplicationRegString(L"Comments", 
Info->szComments);
+
+                    bSuccess = TRUE;
                 }
 
                 if (bSuccess)
diff --git a/base/applications/rapps/loaddlg.cpp 
b/base/applications/rapps/loaddlg.cpp
index 49538ac1d06..d86bdda5131 100644
--- a/base/applications/rapps/loaddlg.cpp
+++ b/base/applications/rapps/loaddlg.cpp
@@ -1030,12 +1030,12 @@ BOOL DownloadListOfApplications(const 
ATL::CSimpleArray<CAvailableApplicationInf
     return TRUE;
 }
 
-BOOL DownloadApplication(CAvailableApplicationInfo* pAppInfo, BOOL bIsModal)
+BOOL DownloadApplication(CAvailableApplicationInfo* pAppInfo)
 {
     if (!pAppInfo)
         return FALSE;
 
-    CDownloadManager::Download(*pAppInfo, bIsModal);
+    CDownloadManager::Download(*pAppInfo, FALSE);
     return TRUE;
 }
 

Reply via email to