https://git.reactos.org/?p=reactos.git;a=commitdiff;h=72951421e6780b85ac125…
commit 72951421e6780b85ac1254f7561425ef3b6eb5a9
Author: Whindmar Saksit <whindsaks(a)proton.me>
AuthorDate: Sat Jan 25 16:42:48 2025 +0100
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Jan 25 16:42:48 2025 +0100
[RAPPS] Reuse active pending downloads window (#7648)
CORE-16716 CORE-16804
---
base/applications/rapps/gui.cpp | 2 +-
base/applications/rapps/loaddlg.cpp | 1094 ++++++++++++++++++-----------------
2 files changed, 551 insertions(+), 545 deletions(-)
diff --git a/base/applications/rapps/gui.cpp b/base/applications/rapps/gui.cpp
index 5e8dc85a8ba..6f2e1a1d3d8 100644
--- a/base/applications/rapps/gui.cpp
+++ b/base/applications/rapps/gui.cpp
@@ -816,7 +816,7 @@ CMainWindow::InstallApplication(CAppInfo *Info)
{
if (DownloadApplication(Info))
{
- UpdateApplicationsList(SelectedEnumType);
+ //FIXME: Delay UpdateApplicationsList(SelectedEnumType); until install
completes
return TRUE;
}
}
diff --git a/base/applications/rapps/loaddlg.cpp b/base/applications/rapps/loaddlg.cpp
index c0ca9d135dc..df8afcbeeea 100644
--- a/base/applications/rapps/loaddlg.cpp
+++ b/base/applications/rapps/loaddlg.cpp
@@ -119,6 +119,19 @@ UrlUnescapeAndMakeFileNameValid(CStringW& str)
str = szPath;
}
+static void
+SetFriendlyUrl(HWND hWnd, LPCWSTR pszUrl)
+{
+ CStringW buf;
+ DWORD cch = (DWORD)(wcslen(pszUrl) + 1);
+ if (InternetCanonicalizeUrlW(pszUrl, buf.GetBuffer(cch), &cch, ICU_DECODE |
ICU_NO_ENCODE))
+ {
+ buf.ReleaseBuffer();
+ pszUrl = buf;
+ }
+ SetWindowTextW(hWnd, pszUrl);
+}
+
struct DownloadInfo
{
DownloadInfo() : DLType(DLTYPE_APPLICATION), IType(INSTALLER_UNKNOWN),
SizeInBytes(0)
@@ -130,9 +143,12 @@ struct DownloadInfo
szName = AppInfo.szDisplayName;
IType = AppInfo.GetInstallerType();
if (IType == INSTALLER_GENERATE)
- {
szPackageName = AppInfo.szIdentifier;
- }
+ }
+
+ bool Equal(const DownloadInfo &other) const
+ {
+ return DLType == other.DLType && !lstrcmpW(szUrl, other.szUrl);
}
DownloadType DLType;
@@ -144,21 +160,6 @@ struct DownloadInfo
ULONG SizeInBytes;
};
-struct DownloadParam
-{
- DownloadParam() : Dialog(NULL), AppInfo(), szCaption(NULL)
- {
- }
- DownloadParam(HWND dlg, const ATL::CSimpleArray<DownloadInfo> &info,
LPCWSTR caption)
- : Dialog(dlg), AppInfo(info), szCaption(caption)
- {
- }
-
- HWND Dialog;
- ATL::CSimpleArray<DownloadInfo> AppInfo;
- LPCWSTR szCaption;
-};
-
class CDownloaderProgress : public CWindowImpl<CDownloaderProgress, CWindow,
CControlWinTraits>
{
CStringW m_szProgressText;
@@ -313,7 +314,7 @@ class CDowloadingAppsListView : public CListView
RECT r;
::GetClientRect(hwndParent, &r);
r.top = (2 * r.top + 1 * r.bottom) / 3; /* The vertical position at ratio 1 : 2
*/
-#define MARGIN 10
+ const INT MARGIN = 10;
::InflateRect(&r, -MARGIN, -MARGIN);
const DWORD style = WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL |
LVS_SHOWSELALWAYS | LVS_NOSORTHEADER |
@@ -328,11 +329,12 @@ class CDowloadingAppsListView : public CListView
}
VOID
- LoadList(ATL::CSimpleArray<DownloadInfo> arrInfo)
+ LoadList(ATL::CSimpleArray<DownloadInfo> arrInfo, UINT Start = 0)
{
- for (INT i = 0; i < arrInfo.GetSize(); ++i)
+ const INT base = GetItemCount();
+ for (INT i = Start; i < arrInfo.GetSize(); ++i)
{
- AddRow(i, arrInfo[i].szName.GetString(), DLSTATUS_WAITING);
+ AddRow(base + i - Start, arrInfo[i].szName, DLSTATUS_WAITING);
}
}
@@ -420,7 +422,7 @@ CertGetSubjectAndIssuer(HINTERNET hFile, CLocalPtr<char>
&subjectInfo, CLocalPtr
}
#endif
-inline VOID
+static inline VOID
MessageBox_LoadString(HWND hOwnerWnd, INT StringID)
{
CStringW szMsgText;
@@ -430,65 +432,175 @@ MessageBox_LoadString(HWND hOwnerWnd, INT StringID)
}
}
+static BOOL
+ShowLastError(HWND hWndOwner, BOOL bInetError, DWORD dwLastError)
+{
+ CLocalPtr<WCHAR> lpMsg;
+
+ if (!FormatMessageW(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |
+ (bInetError ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM),
+ (bInetError ? GetModuleHandleW(L"wininet.dll") : NULL),
dwLastError, LANG_USER_DEFAULT, (LPWSTR)&lpMsg, 0,
+ NULL))
+ {
+ DPRINT1("FormatMessageW unexpected failure (err %d)\n",
GetLastError());
+ return FALSE;
+ }
+
+ MessageBoxW(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
+ return TRUE;
+}
+
// Download dialog (loaddlg.cpp)
-class CDownloadManager
+HWND g_hDownloadWnd = NULL;
+
+class CDownloadManager :
+ public CComCoClass<CDownloadManager, &CLSID_NULL>,
+ public CComObjectRootEx<CComMultiThreadModelNoCS>,
+ public IUnknown
{
- static ATL::CSimpleArray<DownloadInfo> AppsDownloadList;
- static CDowloadingAppsListView DownloadsListView;
- static CDownloaderProgress ProgressBar;
- static BOOL bCancelled;
- static BOOL bModal;
- static VOID
- UpdateProgress(HWND hDlg, ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode,
LPCWSTR szStatusText);
+public:
+ enum {
+ WM_ISCANCELLED = WM_APP, // Return BOOL
+ WM_SETSTATUS, // wParam DownloadStatus
+ WM_GETINSTANCE, // Return CDownloadManager*
+ WM_GETNEXT, // Return DownloadInfo* or NULL
+ };
+
+ CDownloadManager() : m_hDlg(NULL), m_Threads(0), m_Index(0), m_bCancelled(FALSE) {}
+
+ static CDownloadManager*
+ CreateInstanceHelper(BOOL Modal)
+ {
+ if (!Modal)
+ {
+ CDownloadManager* pExisting = CDownloadManager::FindInstance();
+ if (pExisting)
+ {
+ pExisting->AddRef();
+ return pExisting;
+ }
+ }
+ CComPtr<CDownloadManager> obj;
+ if (FAILED(ShellObjectCreator(obj)))
+ return NULL;
+ obj->m_bModal = Modal;
+ return obj.Detach();
+ }
- public:
- static VOID
- Add(DownloadInfo info);
- static VOID
- Download(const DownloadInfo &DLInfo, BOOL bIsModal = FALSE);
- static INT_PTR CALLBACK
- DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
- static unsigned int WINAPI
- ThreadFunc(LPVOID Context);
- static VOID LaunchDownloadDialog(BOOL);
+ static BOOL
+ CreateInstance(BOOL Modal, CComPtr<CDownloadManager> &Obj)
+ {
+ CDownloadManager *p = CreateInstanceHelper(Modal);
+ if (!p)
+ return FALSE;
+ Obj.Attach(p);
+ return TRUE;
+ }
+
+ static CDownloadManager*
+ FindInstance()
+ {
+ if (g_hDownloadWnd)
+ return (CDownloadManager*)SendMessageW(g_hDownloadWnd, WM_GETINSTANCE, 0,
0);
+ return NULL;
+ }
+
+ BOOL
+ IsCancelled()
+ {
+ return !IsWindow(m_hDlg) || SendMessageW(m_hDlg, WM_ISCANCELLED, 0, 0);
+ }
+
+ void StartWorkerThread();
+ void Add(const DownloadInfo &Info);
+ void Show();
+ static INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ INT_PTR RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
+ void UpdateProgress(ULONG ulProgress, ULONG ulProgressMax);
+ static unsigned int CALLBACK ThreadFunc(void*ThreadParam);
+ void PerformDownloadAndInstall(const DownloadInfo &Info);
+
+ DECLARE_NO_REGISTRY()
+ DECLARE_NOT_AGGREGATABLE(CDownloadManager)
+ BEGIN_COM_MAP(CDownloadManager)
+ END_COM_MAP()
+
+protected:
+ HWND m_hDlg;
+ UINT m_Threads;
+ UINT m_Index;
+ BOOL m_bCancelled;
+ BOOL m_bModal;
+ WCHAR m_szCaptionFmt[100];
+ ATL::CSimpleArray<DownloadInfo> m_List;
+ CDowloadingAppsListView m_ListView;
+ CDownloaderProgress m_ProgressBar;
};
-// CDownloadManager
-ATL::CSimpleArray<DownloadInfo> CDownloadManager::AppsDownloadList;
-CDowloadingAppsListView CDownloadManager::DownloadsListView;
-CDownloaderProgress CDownloadManager::ProgressBar;
-BOOL CDownloadManager::bCancelled = FALSE;
-BOOL CDownloadManager::bModal = FALSE;
+void
+CDownloadManager::StartWorkerThread()
+{
+ AddRef(); // To keep m_List alive in thread
+ unsigned int ThreadId;
+ HANDLE Thread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, this, 0, &ThreadId);
+ if (Thread)
+ CloseHandle(Thread);
+ else
+ Release();
+}
-VOID
-CDownloadManager::Add(DownloadInfo info)
+void
+CDownloadManager::Add(const DownloadInfo &Info)
{
- AppsDownloadList.Add(info);
+ const UINT count = m_List.GetSize(), start = count;
+ for (UINT i = 0; i < count; ++i)
+ {
+ if (Info.Equal(m_List[i]))
+ return; // Already in the list
+ }
+ m_List.Add(Info);
+ if (m_hDlg)
+ m_ListView.LoadList(m_List, start);
}
-VOID
-CDownloadManager::Download(const DownloadInfo &DLInfo, BOOL bIsModal)
+void
+CDownloadManager::Show()
{
- AppsDownloadList.RemoveAll();
- AppsDownloadList.Add(DLInfo);
- LaunchDownloadDialog(bIsModal);
+ if (m_bModal)
+ DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd, DlgProc,
(LPARAM)this);
+ else if (!m_hDlg || !IsWindow(m_hDlg))
+ CreateDialogParamW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd,
DlgProc, (LPARAM)this);
}
INT_PTR CALLBACK
-CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+CDownloadManager::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
- static WCHAR szCaption[MAX_PATH];
+ CDownloadManager* pThis = (CDownloadManager*)GetWindowLongPtrW(hDlg, DWLP_USER);
+ if (!pThis)
+ {
+ if (uMsg != WM_INITDIALOG)
+ return FALSE;
+ SetWindowLongPtrW(hDlg, DWLP_USER, lParam);
+ pThis = (CDownloadManager*)lParam;
+ }
+ return pThis->RealDlgProc(hDlg, uMsg, wParam, lParam);
+}
+INT_PTR
+CDownloadManager::RealDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
switch (uMsg)
{
case WM_INITDIALOG:
{
g_Busy++;
- HICON hIconSm, hIconBg;
- CStringW szTempCaption;
-
- bCancelled = FALSE;
+ AddRef();
+ m_hDlg = hDlg;
+ if (!m_bModal)
+ g_hDownloadWnd = hDlg;
+ HICON hIconSm, hIconBg;
if (hMainWnd)
{
hIconBg = (HICON)GetClassLongPtrW(hMainWnd, GCLP_HICON);
@@ -496,630 +608,515 @@ CDownloadManager::DownloadDlgProc(HWND Dlg, UINT uMsg, WPARAM
wParam, LPARAM lPa
}
if (!hMainWnd || (!hIconBg || !hIconSm))
{
- /* Load the default icon */
hIconBg = hIconSm = LoadIconW(hInst, MAKEINTRESOURCEW(IDI_MAIN));
}
+ SendMessageW(hDlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBg);
+ SendMessageW(hDlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
- if (hIconBg && hIconSm)
- {
- SendMessageW(Dlg, WM_SETICON, ICON_BIG, (LPARAM)hIconBg);
- SendMessageW(Dlg, WM_SETICON, ICON_SMALL, (LPARAM)hIconSm);
- }
+ GetWindowTextW(hDlg, m_szCaptionFmt, _countof(m_szCaptionFmt));
+ CStringW buf;
+ buf = m_szCaptionFmt;
+ buf.Replace(L"%ls", L"");
+ SetWindowTextW(hDlg, buf); // "Downloading..."
- HWND Item = GetDlgItem(Dlg, IDC_DOWNLOAD_PROGRESS);
- if (Item)
+ HWND hItem = GetDlgItem(hDlg, IDC_DOWNLOAD_PROGRESS);
+ if (hItem)
{
// initialize the default values for our nifty progress bar
// and subclass it so that it learns to print a status text
- ProgressBar.SubclassWindow(Item);
- ProgressBar.SendMessage(PBM_SETRANGE, 0, MAKELPARAM(0, 100));
- ProgressBar.SendMessage(PBM_SETPOS, 0, 0);
- if (AppsDownloadList.GetSize() > 0)
- ProgressBar.SetProgress(0, AppsDownloadList[0].SizeInBytes);
- }
-
- // Add a ListView
- HWND hListView = DownloadsListView.Create(Dlg);
- if (!hListView)
- {
- return FALSE;
+ m_ProgressBar.SubclassWindow(hItem);
+ m_ProgressBar.SendMessageW(PBM_SETRANGE, 0, MAKELPARAM(0, 100));
+ m_ProgressBar.SendMessageW(PBM_SETPOS, 0, 0);
+ if (m_List.GetSize() > 0)
+ m_ProgressBar.SetProgress(0, m_List[0].SizeInBytes);
}
- DownloadsListView.LoadList(AppsDownloadList);
- // Get a dlg string for later use
- GetWindowTextW(Dlg, szCaption, _countof(szCaption));
-
- // Hide a placeholder from displaying
- szTempCaption = szCaption;
- szTempCaption.Replace(L"%ls", L"");
- SetWindowText(Dlg, szTempCaption.GetString());
-
- ShowWindow(Dlg, SW_SHOW);
-
- // Start download process
- DownloadParam *param = new DownloadParam(Dlg, AppsDownloadList, szCaption);
- unsigned int ThreadId;
- HANDLE Thread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, (void *)param, 0,
&ThreadId);
- if (!Thread)
- {
+ if (!m_ListView.Create(hDlg))
return FALSE;
- }
+ m_ListView.LoadList(m_List);
- CloseHandle(Thread);
- AppsDownloadList.RemoveAll();
+ ShowWindow(hDlg, SW_SHOW);
+ StartWorkerThread();
return TRUE;
}
case WM_COMMAND:
- if (wParam == IDCANCEL)
+ if (LOWORD(wParam) == IDCANCEL)
{
- bCancelled = TRUE;
- PostMessageW(Dlg, WM_CLOSE, 0, 0);
+ m_bCancelled = TRUE;
+ PostMessageW(hDlg, WM_CLOSE, 0, 0);
}
return FALSE;
case WM_CLOSE:
- if (ProgressBar)
- ProgressBar.UnsubclassWindow(TRUE);
- if (CDownloadManager::bModal)
- {
- ::EndDialog(Dlg, 0);
- }
- else
- {
- ::DestroyWindow(Dlg);
- }
- return TRUE;
+ m_bCancelled = TRUE;
+ if (m_ProgressBar)
+ m_ProgressBar.UnsubclassWindow(TRUE);
+ return m_bModal ? ::EndDialog(hDlg, 0) : ::DestroyWindow(hDlg);
case WM_DESTROY:
+ if (g_hDownloadWnd == hDlg)
+ g_hDownloadWnd = NULL;
g_Busy--;
if (hMainWnd)
PostMessage(hMainWnd, WM_NOTIFY_OPERATIONCOMPLETED, 0, 0);
- return FALSE;
-
- default:
- return FALSE;
- }
-}
-
-BOOL UrlHasBeenCopied;
+ Release();
+ break;
-VOID
-CDownloadManager::UpdateProgress(
- HWND hDlg,
- ULONG ulProgress,
- ULONG ulProgressMax,
- ULONG ulStatusCode,
- LPCWSTR szStatusText)
-{
- HWND Item;
+ case WM_ISCANCELLED:
+ return SetDlgMsgResult(hDlg, uMsg, m_bCancelled);
- if (!IsWindow(hDlg))
- return;
- ProgressBar.SetProgress(ulProgress, ulProgressMax);
+ case WM_SETSTATUS:
+ m_ListView.SetDownloadStatus(m_Index - 1, (DownloadStatus)wParam);
+ break;
- if (!IsWindow(hDlg))
- return;
- Item = GetDlgItem(hDlg, IDC_DOWNLOAD_STATUS);
- if (Item && szStatusText && wcslen(szStatusText) > 0 &&
UrlHasBeenCopied == FALSE)
- {
- SIZE_T len = wcslen(szStatusText) + 1;
- CStringW buf;
- DWORD dummyLen;
+ case WM_GETINSTANCE:
+ return SetDlgMsgResult(hDlg, uMsg, (INT_PTR)this);
- /* beautify our url for display purposes */
- if (!InternetCanonicalizeUrlW(szStatusText, buf.GetBuffer(len), &dummyLen,
ICU_DECODE | ICU_NO_ENCODE))
- {
- /* just use the original */
- buf.ReleaseBuffer();
- buf = szStatusText;
- }
- else
+ case WM_GETNEXT:
{
- buf.ReleaseBuffer();
+ DownloadInfo *pItem = NULL;
+ if (!m_bCancelled && m_Index < (SIZE_T)m_List.GetSize())
+ pItem = &m_List[m_Index++];
+ return SetDlgMsgResult(hDlg, uMsg, (INT_PTR)pItem);
}
-
- /* paste it into our dialog and don't do it again in this instance */
- ::SetWindowText(Item, buf.GetString());
- UrlHasBeenCopied = TRUE;
}
+ return FALSE;
}
-BOOL
-ShowLastError(HWND hWndOwner, BOOL bInetError, DWORD dwLastError)
+void
+CDownloadManager::UpdateProgress(ULONG ulProgress, ULONG ulProgressMax)
{
- CLocalPtr<WCHAR> lpMsg;
+ m_ProgressBar.SetProgress(ulProgress, ulProgressMax);
+}
- if (!FormatMessageW(
- FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |
- (bInetError ? FORMAT_MESSAGE_FROM_HMODULE : FORMAT_MESSAGE_FROM_SYSTEM),
- (bInetError ? GetModuleHandleW(L"wininet.dll") : NULL),
dwLastError, LANG_USER_DEFAULT, (LPWSTR)&lpMsg, 0,
- NULL))
+unsigned int CALLBACK
+CDownloadManager::ThreadFunc(void* ThreadParam)
+{
+ CDownloadManager *pThis = (CDownloadManager*)ThreadParam;
+ HWND hDlg = pThis->m_hDlg;
+ for (;;)
{
- DPRINT1("FormatMessageW unexpected failure (err %d)\n",
GetLastError());
- return FALSE;
+ DownloadInfo *pItem = (DownloadInfo*)SendMessageW(hDlg, WM_GETNEXT, 0, 0);
+ if (!pItem)
+ break;
+ pThis->PerformDownloadAndInstall(*pItem);
}
-
- MessageBoxW(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
- return TRUE;
+ SendMessageW(hDlg, WM_CLOSE, 0, 0);
+ return pThis->Release();
}
-unsigned int WINAPI
-CDownloadManager::ThreadFunc(LPVOID param)
+void
+CDownloadManager::PerformDownloadAndInstall(const DownloadInfo &Info)
{
+ const HWND hDlg = m_hDlg;
+ const HWND hStatus = GetDlgItem(m_hDlg, IDC_DOWNLOAD_STATUS);
+ SetFriendlyUrl(hStatus, Info.szUrl);
+
+ m_ProgressBar.SetMarquee(FALSE);
+ m_ProgressBar.SendMessageW(PBM_SETPOS, 0, 0);
+ m_ProgressBar.SetProgress(0, Info.SizeInBytes);
+
+ CStringW str;
CPathW Path;
PCWSTR p, q;
- HWND hDlg = static_cast<DownloadParam *>(param)->Dialog;
- HWND Item;
- INT iAppId;
-
- ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus;
+ ULONG dwContentLen, dwBytesWritten, dwBytesRead, dwStatus, dwStatusLen;
ULONG dwCurrentBytesRead = 0;
- ULONG dwStatusLen = sizeof(dwStatus);
-
- BOOL bTempfile = FALSE;
+ BOOL bTempfile = FALSE, bCancelled = FALSE;
HINTERNET hOpen = NULL;
HINTERNET hFile = NULL;
HANDLE hOut = INVALID_HANDLE_VALUE;
- unsigned char lpBuffer[4096];
+
LPCWSTR lpszAgent = L"RApps/1.1";
- URL_COMPONENTSW urlComponents;
- size_t urlLength, filenameLength;
-
- const ATL::CSimpleArray<DownloadInfo> &InfoArray =
static_cast<DownloadParam *>(param)->AppInfo;
- LPCWSTR szCaption = static_cast<DownloadParam *>(param)->szCaption;
- CStringW szNewCaption;
-
const DWORD dwUrlConnectFlags =
INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_PRAGMA_NOCACHE |
INTERNET_FLAG_KEEP_CONNECTION;
+ URL_COMPONENTSW urlComponents;
+ size_t urlLength, filenameLength;
+ unsigned char lpBuffer[4096];
- if (InfoArray.GetSize() <= 0)
+ // Change caption to show the currently downloaded app
+ switch (Info.DLType)
{
- MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD);
- goto end;
+ case DLTYPE_APPLICATION:
+ str.Format(m_szCaptionFmt, Info.szName.GetString());
+ break;
+ case DLTYPE_DBUPDATE:
+ str.LoadStringW(IDS_DL_DIALOG_DB_DOWNLOAD_DISP);
+ break;
+ case DLTYPE_DBUPDATE_UNOFFICIAL:
+ str.LoadStringW(IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP);
+ break;
}
+ SetWindowTextW(hDlg, str);
- for (iAppId = 0; iAppId < InfoArray.GetSize(); ++iAppId)
+ // is this URL an update package for RAPPS? if so store it in a different place
+ if (Info.DLType != DLTYPE_APPLICATION)
{
- // Reset progress bar
- if (!IsWindow(hDlg))
- break;
- Item = GetDlgItem(hDlg, IDC_DOWNLOAD_PROGRESS);
- if (Item)
+ if (!GetStorageDirectory(Path))
{
- ProgressBar.SetMarquee(FALSE);
- ProgressBar.SendMessage(PBM_SETPOS, 0, 0);
- ProgressBar.SetProgress(0, InfoArray[iAppId].SizeInBytes);
+ ShowLastError(hMainWnd, FALSE, GetLastError());
+ goto end;
}
+ }
+ else
+ {
+ Path = SettingsInfo.szDownloadDir;
+ }
- // is this URL an update package for RAPPS? if so store it in a different place
- if (InfoArray[iAppId].DLType != DLTYPE_APPLICATION)
- {
- if (!GetStorageDirectory(Path))
- {
- ShowLastError(hMainWnd, FALSE, GetLastError());
- goto end;
- }
- }
- else
- {
- Path = SettingsInfo.szDownloadDir;
- }
+ // build the path for the download
+ p = wcsrchr(Info.szUrl.GetString(), L'/');
+ q = wcsrchr(Info.szUrl.GetString(), L'?');
- // Change caption to show the currently downloaded app
- switch (InfoArray[iAppId].DLType)
- {
- case DLTYPE_APPLICATION:
- szNewCaption.Format(szCaption, InfoArray[iAppId].szName.GetString());
- break;
- case DLTYPE_DBUPDATE:
- szNewCaption.LoadStringW(IDS_DL_DIALOG_DB_DOWNLOAD_DISP);
- break;
- case DLTYPE_DBUPDATE_UNOFFICIAL:
- szNewCaption.LoadStringW(IDS_DL_DIALOG_DB_UNOFFICIAL_DOWNLOAD_DISP);
- break;
- }
+ // do we have a final slash separator?
+ if (!p)
+ {
+ MessageBox_LoadString(hMainWnd, IDS_UNABLE_PATH);
+ goto end;
+ }
- if (!IsWindow(hDlg))
- goto end;
- SetWindowTextW(hDlg, szNewCaption.GetString());
+ // prepare the tentative length of the filename, maybe we've to remove part of it
later on
+ filenameLength = wcslen(p) * sizeof(WCHAR);
- // build the path for the download
- p = wcsrchr(InfoArray[iAppId].szUrl.GetString(), L'/');
- q = wcsrchr(InfoArray[iAppId].szUrl.GetString(), L'?');
+ /* do we have query arguments in the target URL after the filename? account for them
+ (e.g.
https://example.org/myfile.exe?no_adware_plz) */
+ if (q && q > p && (q - p) > 0)
+ filenameLength -= wcslen(q - 1) * sizeof(WCHAR);
- // do we have a final slash separator?
- if (!p)
+ // is the path valid? can we access it?
+ if (GetFileAttributesW(Path) == INVALID_FILE_ATTRIBUTES)
+ {
+ if (!CreateDirectoryW(Path, NULL))
{
- MessageBox_LoadString(hMainWnd, IDS_UNABLE_PATH);
+ ShowLastError(hMainWnd, FALSE, GetLastError());
goto end;
}
+ }
- // prepare the tentative length of the filename, maybe we've to remove part
of it later on
- filenameLength = wcslen(p) * sizeof(WCHAR);
-
- /* do we have query arguments in the target URL after the filename? account for
them
- (e.g.
https://example.org/myfile.exe?no_adware_plz) */
- if (q && q > p && (q - p) > 0)
- filenameLength -= wcslen(q - 1) * sizeof(WCHAR);
-
- // is the path valid? can we access it?
- if (GetFileAttributesW(Path) == INVALID_FILE_ATTRIBUTES)
+ switch (Info.DLType)
+ {
+ case DLTYPE_DBUPDATE:
+ case DLTYPE_DBUPDATE_UNOFFICIAL:
+ Path += APPLICATION_DATABASE_NAME;
+ break;
+ case DLTYPE_APPLICATION:
{
- if (!CreateDirectoryW(Path, NULL))
- {
- ShowLastError(hMainWnd, FALSE, GetLastError());
- goto end;
- }
+ CStringW str = p + 1; // use the filename retrieved from URL
+ UrlUnescapeAndMakeFileNameValid(str);
+ Path += str;
+ break;
}
+ }
- switch (InfoArray[iAppId].DLType)
- {
- case DLTYPE_DBUPDATE:
- case DLTYPE_DBUPDATE_UNOFFICIAL:
- Path += APPLICATION_DATABASE_NAME;
- break;
- case DLTYPE_APPLICATION:
- {
- CStringW str = p + 1; // use the filename retrieved from URL
- UrlUnescapeAndMakeFileNameValid(str);
- Path += str;
- break;
- }
- }
+ if ((Info.DLType == DLTYPE_APPLICATION) && Info.szSHA1[0] &&
+ GetFileAttributesW(Path) != INVALID_FILE_ATTRIBUTES)
+ {
+ // only open it in case of total correctness
+ if (VerifyInteg(Info.szSHA1.GetString(), Path))
+ goto run;
+ }
- if ((InfoArray[iAppId].DLType == DLTYPE_APPLICATION) &&
InfoArray[iAppId].szSHA1[0] &&
- GetFileAttributesW(Path) != INVALID_FILE_ATTRIBUTES)
- {
- // only open it in case of total correctness
- if (VerifyInteg(InfoArray[iAppId].szSHA1.GetString(), Path))
- goto run;
- }
+ // Download it
+ SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_DOWNLOADING, 0);
+ /* FIXME: this should just be using the system-wide proxy settings */
+ switch (SettingsInfo.Proxy)
+ {
+ case 0: // preconfig
+ default:
+ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL,
0);
+ break;
+ case 1: // direct (no proxy)
+ hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
+ break;
+ case 2: // use proxy
+ hOpen = InternetOpenW(
+ lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer,
SettingsInfo.szNoProxyFor, 0);
+ break;
+ }
- // Add the download URL
- if (!IsWindow(hDlg))
- goto end;
- SetDlgItemTextW(hDlg, IDC_DOWNLOAD_STATUS, InfoArray[iAppId].szUrl.GetString());
+ if (!hOpen)
+ {
+ ShowLastError(hMainWnd, TRUE, GetLastError());
+ goto end;
+ }
- DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_DOWNLOADING);
+ bTempfile = TRUE;
+ dwContentLen = 0;
+ dwStatusLen = sizeof(dwStatus);
+ ZeroMemory(&urlComponents, sizeof(urlComponents));
+ urlComponents.dwStructSize = sizeof(urlComponents);
- // download it
- UrlHasBeenCopied = FALSE;
- bTempfile = TRUE;
+ urlLength = Info.szUrl.GetLength();
+ urlComponents.dwSchemeLength = urlLength + 1;
+ urlComponents.lpszScheme = (LPWSTR)malloc(urlComponents.dwSchemeLength *
sizeof(WCHAR));
- /* FIXME: this should just be using the system-wide proxy settings */
- switch (SettingsInfo.Proxy)
+ if (!InternetCrackUrlW(Info.szUrl, urlLength + 1, ICU_DECODE | ICU_ESCAPE,
&urlComponents))
+ {
+ ShowLastError(hMainWnd, TRUE, GetLastError());
+ goto end;
+ }
+
+ if (urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme ==
INTERNET_SCHEME_HTTPS)
+ {
+ hFile = InternetOpenUrlW(hOpen, Info.szUrl, NULL, 0, dwUrlConnectFlags, 0);
+ if (!hFile)
{
- case 0: // preconfig
- default:
- hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL,
NULL, 0);
- break;
- case 1: // direct (no proxy)
- hOpen = InternetOpenW(lpszAgent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL,
0);
- break;
- case 2: // use proxy
- hOpen = InternetOpenW(
- lpszAgent, INTERNET_OPEN_TYPE_PROXY, SettingsInfo.szProxyServer,
SettingsInfo.szNoProxyFor, 0);
- break;
+ if (!ShowLastError(hMainWnd, TRUE, GetLastError()))
+ {
+ /* Workaround for CORE-17377 */
+ MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2);
+ }
+ goto end;
}
- if (!hOpen)
+ // query connection
+ if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
&dwStatus, &dwStatusLen, NULL))
{
ShowLastError(hMainWnd, TRUE, GetLastError());
goto end;
}
- dwStatusLen = sizeof(dwStatus);
-
- memset(&urlComponents, 0, sizeof(urlComponents));
- urlComponents.dwStructSize = sizeof(urlComponents);
-
- urlLength = InfoArray[iAppId].szUrl.GetLength();
- urlComponents.dwSchemeLength = urlLength + 1;
- urlComponents.lpszScheme = (LPWSTR)malloc(urlComponents.dwSchemeLength *
sizeof(WCHAR));
-
- if (!InternetCrackUrlW(InfoArray[iAppId].szUrl, urlLength + 1, ICU_DECODE |
ICU_ESCAPE, &urlComponents))
+ if (dwStatus != HTTP_STATUS_OK)
{
- ShowLastError(hMainWnd, TRUE, GetLastError());
+ MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD);
goto end;
}
- dwContentLen = 0;
-
- if (urlComponents.nScheme == INTERNET_SCHEME_HTTP || urlComponents.nScheme ==
INTERNET_SCHEME_HTTPS)
+ // query content length
+ HttpQueryInfoW(hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
&dwContentLen, &dwStatusLen, NULL);
+ }
+ else if (urlComponents.nScheme == INTERNET_SCHEME_FTP)
+ {
+ // force passive mode on FTP
+ hFile =
+ InternetOpenUrlW(hOpen, Info.szUrl, NULL, 0, dwUrlConnectFlags |
INTERNET_FLAG_PASSIVE, 0);
+ if (!hFile)
{
- hFile = InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl.GetString(), NULL, 0,
dwUrlConnectFlags, 0);
- if (!hFile)
- {
- if (!ShowLastError(hMainWnd, TRUE, GetLastError()))
- {
- /* Workaround for CORE-17377 */
- MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2);
- }
- goto end;
- }
-
- // query connection
- if (!HttpQueryInfoW(hFile, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
&dwStatus, &dwStatusLen, NULL))
+ if (!ShowLastError(hMainWnd, TRUE, GetLastError()))
{
- ShowLastError(hMainWnd, TRUE, GetLastError());
- goto end;
- }
-
- if (dwStatus != HTTP_STATUS_OK)
- {
- MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD);
- goto end;
+ /* Workaround for CORE-17377 */
+ MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2);
}
-
- // query content length
- HttpQueryInfoW(
- hFile, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
&dwContentLen, &dwStatusLen, NULL);
+ goto end;
}
- else if (urlComponents.nScheme == INTERNET_SCHEME_FTP)
- {
- // force passive mode on FTP
- hFile =
- InternetOpenUrlW(hOpen, InfoArray[iAppId].szUrl, NULL, 0,
dwUrlConnectFlags | INTERNET_FLAG_PASSIVE, 0);
- if (!hFile)
- {
- if (!ShowLastError(hMainWnd, TRUE, GetLastError()))
- {
- /* Workaround for CORE-17377 */
- MessageBox_LoadString(hMainWnd, IDS_UNABLE_TO_DOWNLOAD2);
- }
- goto end;
- }
- dwContentLen = FtpGetFileSize(hFile, &dwStatus);
- }
- else if (urlComponents.nScheme == INTERNET_SCHEME_FILE)
+ dwContentLen = FtpGetFileSize(hFile, &dwStatus);
+ }
+ else if (urlComponents.nScheme == INTERNET_SCHEME_FILE)
+ {
+ // Add support for the file scheme so testing locally is simpler
+ WCHAR LocalFilePath[MAX_PATH];
+ DWORD cchPath = _countof(LocalFilePath);
+ // Ideally we would use PathCreateFromUrlAlloc here, but that is not exported
(yet)
+ HRESULT hr = PathCreateFromUrlW(Info.szUrl, LocalFilePath, &cchPath, 0);
+ if (SUCCEEDED(hr))
{
- // Add support for the file scheme so testing locally is simpler
- WCHAR LocalFilePath[MAX_PATH];
- DWORD cchPath = _countof(LocalFilePath);
- // Ideally we would use PathCreateFromUrlAlloc here, but that is not exported
(yet)
- HRESULT hr = PathCreateFromUrlW(InfoArray[iAppId].szUrl, LocalFilePath,
&cchPath, 0);
- if (SUCCEEDED(hr))
+ if (CopyFileW(LocalFilePath, Path, FALSE))
{
- if (CopyFileW(LocalFilePath, Path, FALSE))
- {
- goto run;
- }
- else
- {
- ShowLastError(hMainWnd, FALSE, GetLastError());
- goto end;
- }
+ goto run;
}
else
{
- ShowLastError(hMainWnd, FALSE, hr);
+ ShowLastError(hMainWnd, FALSE, GetLastError());
goto end;
}
}
+ else
+ {
+ ShowLastError(hMainWnd, FALSE, hr);
+ goto end;
+ }
+ }
- if (!dwContentLen)
+ if (!dwContentLen)
+ {
+ // Someone was nice enough to add this, let's use it
+ if (Info.SizeInBytes)
{
- // Someone was nice enough to add this, let's use it
- if (InfoArray[iAppId].SizeInBytes)
- {
- dwContentLen = InfoArray[iAppId].SizeInBytes;
- }
- else
- {
- // content-length is not known, enable marquee mode
- ProgressBar.SetMarquee(TRUE);
- }
+ dwContentLen = Info.SizeInBytes;
}
+ else
+ {
+ // content-length is not known, enable marquee mode
+ m_ProgressBar.SetMarquee(TRUE);
+ }
+ }
- free(urlComponents.lpszScheme);
+ free(urlComponents.lpszScheme);
#ifdef USE_CERT_PINNING
- // are we using HTTPS to download the RAPPS update package? check if the
certificate is original
- if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) &&
(InfoArray[iAppId].DLType == DLTYPE_DBUPDATE))
+ // are we using HTTPS to download the RAPPS update package? check if the certificate
is original
+ if ((urlComponents.nScheme == INTERNET_SCHEME_HTTPS) && (Info.DLType ==
DLTYPE_DBUPDATE))
+ {
+ CLocalPtr<char> subjectName, issuerName;
+ CStringA szMsgText;
+ bool bAskQuestion = false;
+ if (!CertGetSubjectAndIssuer(hFile, subjectName, issuerName))
{
- CLocalPtr<char> subjectName, issuerName;
- CStringA szMsgText;
- bool bAskQuestion = false;
- if (!CertGetSubjectAndIssuer(hFile, subjectName, issuerName))
- {
- szMsgText.LoadStringW(IDS_UNABLE_TO_QUERY_CERT);
- bAskQuestion = true;
- }
- else if (!IsTrustedPinnedCert(subjectName, issuerName))
- {
- szMsgText.Format(IDS_MISMATCH_CERT_INFO, (LPCSTR)subjectName,
(LPCSTR)issuerName);
- bAskQuestion = true;
- }
+ szMsgText.LoadStringW(IDS_UNABLE_TO_QUERY_CERT);
+ bAskQuestion = true;
+ }
+ else if (!IsTrustedPinnedCert(subjectName, issuerName))
+ {
+ szMsgText.Format(IDS_MISMATCH_CERT_INFO, (LPCSTR)subjectName,
(LPCSTR)issuerName);
+ bAskQuestion = true;
+ }
- if (bAskQuestion)
+ if (bAskQuestion)
+ {
+ if (MessageBoxA(hDlg, szMsgText, NULL, MB_YESNO | MB_ICONERROR) != IDYES)
{
- if (MessageBoxA(hMainWnd, szMsgText.GetString(), NULL, MB_YESNO |
MB_ICONERROR) != IDYES)
- {
- goto end;
- }
+ goto end;
}
}
+ }
#endif
- hOut = CreateFileW(Path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, 0, NULL);
+ hOut = CreateFileW(Path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, 0, NULL);
+ if (hOut == INVALID_HANDLE_VALUE)
+ {
+ ShowLastError(hDlg, FALSE, GetLastError());
+ goto end;
+ }
- if (hOut == INVALID_HANDLE_VALUE)
+ dwCurrentBytesRead = 0;
+ do
+ {
+ bCancelled = IsCancelled();
+ if (bCancelled)
+ break;
+
+ if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer), &dwBytesRead))
{
- ShowLastError(hMainWnd, FALSE, GetLastError());
+ ShowLastError(hDlg, TRUE, GetLastError());
goto end;
}
- dwCurrentBytesRead = 0;
- do
+ if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten, NULL))
{
- if (!InternetReadFile(hFile, lpBuffer, _countof(lpBuffer),
&dwBytesRead))
- {
- ShowLastError(hMainWnd, TRUE, GetLastError());
- goto end;
- }
+ ShowLastError(hDlg, FALSE, GetLastError());
+ goto end;
+ }
- if (!WriteFile(hOut, &lpBuffer[0], dwBytesRead, &dwBytesWritten,
NULL))
- {
- ShowLastError(hMainWnd, FALSE, GetLastError());
- goto end;
- }
+ dwCurrentBytesRead += dwBytesRead;
+ UpdateProgress(dwCurrentBytesRead, dwContentLen);
+
+ } while (dwBytesRead);
- dwCurrentBytesRead += dwBytesRead;
- if (!IsWindow(hDlg))
- goto end;
- UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0,
InfoArray[iAppId].szUrl.GetString());
- } while (dwBytesRead && !bCancelled);
+ CloseHandle(hOut);
+ hOut = INVALID_HANDLE_VALUE;
- CloseHandle(hOut);
- hOut = INVALID_HANDLE_VALUE;
+ if (bCancelled)
+ {
+ DPRINT1("Operation cancelled\n");
+ goto end;
+ }
- if (bCancelled)
+ if (!dwContentLen)
+ {
+ // set progress bar to 100%
+ m_ProgressBar.SetMarquee(FALSE);
+
+ dwContentLen = dwCurrentBytesRead;
+ UpdateProgress(dwCurrentBytesRead, dwContentLen);
+ }
+
+ /* if this thing isn't a RAPPS update and it has a SHA-1 checksum
+ verify its integrity by using the native advapi32.A_SHA1 functions */
+ if ((Info.DLType == DLTYPE_APPLICATION) && Info.szSHA1[0] != 0)
+ {
+ CStringW szMsgText;
+
+ // change a few strings in the download dialog to reflect the verification
process
+ if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_TITLE))
{
- DPRINT1("Operation cancelled\n");
+ DPRINT1("Unable to load string\n");
goto end;
}
- if (!dwContentLen)
- {
- // set progress bar to 100%
- ProgressBar.SetMarquee(FALSE);
-
- dwContentLen = dwCurrentBytesRead;
- if (!IsWindow(hDlg))
- goto end;
- UpdateProgress(hDlg, dwCurrentBytesRead, dwContentLen, 0,
InfoArray[iAppId].szUrl.GetString());
- }
+ SetWindowTextW(hDlg, szMsgText);
+ SetWindowTextW(hStatus, Path);
- /* if this thing isn't a RAPPS update and it has a SHA-1 checksum
- verify its integrity by using the native advapi32.A_SHA1 functions */
- if ((InfoArray[iAppId].DLType == DLTYPE_APPLICATION) &&
InfoArray[iAppId].szSHA1[0] != 0)
+ // this may take a while, depending on the file size
+ if (!VerifyInteg(Info.szSHA1, Path))
{
- CStringW szMsgText;
-
- // change a few strings in the download dialog to reflect the verification
process
- if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_TITLE))
+ if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_FAIL))
{
DPRINT1("Unable to load string\n");
goto end;
}
- if (!IsWindow(hDlg))
- goto end;
- SetWindowTextW(hDlg, szMsgText.GetString());
- ::SetDlgItemTextW(hDlg, IDC_DOWNLOAD_STATUS, Path);
-
- // this may take a while, depending on the file size
- if (!VerifyInteg(InfoArray[iAppId].szSHA1.GetString(), Path))
- {
- if (!szMsgText.LoadStringW(IDS_INTEG_CHECK_FAIL))
- {
- DPRINT1("Unable to load string\n");
- goto end;
- }
-
- if (!IsWindow(hDlg))
- goto end;
- MessageBoxW(hDlg, szMsgText.GetString(), NULL, MB_OK | MB_ICONERROR);
- goto end;
- }
+ MessageBoxW(hDlg, szMsgText, NULL, MB_OK | MB_ICONERROR);
+ goto end;
}
+ }
- run:
- DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_WAITING_INSTALL);
+run:
+ SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_WAITING_INSTALL, 0);
- // run it
- if (InfoArray[iAppId].DLType == DLTYPE_APPLICATION)
+ // run it
+ if (Info.DLType == DLTYPE_APPLICATION)
+ {
+ CStringW app, params;
+ SHELLEXECUTEINFOW shExInfo = {0};
+ shExInfo.cbSize = sizeof(shExInfo);
+ shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
+ shExInfo.lpVerb = L"open";
+ shExInfo.lpFile = Path;
+ shExInfo.lpParameters = L"";
+ shExInfo.nShow = SW_SHOW;
+
+ if (Info.IType == INSTALLER_GENERATE)
{
- CStringW app, params;
- SHELLEXECUTEINFOW shExInfo = {0};
- shExInfo.cbSize = sizeof(shExInfo);
- shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
- shExInfo.lpVerb = L"open";
- shExInfo.lpFile = Path;
- shExInfo.lpParameters = L"";
- shExInfo.nShow = SW_SHOW;
-
- if (InfoArray[iAppId].IType == INSTALLER_GENERATE)
- {
- params = L"/" + CStringW(CMD_KEY_GENINST) + L"
\"" +
- InfoArray[iAppId].szPackageName + L"\" \""
+
- CStringW(shExInfo.lpFile) + L"\"";
- shExInfo.lpParameters = params;
- shExInfo.lpFile = app.GetBuffer(MAX_PATH);
- GetModuleFileNameW(NULL, const_cast<LPWSTR>(shExInfo.lpFile),
MAX_PATH);
- app.ReleaseBuffer();
- }
-
- /* FIXME: Do we want to log installer status? */
- WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_INSTALL,
InfoArray[iAppId].szName);
-
- if (ShellExecuteExW(&shExInfo))
- {
- // reflect installation progress in the titlebar
- // TODO: make a separate string with a placeholder to include app name?
- CStringW szMsgText = LoadStatusString(DLSTATUS_INSTALLING);
- if (!IsWindow(hDlg))
- goto end;
- SetWindowTextW(hDlg, szMsgText.GetString());
-
- DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_INSTALLING);
-
- // TODO: issue an install operation separately so that the apps could be
downloaded in the background
- WaitForSingleObject(shExInfo.hProcess, INFINITE);
- CloseHandle(shExInfo.hProcess);
- }
- else
- {
- ShowLastError(hMainWnd, FALSE, GetLastError());
- }
+ params = L"/" + CStringW(CMD_KEY_GENINST) + L" \""
+
+ Info.szPackageName + L"\" \"" +
+ CStringW(shExInfo.lpFile) + L"\"";
+ shExInfo.lpParameters = params;
+ shExInfo.lpFile = app.GetBuffer(MAX_PATH);
+ GetModuleFileNameW(NULL, const_cast<LPWSTR>(shExInfo.lpFile),
MAX_PATH);
+ app.ReleaseBuffer();
}
- end:
- if (hOut != INVALID_HANDLE_VALUE)
- CloseHandle(hOut);
+ /* FIXME: Do we want to log installer status? */
+ WriteLogMessage(EVENTLOG_SUCCESS, MSG_SUCCESS_INSTALL, Info.szName);
- if (hFile)
- InternetCloseHandle(hFile);
- InternetCloseHandle(hOpen);
+ if (ShellExecuteExW(&shExInfo))
+ {
+ // reflect installation progress in the titlebar
+ // TODO: make a separate string with a placeholder to include app name?
+ CStringW szMsgText = LoadStatusString(DLSTATUS_INSTALLING);
+ SetWindowTextW(hDlg, szMsgText);
+
+ SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_INSTALLING, 0);
- if (bTempfile)
+ // TODO: issue an install operation separately so that the apps could be
downloaded in the background
+ WaitForSingleObject(shExInfo.hProcess, INFINITE);
+ CloseHandle(shExInfo.hProcess);
+ }
+ else
{
- if (bCancelled || (SettingsInfo.bDelInstaller &&
(InfoArray[iAppId].DLType == DLTYPE_APPLICATION)))
- DeleteFileW(Path);
+ ShowLastError(hMainWnd, FALSE, GetLastError());
}
-
- if (!IsWindow(hDlg))
- return 0;
- DownloadsListView.SetDownloadStatus(iAppId, DLSTATUS_FINISHED);
}
- delete static_cast<DownloadParam *>(param);
- if (!IsWindow(hDlg))
- return 0;
- SendMessageW(hDlg, WM_CLOSE, 0, 0);
- return 0;
-}
+end:
+ if (hOut != INVALID_HANDLE_VALUE)
+ CloseHandle(hOut);
-// TODO: Reuse the dialog
-VOID
-CDownloadManager::LaunchDownloadDialog(BOOL bIsModal)
-{
- CDownloadManager::bModal = bIsModal;
- if (bIsModal)
- {
- DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd,
DownloadDlgProc);
- }
- else
+ if (hFile)
+ InternetCloseHandle(hFile);
+ InternetCloseHandle(hOpen);
+
+ if (bTempfile)
{
- CreateDialogW(hInst, MAKEINTRESOURCEW(IDD_DOWNLOAD_DIALOG), hMainWnd,
DownloadDlgProc);
+ if (bCancelled || (SettingsInfo.bDelInstaller && Info.DLType ==
DLTYPE_APPLICATION))
+ DeleteFileW(Path);
}
+
+ SendMessageW(hDlg, WM_SETSTATUS, DLSTATUS_FINISHED, 0);
}
-// CDownloadManager
BOOL
DownloadListOfApplications(const CAtlList<CAppInfo *> &AppsList, BOOL
bIsModal)
@@ -1127,35 +1124,44 @@ DownloadListOfApplications(const CAtlList<CAppInfo *>
&AppsList, BOOL bIsModal)
if (AppsList.IsEmpty())
return FALSE;
- POSITION CurrentListPosition = AppsList.GetHeadPosition();
- while (CurrentListPosition)
+ CComPtr<CDownloadManager> pDM;
+ if (!CDownloadManager::CreateInstance(bIsModal, pDM))
+ return FALSE;
+
+ for (POSITION it = AppsList.GetHeadPosition(); it;)
{
- const CAppInfo *Info = AppsList.GetNext(CurrentListPosition);
- CDownloadManager::Add(DownloadInfo(*Info));
+ const CAppInfo *Info = AppsList.GetNext(it);
+ pDM->Add(DownloadInfo(*Info));
}
-
- // Create a dialog and issue a download process
- CDownloadManager::LaunchDownloadDialog(bIsModal);
-
+ pDM->Show();
return TRUE;
}
BOOL
DownloadApplication(CAppInfo *pAppInfo)
{
+ const bool bModal = false;
if (!pAppInfo)
return FALSE;
- CDownloadManager::Download(*pAppInfo, FALSE);
- return TRUE;
+ CAtlList<CAppInfo*> list;
+ list.AddTail(pAppInfo);
+ return DownloadListOfApplications(list, bModal);
}
VOID
DownloadApplicationsDB(LPCWSTR lpUrl, BOOL IsOfficial)
{
- static DownloadInfo DatabaseDLInfo;
+ const bool bModal = true;
+ CComPtr<CDownloadManager> pDM;
+ if (!CDownloadManager::CreateInstance(bModal, pDM))
+ return;
+
+ DownloadInfo DatabaseDLInfo;
DatabaseDLInfo.szUrl = lpUrl;
DatabaseDLInfo.szName.LoadStringW(IDS_DL_DIALOG_DB_DISP);
DatabaseDLInfo.DLType = IsOfficial ? DLTYPE_DBUPDATE : DLTYPE_DBUPDATE_UNOFFICIAL;
- CDownloadManager::Download(DatabaseDLInfo, TRUE);
+
+ pDM->Add(DatabaseDLInfo);
+ pDM->Show();
}