[RAPPS]
authorAlexander Shaposhnikov <sanchaez@reactos.org>
Tue, 15 Aug 2017 19:36:23 +0000 (19:36 +0000)
committerAlexander Shaposhnikov <sanchaez@reactos.org>
Tue, 15 Aug 2017 19:36:23 +0000 (19:36 +0000)
- Changed "/SETUP" key to "/INSTALL"
- Added support for multiple apps install by "/INSTALL"
  rapps /INSTALL 7-Zip AkelPad [...]
- Added INF based batch install with the "/SETUP" key
  Works for the full path for the .inf file
  TODO: detect if user entered the relative path for the inf and correct it
- Moved CmdParser to include/unattended.h and unattended.cpp

svn path=/branches/GSoC_2017/rapps/; revision=75555

reactos/base/applications/rapps/CMakeLists.txt
reactos/base/applications/rapps/available.cpp
reactos/base/applications/rapps/include/available.h
reactos/base/applications/rapps/include/dialogs.h
reactos/base/applications/rapps/include/misc.h
reactos/base/applications/rapps/include/unattended.h [new file with mode: 0644]
reactos/base/applications/rapps/loaddlg.cpp
reactos/base/applications/rapps/misc.cpp
reactos/base/applications/rapps/unattended.cpp [new file with mode: 0644]
reactos/base/applications/rapps/winmain.cpp

index 500834f..6efc9a4 100644 (file)
@@ -17,6 +17,7 @@ list(APPEND SOURCE
     misc.cpp
     settingsdlg.cpp
     winmain.cpp
+    unattended.cpp
     include/rapps.h
     include/available.h
     include/gui.h
@@ -28,6 +29,7 @@ list(APPEND SOURCE
     include/resource.h
     include/rosui.h
     include/winmain.h
+    include/unattended.h
 )
 
 add_definitions(-DUSE_CERT_PINNING)
@@ -36,7 +38,7 @@ add_rc_deps(rapps.rc ${rapps_rc_deps})
 add_executable(rapps ${SOURCE} rapps.rc)
 set_module_type(rapps win32gui UNICODE)
 target_link_libraries(rapps atlnew uuid wine)
-add_importlibs(rapps advapi32 comctl32 gdi32 wininet user32 shell32 shlwapi ole32 msvcrt kernel32 ntdll)
+add_importlibs(rapps advapi32 comctl32 gdi32 wininet user32 shell32 shlwapi ole32 msvcrt kernel32 ntdll setupapi)
 add_pch(rapps include/rapps.h SOURCE)
 add_dependencies(rapps rappsmsg)
 add_message_headers(ANSI rappsmsg.mc)
index 0ae86ac..23db36b 100644 (file)
@@ -379,6 +379,20 @@ const PAPPLICATION_INFO CAvailableApps::FindInfo(const ATL::CStringW& szAppName)
     return NULL;
 }
 
+ATL::CSimpleArray<PAPPLICATION_INFO> CAvailableApps::FindInfoList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames)
+{
+    ATL::CSimpleArray<PAPPLICATION_INFO> result;
+    for (int i = 0; i < arrAppsNames.GetSize(); ++i)
+    {
+        PAPPLICATION_INFO Info = FindInfo(arrAppsNames[i]);
+        if (Info)
+        {
+            result.Add(Info);
+        }
+    }
+    return result;
+}
+
 const ATL::CStringW & CAvailableApps::GetFolderPath()
 {
     return m_szPath;
@@ -409,109 +423,3 @@ const LPCWSTR CAvailableApps::GetCabPathString()
     return m_szPath.GetString();
 }
 // CAvailableApps
