|
8 | 8 | #include "winget/UserSettings.h" |
9 | 9 |
|
10 | 10 | // TODO: Get this from the Windows SDK when available |
11 | | -#include "external/do.h" |
| 11 | +#define DODownloadProperty_HttpRedirectionTarget static_cast<DODownloadProperty>(DODownloadProperty_NonVolatile + 1) |
| 12 | +#define DODownloadProperty_HttpResponseHeaders static_cast<DODownloadProperty>(DODownloadProperty_HttpRedirectionTarget + 1) |
| 13 | +#define DODownloadProperty_HttpServerIPAddress static_cast<DODownloadProperty>(DODownloadProperty_HttpResponseHeaders + 1) |
| 14 | +#define DODownloadProperty_HttpStatusCode static_cast<DODownloadProperty>(DODownloadProperty_HttpServerIPAddress + 1) |
12 | 15 |
|
13 | 16 | namespace AppInstaller::Utility |
14 | 17 | { |
15 | 18 | namespace DeliveryOptimization |
16 | 19 | { |
17 | | -// TODO: Once the SDK headers are available, remove these defines |
18 | | -#define DO_E_DOWNLOAD_NO_PROGRESS HRESULT(0x80D02002L) // Download of a file saw no progress within the defined period |
19 | | - |
20 | | -#define DO_E_BLOCKED_BY_COST_TRANSFER_POLICY HRESULT(0x80D03801L) // DO core paused the job due to cost policy restrictions |
21 | | -#define DO_E_BLOCKED_BY_CELLULAR_POLICY HRESULT(0x80D03803L) // DO core paused the job due to detection of cellular network and policy restrictions |
22 | | -#define DO_E_BLOCKED_BY_POWER_STATE HRESULT(0x80D03804L) // DO core paused the job due to detection of power state change into non-AC mode |
23 | | -#define DO_E_BLOCKED_BY_NO_NETWORK HRESULT(0x80D03805L) // DO core paused the job due to loss of network connectivity |
24 | | - |
25 | 20 | // Represents a download work item for Delivery Optimization. |
26 | 21 | struct Download |
27 | 22 | { |
@@ -106,6 +101,23 @@ namespace AppInstaller::Utility |
106 | 101 | THROW_IF_FAILED(m_download->SetProperty(prop, &var)); |
107 | 102 | } |
108 | 103 |
|
| 104 | + template<typename T> |
| 105 | + std::optional<T> TryGetProperty(DODownloadProperty prop) |
| 106 | + { |
| 107 | + std::optional<T> result; |
| 108 | + wil::unique_variant var; |
| 109 | + HRESULT hr = m_download->GetProperty(prop, &var); |
| 110 | + if (SUCCEEDED(hr)) |
| 111 | + { |
| 112 | + T value; |
| 113 | + if (ExtractFromVariant(var, value)) |
| 114 | + { |
| 115 | + result = std::move(value); |
| 116 | + } |
| 117 | + } |
| 118 | + return result; |
| 119 | + } |
| 120 | + |
109 | 121 | void Uri(std::string_view uri) |
110 | 122 | { |
111 | 123 | SetProperty(DODownloadProperty_Uri, uri); |
@@ -186,6 +198,22 @@ namespace AppInstaller::Utility |
186 | 198 | } |
187 | 199 |
|
188 | 200 | private: |
| 201 | + bool ExtractFromVariant(const VARIANT& var, std::string& value) |
| 202 | + { |
| 203 | + if (var.vt == VT_BSTR && var.bstrVal != nullptr) |
| 204 | + { |
| 205 | + value = Utility::ConvertToUTF8(var.bstrVal); |
| 206 | + return true; |
| 207 | + } |
| 208 | + else if (var.vt == (VT_BSTR | VT_BYREF) && var.pbstrVal != nullptr && *var.pbstrVal != nullptr) |
| 209 | + { |
| 210 | + value = Utility::ConvertToUTF8(*var.pbstrVal); |
| 211 | + return true; |
| 212 | + } |
| 213 | + |
| 214 | + return false; |
| 215 | + } |
| 216 | + |
189 | 217 | wil::com_ptr<IDODownload> m_download; |
190 | 218 | }; |
191 | 219 |
|
@@ -221,7 +249,7 @@ namespace AppInstaller::Utility |
221 | 249 | { |
222 | 250 | } |
223 | 251 |
|
224 | | - IFACEMETHOD(OnStatusChange)(IDODownload*, DO_DOWNLOAD_STATUS* status) |
| 252 | + IFACEMETHOD(OnStatusChange)(IDODownload*, const DO_DOWNLOAD_STATUS* status) |
225 | 253 | { |
226 | 254 | { |
227 | 255 | std::lock_guard<std::mutex> guard(m_statusMutex); |
@@ -397,6 +425,9 @@ namespace AppInstaller::Utility |
397 | 425 | // Wait returns true for success, false for cancellation, and throws on error. |
398 | 426 | if (callback->Wait()) |
399 | 427 | { |
| 428 | + // Grab the headers so that we can use them later |
| 429 | + std::optional<std::string> responseHeaders = download.TryGetProperty<std::string>(DODownloadProperty_HttpResponseHeaders); |
| 430 | + |
400 | 431 | // Finalize is required to flush the data and change the file name. |
401 | 432 | download.Finalize(); |
402 | 433 | AICLI_LOG(Core, Info, << "Download completed."); |
|
0 commit comments