Skip to content

Commit b9f1d24

Browse files
committed
CollectionInterface: MultiDownload = combine all UAC into single request
1 parent 95bd7de commit b9f1d24

File tree

1 file changed

+45
-33
lines changed

1 file changed

+45
-33
lines changed

src/Dialogs/CollectionInterfaceDialog.cpp

Lines changed: 45 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include <string>
2828
#include <vector>
2929
#include <CommCtrl.h>
30+
#include <Shlwapi.h>
3031

3132

3233
HWND g_hwndCIDlg = nullptr, g_hwndCIHlpDlg = nullptr;
@@ -272,6 +273,7 @@ INT_PTR CALLBACK ciDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
272273
}
273274

274275
// loop through each index in the buffer, and download as needed
276+
std::map<std::wstring, std::wstring> mapUacDelayed;
275277
for(auto selectedFileIndex: vBuf) {
276278
if (selectedFileIndex == LB_ERR) {
277279
::MessageBox(NULL, L"Could not understand name selection; sorry", L"Download Error", MB_ICONERROR);
@@ -367,23 +369,8 @@ INT_PTR CALLBACK ciDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
367369
else {
368370
// check if it needs to be overwritten before elevating permissions
369371
if (pobjCI->ask_overwrite_if_exists(wsPath)) {
370-
// download to a temp path, then use ShellExecute(runas) to move it from the temp path to the final destination
371-
std::wstring wsAsk = L"Cannot write to " + wsPath;
372-
wsAsk += L"\nI will try again with elevated UAC permission.";
373-
int ans = ::MessageBox(hwndDlg, wsAsk.c_str(), L"Need Directory Permission", MB_OKCANCEL);
374-
if (ans == IDOK) {
375-
std::wstring tmpPath = pobjCI->getWritableTempDir() + L"\\~$TMPFILE.DOWNLOAD.PRYRT.xml";
376-
pobjCI->downloadFileToDisk(wsURL, tmpPath);
377-
std::wstring msg = L"Downloaded from\n" + tmpPath + L"\nand moved to\n" + wsPath;
378-
std::wstring args = L"/C MOVE /Y \"" + tmpPath + L"\" \"" + wsPath + L"\"";
379-
ShellExecute(hwndDlg, L"runas", L"cmd.exe", args.c_str(), NULL, SW_SHOWMINIMIZED);
380-
//::MessageBox(hwndDlg, msg.c_str(), L"Download and UAC move", MB_OK);
381-
count++;
382-
didDownload = true;
383-
}
384-
else {
385-
total--;
386-
}
372+
mapUacDelayed[wsURL] = wsPath;
373+
total--;
387374
}
388375
else {
389376
total--;
@@ -392,6 +379,7 @@ INT_PTR CALLBACK ciDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
392379

393380
// update progress bar
394381
wchar_t wcDLPCT[256];
382+
if (total < 1) total = 1;
395383
swprintf_s(wcDLPCT, L"Downloading %d%%", 100 * count / total);
396384
if (didDownload) {
397385
::SendDlgItemMessage(hwndDlg, IDC_CI_PROGRESSBAR, PBM_SETPOS, 100 * count / total, 0);
@@ -411,29 +399,16 @@ INT_PTR CALLBACK ciDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
411399
}
412400
else {
413401
if (pobjCI->ask_overwrite_if_exists(xPath)) {
414-
// download to a temp path, then use ShellExecute(runas) to move it from the temp path to the final destination
415-
std::wstring wsAsk = L"Cannot write to " + xPath;
416-
wsAsk += L"\nI will try again with elevated UAC permission.";
417-
int ans = ::MessageBox(hwndDlg, wsAsk.c_str(), L"Need Directory Permission", MB_OKCANCEL);
418-
if (ans == IDOK) {
419-
std::wstring tmpPath = pobjCI->getWritableTempDir() + L"\\~$TMPFILE.DOWNLOAD.PRYRT.xml";
420-
pobjCI->downloadFileToDisk(xURL, tmpPath);
421-
std::wstring msg = L"Downloaded from\n" + tmpPath + L"\nand moved to\n" + xPath;
422-
std::wstring args = L"/C MOVE /Y \"" + tmpPath + L"\" \"" + xPath + L"\"";
423-
ShellExecute(hwndDlg, L"runas", L"cmd.exe", args.c_str(), NULL, SW_SHOWMINIMIZED);
424-
count++;
425-
didDownload = true;
426-
}
427-
else {
428-
total--;
429-
}
402+
mapUacDelayed[xURL] = xPath;
403+
total--;
430404
}
431405
else {
432406
total--;
433407
}
434408
}
435409
}
436410
// update progress bar
411+
if (total < 1) total = 1;
437412
swprintf_s(wcDLPCT, L"Downloading %d%%", 100 * count / total);
438413
if (didDownload) {
439414
::SendDlgItemMessage(hwndDlg, IDC_CI_PROGRESSBAR, PBM_SETPOS, 100 * count / total, 0);
@@ -454,6 +429,43 @@ INT_PTR CALLBACK ciDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
454429
}
455430
}
456431

432+
if (mapUacDelayed.size()) {
433+
int total = static_cast<int>(mapUacDelayed.size()) + 1; // want one extra "slot" for the MOVE command
434+
int count = 0;
435+
std::wstring wsAsk = L"Cannot write the following files:";
436+
for (const auto& pair : mapUacDelayed) {
437+
wsAsk += std::wstring(L"\n") + pair.second;
438+
}
439+
wsAsk += L"\n\nI will download temporary files, and then try to copy them to the right location with elevated UAC permission. (The OS may prompt you for UAC.)";
440+
int ans = ::MessageBox(hwndDlg, wsAsk.c_str(), L"Need Directory Permission", MB_OKCANCEL);
441+
if (ans == IDOK) {
442+
wchar_t wcDLPCT[256];
443+
swprintf_s(wcDLPCT, L"Downloading %d%%", 100 * count / total);
444+
Edit_SetText(GetDlgItem(hwndDlg, IDC_CI_PROGRESSLBL), wcDLPCT);
445+
446+
std::wstring args = L"/C ";
447+
448+
for (const auto& pair : mapUacDelayed) {
449+
++count;
450+
std::wstring tmpPath = pobjCI->getWritableTempDir() + L"\\~$TMPFILE.DOWNLOAD.PRYRT." + std::to_wstring(count);
451+
pobjCI->downloadFileToDisk(pair.first, tmpPath);
452+
didDownload = true;
453+
args += L"MOVE /Y \"" + tmpPath + L"\" \"" + pair.second + L"\" & ";
454+
455+
::SendDlgItemMessage(hwndDlg, IDC_CI_PROGRESSBAR, PBM_SETPOS, 100 * count / total, 0);
456+
swprintf_s(wcDLPCT, L"Downloading %d%%", 100 * count / total);
457+
Edit_SetText(GetDlgItem(hwndDlg, IDC_CI_PROGRESSLBL), wcDLPCT);
458+
}
459+
460+
//::MessageBox(hwndDlg, (std::wstring(L"cmd.exe ") + args).c_str(), L"TODO: UAC Command", MB_OK);
461+
ShellExecute(hwndDlg, L"runas", L"cmd.exe", args.c_str(), NULL, SW_SHOWMINIMIZED);
462+
463+
::SendDlgItemMessage(hwndDlg, IDC_CI_PROGRESSBAR, PBM_SETPOS, 100, 0);
464+
swprintf_s(wcDLPCT, L"Downloading %d%% [DONE]", 100);
465+
Edit_SetText(GetDlgItem(hwndDlg, IDC_CI_PROGRESSLBL), wcDLPCT);
466+
}
467+
}
468+
457469
return true;
458470
}
459471
case IDC_CI_HELPBTN:

0 commit comments

Comments
 (0)