Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12 kB · 452 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453/* * PROJECT: ReactOS Applications Manager * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Functions to parse command-line flags and process them * COPYRIGHT: Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org) * Copyright 2020 He Yang (1160386205@qq.com) */
#include "gui.h"#include "unattended.h"#include "configparser.h"#include <setupapi.h>#include <conutils.h>
static BOOLMatchCmdOption(LPWSTR argvOption, LPCWSTR szOptToMacth){ WCHAR FirstCharList[] = {L'-', L'/'};
for (UINT i = 0; i < _countof(FirstCharList); i++) { if (argvOption[0] == FirstCharList[i]) { return StrCmpIW(argvOption + 1, szOptToMacth) == 0; } } return FALSE;}
static voidInitRappsConsole(){ // First, try to attach to our parent's console if (!AttachConsole(ATTACH_PARENT_PROCESS)) { // Did we already have a console? if (GetLastError() != ERROR_ACCESS_DENIED) { // No, try to open a new one AllocConsole(); } } ConInitStdStreams(); // Initialize the Console Standard Streams}
static CAppInfo *SearchForAppWithDisplayName(CAppDB &db, AppsCategories Type, LPCWSTR Name){ CAtlList<CAppInfo *> List; db.GetApps(List, Type); for (POSITION it = List.GetHeadPosition(); it;) { CAppInfo *Info = List.GetNext(it); if (SearchPatternMatch(Info->szDisplayName, Name)) { return Info; } } return NULL;}
static BOOLHandleInstallCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft){ UINT flags = DAF_MODAL; if (argcLeft >= 1 && !StrCmpIW(L"/S", argvLeft[0])) { flags |= DAF_SILENT; argvLeft = &argvLeft[1], --argcLeft; }
if (argcLeft < 1) { InitRappsConsole(); ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_PACKAGE_NAME, szCommand); return FALSE; }
CAtlList<CAppInfo *> Applications; for (int i = 0; i < argcLeft; i++) { LPCWSTR PackageName = argvLeft[i]; CAppInfo *AppInfo = db->FindByPackageName(PackageName); if (AppInfo) { Applications.AddTail(AppInfo); } }
return DownloadListOfApplications(Applications, flags);}
static BOOLHandleSetupCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft){ UINT flags = DAF_MODAL; if (argcLeft >= 1 && !StrCmpIW(L"/S", argvLeft[0])) { flags |= DAF_SILENT; argvLeft = &argvLeft[1], --argcLeft; }
if (argcLeft != 1) { InitRappsConsole(); ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_FILE_NAME, szCommand); return FALSE; }
CAtlList<CAppInfo *> Applications; HINF InfHandle = SetupOpenInfFileW(argvLeft[0], NULL, INF_STYLE_WIN4, NULL); if (InfHandle == INVALID_HANDLE_VALUE) { return FALSE; }
INFCONTEXT Context; if (SetupFindFirstLineW(InfHandle, L"RAPPS", L"Install", &Context)) { WCHAR szPkgName[MAX_PATH]; do { if (SetupGetStringFieldW(&Context, 1, szPkgName, _countof(szPkgName), NULL)) { CAppInfo *AppInfo = db->FindByPackageName(szPkgName); if (AppInfo) { Applications.AddTail(AppInfo); } } } while (SetupFindNextLine(&Context, &Context)); } SetupCloseInfFile(InfHandle);
return DownloadListOfApplications(Applications, flags);}
static BOOLHandleUninstallCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft){ UINT argi = 0, silent = FALSE, byregkeyname = FALSE; for (; argcLeft; ++argi, --argcLeft) { if (!StrCmpIW(argvLeft[argi], L"/S")) ++silent; else if (!StrCmpIW(argvLeft[argi], L"/K")) ++byregkeyname; else break; } if (argcLeft != 1) return FALSE;
CStringW buf; LPCWSTR name = argvLeft[argi]; BOOL retval = FALSE; CAppInfo *pInfo = NULL, *pDelete = NULL;
if (!byregkeyname) { for (UINT i = ENUM_INSTALLED_MIN; !pInfo && i <= ENUM_INSTALLED_MAX; ++i) { pInfo = SearchForAppWithDisplayName(db, AppsCategories(i), name); }
if (!pInfo) { CAvailableApplicationInfo *p = db.FindAvailableByPackageName(name); if (p) { CConfigParser *cp = p->GetConfigParser(); if (cp && cp->GetString(DB_REGNAME, buf) && !buf.IsEmpty()) { name = buf.GetString(); byregkeyname = TRUE; } } } }
if (byregkeyname) { // Force a specific key type if requested (<M|U>[32|64]<\\KeyName>) if (name[0]) { REGSAM wow = 0; UINT i = 1; if (name[i] == '3' && name[i + 1]) wow = KEY_WOW64_32KEY, i += 2; else if (name[i] == '6' && name[i + 1]) wow = KEY_WOW64_64KEY, i += 2;
if (name[i++] == '\\') { pInfo = CAppDB::CreateInstalledAppInstance(name + i, name[0] == 'U', wow); } }
if (!pInfo) { pInfo = CAppDB::CreateInstalledAppByRegistryKey(name); } pDelete = pInfo; }
if (pInfo) { retval = pInfo->UninstallApplication((silent ? UCF_SILENT : UCF_NONE) | UCF_SAMEPROCESS); } delete pDelete; return retval;}
static BOOLHandleGenerateInstallerCommand(CAppDB &db, UINT argcLeft, LPWSTR *argvLeft){ bool bSilent = false; if (argcLeft && !StrCmpIW(argvLeft[0], L"/S")) { bSilent = true; --argcLeft; ++argvLeft; }
if (argcLeft != 2) return FALSE;
CAvailableApplicationInfo *pAI = db.FindAvailableByPackageName(argvLeft[0]); if (!pAI) return FALSE;
return ExtractAndRunGeneratedInstaller(*pAI, argvLeft[1], bSilent);}
static BOOLHandleFindCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft){ if (argcLeft < 1) { ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_PARAMS, szCommand); return FALSE; }
CAtlList<CAppInfo *> List; db->GetApps(List, ENUM_ALL_AVAILABLE);
for (int i = 0; i < argcLeft; i++) { LPCWSTR lpszSearch = argvLeft[i]; ConResMsgPrintf(StdOut, NULL, IDS_CMD_FIND_RESULT_FOR, lpszSearch);
POSITION CurrentListPosition = List.GetHeadPosition(); while (CurrentListPosition) { CAppInfo *Info = List.GetNext(CurrentListPosition);
if (SearchPatternMatch(Info->szDisplayName, lpszSearch) || SearchPatternMatch(Info->szComments, lpszSearch)) { ConPrintf(StdOut, L"%s (%s)\n", Info->szDisplayName.GetString(), Info->szIdentifier.GetString()); } }
ConPrintf(StdOut, L"\n"); }
return TRUE;}
static BOOLHandleInfoCommand(CAppDB *db, LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft){ if (argcLeft < 1) { ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_PARAMS, szCommand); return FALSE; }
for (int i = 0; i < argcLeft; i++) { LPCWSTR PackageName = argvLeft[i]; CAppInfo *AppInfo = db->FindByPackageName(PackageName); if (!AppInfo) { ConResMsgPrintf(StdOut, NULL, IDS_CMD_PACKAGE_NOT_FOUND, PackageName); } else { ConResMsgPrintf(StdOut, NULL, IDS_CMD_PACKAGE_INFO, PackageName);
ConPuts(StdOut, AppInfo->szDisplayName);
if (!AppInfo->szDisplayVersion.IsEmpty()) { ConResPrintf(StdOut, IDS_AINFO_VERSION); ConPuts(StdOut, AppInfo->szDisplayVersion); }
CStringW License, Size, UrlSite, UrlDownload; AppInfo->GetDisplayInfo(License, Size, UrlSite, UrlDownload);
if (!License.IsEmpty()) { ConResPrintf(StdOut, IDS_AINFO_LICENSE); ConPuts(StdOut, License); }
if (!Size.IsEmpty()) { ConResPrintf(StdOut, IDS_AINFO_SIZE); ConPuts(StdOut, Size); }
if (!UrlSite.IsEmpty()) { ConResPrintf(StdOut, IDS_AINFO_URLSITE); ConPuts(StdOut, UrlSite); }
if (AppInfo->szComments) { ConResPrintf(StdOut, IDS_AINFO_DESCRIPTION); ConPuts(StdOut, AppInfo->szComments); }
if (!UrlDownload.IsEmpty()) { ConResPrintf(StdOut, IDS_AINFO_URLDOWNLOAD); ConPuts(StdOut, UrlDownload); } ConPuts(StdOut, L"\n"); } ConPuts(StdOut, L"\n"); } return TRUE;}
static VOIDPrintHelpCommand(){ ConPrintf(StdOut, L"\n"); ConResPuts(StdOut, IDS_APPTITLE); ConPrintf(StdOut, L"\n\n");
ConResPuts(StdOut, IDS_CMD_USAGE); ConPrintf(StdOut, L"%ls\n", UsageString);}
BOOLParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow){ INT argc; LPWSTR *argv = CommandLineToArgvW(lpCmdLine, &argc); if (!argv) return FALSE;
CAppDB db(CAppDB::GetDefaultPath());
BOOL bAppwizMode = (argc > 1 && MatchCmdOption(argv[1], CMD_KEY_APPWIZ)); if (!bAppwizMode) { CUpdateDatabaseMutex lock; if (SettingsInfo.bUpdateAtStart || bIsFirstLaunch) db.RemoveCached();
db.UpdateAvailable(); }
db.UpdateInstalled();
if (argc == 1 || bAppwizMode) // RAPPS is launched without options or APPWIZ mode is requested { // Check whether the RAPPS MainWindow is already launched in another process CStringW szWindowText(MAKEINTRESOURCEW(bAppwizMode ? IDS_APPWIZ_TITLE : IDS_APPTITLE)); LPCWSTR pszMutex = bAppwizMode ? L"RAPPWIZ" : MAINWINDOWMUTEX;
HANDLE hMutex = CreateMutexW(NULL, FALSE, pszMutex); if ((!hMutex) || (GetLastError() == ERROR_ALREADY_EXISTS)) { /* If already started, find its window */ HWND hWindow; for (int wait = 2500, inter = 250; wait > 0; wait -= inter) { if ((hWindow = FindWindowW(szWindowClass, szWindowText)) != NULL) break; Sleep(inter); }
if (hWindow) { /* Activate the window in the other instance */ ShowWindow(hWindow, SW_SHOWNA); SwitchToThisWindow(hWindow, TRUE); if (bAppwizMode) PostMessage(hWindow, WM_COMMAND, ID_ACTIVATE_APPWIZ, 0);
if (hMutex) CloseHandle(hMutex);
return FALSE; } } szWindowText.Empty();
CMainWindow wnd(&db, bAppwizMode); MainWindowLoop(&wnd, nCmdShow);
if (hMutex) CloseHandle(hMutex);
return TRUE; }
if (MatchCmdOption(argv[1], CMD_KEY_INSTALL)) { return HandleInstallCommand(&db, argv[1], argc - 2, argv + 2); } else if (MatchCmdOption(argv[1], CMD_KEY_SETUP)) { return HandleSetupCommand(&db, argv[1], argc - 2, argv + 2); } else if (MatchCmdOption(argv[1], CMD_KEY_UNINSTALL)) { return HandleUninstallCommand(db, argc - 2, argv + 2); } else if (MatchCmdOption(argv[1], CMD_KEY_GENINST)) { return HandleGenerateInstallerCommand(db, argc - 2, argv + 2); }
InitRappsConsole();
if (MatchCmdOption(argv[1], CMD_KEY_FIND)) { return HandleFindCommand(&db, argv[1], argc - 2, argv + 2); } else if (MatchCmdOption(argv[1], CMD_KEY_INFO)) { return HandleInfoCommand(&db, argv[1], argc - 2, argv + 2); } else if (MatchCmdOption(argv[1], CMD_KEY_HELP) || MatchCmdOption(argv[1], CMD_KEY_HELP_ALT)) { PrintHelpCommand(); return TRUE; } else { // unrecognized/invalid options ConResPuts(StdOut, IDS_CMD_INVALID_OPTION); PrintHelpCommand(); return FALSE; }}