-
-// CConfigParser
-ATL::CStringW CConfigParser::m_szLocaleID;
-ATL::CStringW CConfigParser::m_szCachedINISectionLocale;
-ATL::CStringW CConfigParser::m_szCachedINISectionLocaleNeutral;
-
-CConfigParser::CConfigParser(const ATL::CStringW& FileName) : szConfigPath(GetINIFullPath(FileName))
-{
-    // we don't have cached section strings for the current system language, create them, lazy
-    CacheINILocaleLazy();
-}
-
-ATL::CStringW CConfigParser::GetINIFullPath(const ATL::CStringW& FileName)
-{
-    ATL::CStringW szDir;
-    ATL::CStringW szBuffer;
-
-    GetStorageDirectory(szDir);
-    szBuffer.Format(L"%ls\\rapps\\%ls", szDir, FileName);
-
-    return szBuffer;
-}
-
-VOID CConfigParser::CacheINILocaleLazy()
-{
-    if (m_szLocaleID.IsEmpty())
-    {
-        // TODO: Set default locale if call fails
-        // find out what is the current system lang code (e.g. "0a") and append it to SectionLocale
-        GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_ILANGUAGE,
-                       m_szLocaleID.GetBuffer(m_cchLocaleSize), m_cchLocaleSize);
-
-        m_szLocaleID.ReleaseBuffer();
-        m_szCachedINISectionLocale = L"Section." + m_szLocaleID;
-
-        // turn "Section.0c0a" into "Section.0a", keeping just the neutral lang part
-        m_szCachedINISectionLocaleNeutral = m_szCachedINISectionLocale + m_szLocaleID.Right(2);
-    }
-}
-
-const ATL::CStringW& CConfigParser::GetLocale()
-{
-    CacheINILocaleLazy();
-    return m_szLocaleID;
-}
-
-INT CConfigParser::GetLocaleSize()
-{
-    return m_cchLocaleSize;
-}
-
-UINT CConfigParser::GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString)
-{
-    DWORD dwResult;
-
-    LPWSTR ResultStringBuffer = ResultString.GetBuffer(MAX_PATH);
-    // 1st - find localized strings (e.g. "Section.0c0a")
-    dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocale.GetString(),
-                                        KeyName.GetString(),
-                                        NULL,
-                                        ResultStringBuffer,
-                                        MAX_PATH,
-                                        szConfigPath.GetString());
-
-    if (!dwResult)
-    {
-        // 2nd - if they weren't present check for neutral sub-langs/ generic translations (e.g. "Section.0a")
-        dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocaleNeutral.GetString(),
-                                            KeyName.GetString(),
-                                            NULL,
-                                            ResultStringBuffer,
-                                            MAX_PATH,
-                                            szConfigPath.GetString());
-        if (!dwResult)
-        {
-            // 3rd - if they weren't present fallback to standard english strings (just "Section")
-            dwResult = GetPrivateProfileStringW(L"Section",
-                                                KeyName.GetString(),
-                                                NULL,
-                                                ResultStringBuffer,
-                                                MAX_PATH,
-                                                szConfigPath.GetString());
-        }
-    }
-
-    ResultString.ReleaseBuffer();
-    return (dwResult != 0 ? TRUE : FALSE);
-}
-
-UINT CConfigParser::GetInt(const ATL::CStringW& KeyName)
-{
-    ATL::CStringW Buffer;
-
-    // grab the text version of our entry
-    if (!GetString(KeyName, Buffer))
-        return FALSE;
-
-    if (Buffer.IsEmpty())
-        return FALSE;
-
-    // convert it to an actual integer
-    int result = StrToIntW(Buffer.GetString());
-
-    return (UINT) (result <= 0) ? 0 : result;
-}
-// CConfigParser
index 5221e76..6b26fcd 100644 (file)
@@ -1,8 +1,10 @@
 #pragma once
+
 #include <windef.h>
 #include <atlstr.h> 
 #include <atlsimpcoll.h>
 #include <atlcoll.h>
+#include "misc.h"
 
 /* EnumType flags for EnumAvailableApplications */
 enum AvailableCategories
@@ -42,31 +44,6 @@ typedef enum LICENSE_TYPE
     Min = None
 } *PLICENSE_TYPE;
 
