From 14be048f6f5bcaa9225663586a63d7a255ee9dec Mon Sep 17 00:00:00 2001 From: Alexander Shaposhnikov Date: Tue, 15 Aug 2017 19:36:23 +0000 Subject: [PATCH] [RAPPS] - 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 --- .../base/applications/rapps/CMakeLists.txt | 4 +- reactos/base/applications/rapps/available.cpp | 120 ++---------------- .../applications/rapps/include/available.h | 28 +--- .../base/applications/rapps/include/dialogs.h | 2 +- .../base/applications/rapps/include/misc.h | 32 ++++- .../applications/rapps/include/unattended.h | 8 ++ reactos/base/applications/rapps/loaddlg.cpp | 4 +- reactos/base/applications/rapps/misc.cpp | 106 ++++++++++++++++ .../base/applications/rapps/unattended.cpp | 70 ++++++++++ reactos/base/applications/rapps/winmain.cpp | 36 +----- 10 files changed, 238 insertions(+), 172 deletions(-) create mode 100644 reactos/base/applications/rapps/include/unattended.h create mode 100644 reactos/base/applications/rapps/unattended.cpp diff --git a/reactos/base/applications/rapps/CMakeLists.txt b/reactos/base/applications/rapps/CMakeLists.txt index 500834ffa43..6efc9a41b54 100644 --- a/reactos/base/applications/rapps/CMakeLists.txt +++ b/reactos/base/applications/rapps/CMakeLists.txt @@ -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) diff --git a/reactos/base/applications/rapps/available.cpp b/reactos/base/applications/rapps/available.cpp index 0ae86ac4510..23db36b0d80 100644 --- a/reactos/base/applications/rapps/available.cpp +++ b/reactos/base/applications/rapps/available.cpp @@ -379,6 +379,20 @@ const PAPPLICATION_INFO CAvailableApps::FindInfo(const ATL::CStringW& szAppName) return NULL; } +ATL::CSimpleArray CAvailableApps::FindInfoList(const ATL::CSimpleArray &arrAppsNames) +{ + ATL::CSimpleArray 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 diff --git a/reactos/base/applications/rapps/include/available.h b/reactos/base/applications/rapps/include/available.h index 5221e762095..6b26fcd0d64 100644 --- a/reactos/base/applications/rapps/include/available.h +++ b/reactos/base/applications/rapps/include/available.h @@ -1,8 +1,10 @@ #pragma once + #include #include #include #include +#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 FindInfoList(const ATL::CSimpleArray &arrAppsNames); const ATL::CStringW& GetFolderPath(); const ATL::CStringW& GetAppPath(); const ATL::CStringW& GetCabPath(); diff --git a/reactos/base/applications/rapps/include/dialogs.h b/reactos/base/applications/rapps/include/dialogs.h index e90d351c1b1..08886ee9cad 100644 --- a/reactos/base/applications/rapps/include/dialogs.h +++ b/reactos/base/applications/rapps/include/dialogs.h @@ -25,7 +25,7 @@ public: DWORD_PTR dwRefData); static DWORD WINAPI ThreadFunc(LPVOID Context); - static BOOL DownloadListOfApplications(const ATL::CSimpleArray& AppsList); + static BOOL DownloadListOfApplications(const ATL::CSimpleArray& AppsList, BOOL modal = FALSE); static BOOL DownloadApplication(PAPPLICATION_INFO pAppInfo, BOOL modal = FALSE); static VOID DownloadApplicationsDB(LPCWSTR lpUrl); static VOID LaunchDownloadDialog(BOOL); diff --git a/reactos/base/applications/rapps/include/misc.h b/reactos/base/applications/rapps/include/misc.h index c27007d9b1d..878f5bb9a93 100644 --- a/reactos/base/applications/rapps/include/misc.h +++ b/reactos/base/applications/rapps/include/misc.h @@ -3,10 +3,10 @@ #include #include -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 index 00000000000..15b2811d29c --- /dev/null +++ b/reactos/base/applications/rapps/include/unattended.h @@ -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 diff --git a/reactos/base/applications/rapps/loaddlg.cpp b/reactos/base/applications/rapps/loaddlg.cpp index 564fda5e2d6..86580383359 100644 --- a/reactos/base/applications/rapps/loaddlg.cpp +++ b/reactos/base/applications/rapps/loaddlg.cpp @@ -793,7 +793,7 @@ end: return 0; } -BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray& AppsList) +BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray& AppsList, BOOL modal) { if (AppsList.GetSize() == 0) { @@ -804,7 +804,7 @@ BOOL CDownloadManager::DownloadListOfApplications(const ATL::CSimpleArray 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 arrAppInfo = apps.FindInfoList(arrNames); + if (arrAppInfo.GetSize() > 0) + { + CDownloadManager::DownloadListOfApplications(arrAppInfo, TRUE); + return TRUE; + } + + return FALSE; +} + diff --git a/reactos/base/applications/rapps/winmain.cpp b/reactos/base/applications/rapps/winmain.cpp index 5fa47d6ecf2..084ce55dbc0 100644 --- a/reactos/base/applications/rapps/winmain.cpp +++ b/reactos/base/applications/rapps/winmain.cpp @@ -8,12 +8,10 @@ * Alexander Shaposhnikov (chaez.san@gmail.com) */ #include "defines.h" - #include "rapps.h" +#include "unattended.h" -#include #include -#include 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);