- 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
This commit is contained in:
Alexander Shaposhnikov 2017-08-15 19:36:23 +00:00
parent a59f6f7573
commit 14be048f6f
10 changed files with 238 additions and 172 deletions

View 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)

View 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

View 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();

View 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);

View 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);
};

View file

@ -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);

View 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;
}

View 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

View file

@ -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;
}

View 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);