-class CConfigParser
-{
-    // Locale names cache
-    const static INT m_cchLocaleSize = 5;
-
-    static ATL::CStringW m_szLocaleID;
-    static ATL::CStringW m_szCachedINISectionLocale;
-    static ATL::CStringW m_szCachedINISectionLocaleNeutral;
-
-    const LPCWSTR STR_VERSION_CURRENT = L"CURRENT";
-    const ATL::CStringW szConfigPath;
-
-    static ATL::CStringW GetINIFullPath(const ATL::CStringW& FileName);
-    static VOID CacheINILocaleLazy();
-
-public:
-    static const ATL::CStringW& GetLocale();
-    static INT CConfigParser::GetLocaleSize();
-
-    CConfigParser(const ATL::CStringW& FileName);
-
-    UINT GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString);
-    UINT GetInt(const ATL::CStringW& KeyName);
-};
-
 typedef struct APPLICATION_INFO
 {
     INT Category;
@@ -142,6 +119,7 @@ public:
     BOOL UpdateAppsDB();
     BOOL EnumAvailableApplications(INT EnumType, AVAILENUMPROC lpEnumProc);
     const PAPPLICATION_INFO FindInfo(const ATL::CStringW& szAppName);
+    ATL::CSimpleArray<PAPPLICATION_INFO> FindInfoList(const ATL::CSimpleArray<ATL::CStringW> &arrAppsNames);
     const ATL::CStringW& GetFolderPath();
     const ATL::CStringW& GetAppPath();
     const ATL::CStringW& GetCabPath();
index e90d351..08886ee 100644 (file)
@@ -25,7 +25,7 @@ public:
                                                  DWORD_PTR dwRefData);
 
     static DWORD WINAPI ThreadFunc(LPVOID Context);
-    static BOOL DownloadListOfApplications(const ATL::CSimpleArray<PAPPLICATION_INFO>& AppsList);
+    static BOOL DownloadListOfApplications(const ATL::CSimpleArray<PAPPLICATION_INFO>& AppsList, BOOL modal = FALSE);
     static BOOL DownloadApplication(PAPPLICATION_INFO pAppInfo, BOOL modal = FALSE);
     static VOID DownloadApplicationsDB(LPCWSTR lpUrl);
     static VOID LaunchDownloadDialog(BOOL);
index c27007d..878f5bb 100644 (file)
@@ -3,10 +3,10 @@
 #include <windef.h>
 #include <atlstr.h>
 
-int GetWindowWidth(HWND hwnd);
-int GetWindowHeight(HWND hwnd);
-int GetClientWindowWidth(HWND hwnd);
-int GetClientWindowHeight(HWND hwnd);
+INT GetWindowWidth(HWND hwnd);
+INT GetWindowHeight(HWND hwnd);
+INT GetClientWindowWidth(HWND hwnd);
+INT GetClientWindowHeight(HWND hwnd);
 
 VOID CopyTextToClipboard(LPCWSTR lpszText);
 VOID SetWelcomeText(VOID);
@@ -19,3 +19,27 @@ VOID InitLogs(VOID);
 VOID FreeLogs(VOID);
 BOOL WriteLogMessage(WORD wType, DWORD dwEventID, LPCWSTR lpMsg);
 BOOL GetInstalledVersion(ATL::CStringW *pszVersion, const ATL::CStringW &szRegName);
+
+class CConfigParser
+{
+    // Locale names cache
+    const static INT m_cchLocaleSize = 5;
+
+    static ATL::CStringW m_szLocaleID;
+    static ATL::CStringW m_szCachedINISectionLocale;
+    static ATL::CStringW m_szCachedINISectionLocaleNeutral;
+
+    const ATL::CStringW szConfigPath;
+
+    static ATL::CStringW GetINIFullPath(const ATL::CStringW& FileName);
+    static VOID CacheINILocaleLazy();
+
+public:
+    static const ATL::CStringW& GetLocale();
+    static INT CConfigParser::GetLocaleSize();
+
+    CConfigParser(const ATL::CStringW& FileName);
+
+    UINT GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString);
+    UINT GetInt(const ATL::CStringW& KeyName);
+};
\ No newline at end of file
diff --git a/reactos/base/applications/rapps/include/unattended.h b/reactos/base/applications/rapps/include/unattended.h
new file mode 100644 (file)
index 0000000..15b2811
--- /dev/null
@@ -0,0 +1,8 @@
+#pragma once
+#include "windef.h"
+
+#define CMD_KEY_INSTALL L"/INSTALL"
+#define CMD_KEY_SETUP L"/SETUP"
+
+// return TRUE if the SETUP key was valid
+BOOL CmdParser(LPWSTR lpCmdLine);
\ No newline at end of file
index 564fda5..8658038 100644 (file)
@@ -793,7 +793,7 @@ end:
     return 0;
 }
 
-BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray<PAPPLICATION_INFO>& AppsList)
+BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray<PAPPLICATION_INFO>& AppsList, BOOL modal)
 {
     if (AppsList.GetSize() == 0)
     {
@@ -804,7 +804,7 @@ BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray<PAPPLI
     AppsToInstallList = AppsList;
 
     // Create a dialog and issue a download process
-    LaunchDownloadDialog(FALSE);
+    LaunchDownloadDialog(modal);
 
     return TRUE;
 }
index 1353828..4b15bad 100644 (file)
@@ -397,3 +397,109 @@ BOOL GetInstalledVersion(ATL::CStringW *pszVersion, const ATL::CStringW &szRegNa
                 || GetInstalledVersion_WowUser(pszVersion, szRegName, TRUE, KEY_WOW64_64KEY)
                 || GetInstalledVersion_WowUser(pszVersion, szRegName, FALSE, KEY_WOW64_64KEY)));
 }
+
+// CConfigParser
+ATL::CStringW CConfigParser::m_szLocaleID;
+ATL::CStringW CConfigParser::m_szCachedINISectionLocale;
+ATL::CStringW CConfigParser::m_szCachedINISectionLocaleNeutral;
+
+CConfigParser::CConfigParser(const ATL::CStringW& FileName) : szConfigPath(GetINIFullPath(FileName))
+{
+    // we don't have cached section strings for the current system language, create them, lazy
+    CacheINILocaleLazy();
+}
+
+ATL::CStringW CConfigParser::GetINIFullPath(const ATL::CStringW& FileName)
+{
+    ATL::CStringW szDir;
+    ATL::CStringW szBuffer;
+
+    GetStorageDirectory(szDir);
+    szBuffer.Format(L"%ls\\rapps\\%ls", szDir, FileName);
+
+    return szBuffer;
+}
+
+VOID CConfigParser::CacheINILocaleLazy()
+{
+    if (m_szLocaleID.IsEmpty())
+    {
+        // TODO: Set default locale if call fails
+        // find out what is the current system lang code (e.g. "0a") and append it to SectionLocale
+        GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_ILANGUAGE,
+                       m_szLocaleID.GetBuffer(m_cchLocaleSize), m_cchLocaleSize);
+
+        m_szLocaleID.ReleaseBuffer();
+        m_szCachedINISectionLocale = L"Section." + m_szLocaleID;
+
+        // turn "Section.0c0a" into "Section.0a", keeping just the neutral lang part
+        m_szCachedINISectionLocaleNeutral = m_szCachedINISectionLocale + m_szLocaleID.Right(2);
+    }
+}
+
+const ATL::CStringW& CConfigParser::GetLocale()
+{
+    CacheINILocaleLazy();
+    return m_szLocaleID;
+}
+
+INT CConfigParser::GetLocaleSize()
+{
+    return m_cchLocaleSize;
+}
+
+UINT CConfigParser::GetString(const ATL::CStringW& KeyName, ATL::CStringW& ResultString)
+{
+    DWORD dwResult;
+
+    LPWSTR ResultStringBuffer = ResultString.GetBuffer(MAX_PATH);
+    // 1st - find localized strings (e.g. "Section.0c0a")
+    dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocale.GetString(),
+                                        KeyName.GetString(),
+                                        NULL,
+                                        ResultStringBuffer,
+                                        MAX_PATH,
+                                        szConfigPath.GetString());
+
+    if (!dwResult)
+    {
+        // 2nd - if they weren't present check for neutral sub-langs/ generic translations (e.g. "Section.0a")
+        dwResult = GetPrivateProfileStringW(m_szCachedINISectionLocaleNeutral.GetString(),
+                                            KeyName.GetString(),
+                                            NULL,
+                                            ResultStringBuffer,
+                                            MAX_PATH,
+                                            szConfigPath.GetString());
+        if (!dwResult)
+        {
+            // 3rd - if they weren't present fallback to standard english strings (just "Section")
+            dwResult = GetPrivateProfileStringW(L"Section",
+                                                KeyName.GetString(),
+                                                NULL,
+                                                ResultStringBuffer,
+                                                MAX_PATH,
+                                                szConfigPath.GetString());
+        }
+    }
+
+    ResultString.ReleaseBuffer();
+    return (dwResult != 0 ? TRUE : FALSE);
+}
+
+UINT CConfigParser::GetInt(const ATL::CStringW& KeyName)
+{
+    ATL::CStringW Buffer;
+
+    // grab the text version of our entry
+    if (!GetString(KeyName, Buffer))
+        return FALSE;
+
+    if (Buffer.IsEmpty())
+        return FALSE;
+
+    // convert it to an actual integer
+    int result = StrToIntW(Buffer.GetString());
+
+    return (UINT) (result <= 0) ? 0 : result;
+}
+// CConfigParser
diff --git a/reactos/base/applications/rapps/unattended.cpp b/reactos/base/applications/rapps/unattended.cpp
new file mode 100644 (file)
index 0000000..0b66686
--- /dev/null
@@ -0,0 +1,70 @@
+#include "unattended.h"
+#include "defines.h"
+#include "available.h"
+#include "dialogs.h"
+
+#include "setupapi.h"
+
+BOOL CmdParser(LPWSTR lpCmdLine)
+{
+    INT argc;
+    LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
+    ATL::CString szName;
+
+    if (!argv || argc < 2)
+    {
+        return FALSE;
+    }
+
+    // Setup key - single app expected
+    // TODO: add multiple apps
+    // TODO: use DB filenames as names because they're shorter
+
+    // app setup
+    ATL::CSimpleArray<ATL::CStringW> arrNames;
+    if (!StrCmpW(argv[0], CMD_KEY_INSTALL))
+    {
+        for (int i = 1; i < argc; ++i)
+        {
+            arrNames.Add(argv[i]);
+        }       
+    } 
+    else 
+    if (!StrCmpW(argv[0], CMD_KEY_SETUP))
+    {
+        //TODO: inf file loading
+        HINF InfHandle = SetupOpenInfFileW(argv[1], NULL, INF_STYLE_WIN4, NULL);
+        if (InfHandle == INVALID_HANDLE_VALUE)
+        {
+            return FALSE;
+        }
+
+        INFCONTEXT Context;
+        if (!SetupFindFirstLineW(InfHandle, L"RAPPS", L"Install", &Context))
+        {
+            return FALSE;
+        }
+
+        WCHAR szName[MAX_PATH];
+        do
+        {
+            if (SetupGetStringFieldW(&Context, 1, szName, MAX_PATH, NULL))
+            {
+                arrNames.Add(szName);
+            }
+        } 
+        while (SetupFindNextLine(&Context, &Context));
+    }
+
+    CAvailableApps apps;
+    apps.EnumAvailableApplications(ENUM_ALL_AVAILABLE, NULL);
+    ATL::CSimpleArray<PAPPLICATION_INFO> arrAppInfo = apps.FindInfoList(arrNames);
+    if (arrAppInfo.GetSize() > 0)
+    {
+        CDownloadManager::DownloadListOfApplications(arrAppInfo, TRUE);
+        return TRUE;
+    }
+    
+    return FALSE;
+}
+
index 5fa47d6..084ce55 100644 (file)
@@ -8,12 +8,10 @@
  *                  Alexander Shaposhnikov     (chaez.san@gmail.com)
  */
 #include "defines.h"
-
 #include "rapps.h"
+#include "unattended.h"
 
-#include <atlbase.h>
 #include <atlcom.h>
-#include <shellapi.h>
 
 HWND hMainWnd;
 HINSTANCE hInst;
@@ -132,39 +130,11 @@ VOID SaveSettings(HWND hwnd)
     }
 }
 
-
-#define CMD_KEY_SETUP L"/SETUP"
-
-// return TRUE if the SETUP key was valid
-BOOL CmdParser(LPWSTR lpCmdLine)
-{
-    INT argc;
-    LPWSTR* argv = CommandLineToArgvW(lpCmdLine, &argc);
-    CAvailableApps apps;
-    PAPPLICATION_INFO appInfo;
-    ATL::CString szName;
-
-    if (!argv || argc < 2 || StrCmpW(argv[0], CMD_KEY_SETUP))
-    {
-        return FALSE;
-    }
-
-    apps.EnumAvailableApplications(ENUM_ALL_AVAILABLE, NULL);
-    appInfo = apps.FindInfo(argv[1]);
-    if (appInfo)
-    {
-        CDownloadManager::DownloadApplication(appInfo, TRUE);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
 INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nShowCmd)
 {
     LPCWSTR szWindowClass = L"ROSAPPMGR";
-    HANDLE hMutex = NULL;
-    HACCEL KeyBrd = NULL;
+    HANDLE hMutex;
+    HACCEL KeyBrd;
     MSG Msg;
 
     InitializeAtlModule(hInstance, TRUE);