diff --git a/src/AppInstallerCLI/AppInstallerCLI.vcxproj b/src/AppInstallerCLI/AppInstallerCLI.vcxproj
index d818f0e343..52e9f4ab96 100644
--- a/src/AppInstallerCLI/AppInstallerCLI.vcxproj
+++ b/src/AppInstallerCLI/AppInstallerCLI.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -247,13 +247,13 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCLI/packages.config b/src/AppInstallerCLI/packages.config
index f32f48b009..0495acb040 100644
--- a/src/AppInstallerCLI/packages.config
+++ b/src/AppInstallerCLI/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj b/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
index 9d92771cc6..d14e4c5cac 100644
--- a/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
+++ b/src/AppInstallerCLICore/AppInstallerCLICore.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -480,15 +480,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCLICore/packages.config b/src/AppInstallerCLICore/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/AppInstallerCLICore/packages.config
+++ b/src/AppInstallerCLICore/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
index ba0ced5853..4bc7051f23 100644
--- a/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
+++ b/src/AppInstallerCLITests/AppInstallerCLITests.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -1137,14 +1137,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCLITests/packages.config b/src/AppInstallerCLITests/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/AppInstallerCLITests/packages.config
+++ b/src/AppInstallerCLITests/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj
index 302805976d..d63e68789a 100644
--- a/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj
+++ b/src/AppInstallerCommonCore/AppInstallerCommonCore.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -466,14 +466,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp b/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp
index 1da48efa8c..780fce2247 100644
--- a/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp
+++ b/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.cpp
@@ -1,190 +1,185 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-#include "pch.h"
-#include "Public/AppInstallerStrings.h"
-#include "HttpClientWrapper.h"
-#include "Public/AppInstallerRuntime.h"
-#include "Public/AppInstallerDownloader.h"
-
-using namespace winrt::Windows::Foundation;
-using namespace winrt::Windows::Security::Cryptography;
-using namespace winrt::Windows::Storage;
-using namespace winrt::Windows::Storage::Streams;
-using namespace winrt::Windows::Web::Http;
-using namespace winrt::Windows::Web::Http::Headers;
-using namespace winrt::Windows::Web::Http::Filters;
-
-// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API
-// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
-// The HRESULTs will be mapped to UI error code by the appropriate component
-namespace AppInstaller::Utility::HttpStream
-{
- std::future> HttpClientWrapper::CreateAsync(const Uri& uri)
- {
- // TODO: Use proxy info. HttpClient does not support using a custom proxy, only using the system-wide one.
- std::shared_ptr instance = std::make_shared();
-
- // Use an HTTP filter to disable the default caching behavior and use the Most Recent caching behavior instead
- // so we don't use a stale cached resource. Note: this wrapper object is used in the custom HTTP stream implementation
- // so this affects the parsing of HTTP-based packages/bundles.
- HttpBaseProtocolFilter filter;
- filter.CacheControl().ReadBehavior(HttpCacheReadBehavior::MostRecent);
- instance->m_httpClient = HttpClient(filter);
- instance->m_requestUri = uri;
-
- instance->m_httpClient.DefaultRequestHeaders().Connection().Clear();
- instance->m_httpClient.DefaultRequestHeaders().Append(L"Connection", L"Keep-Alive");
- instance->m_httpClient.DefaultRequestHeaders().UserAgent().ParseAdd(Utility::ConvertToUTF16(Runtime::GetDefaultUserAgent().get()));
-
- co_await instance->PopulateInfoAsync();
-
- co_return instance;
- }
-
- // this function will issue a HEAD request to determine the size of the file and the redirect URI
- std::future HttpClientWrapper::PopulateInfoAsync()
- {
- HttpRequestMessage request(HttpMethod::Head(), m_requestUri);
-
- HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);
-
- switch (response.StatusCode())
- {
- case HttpStatusCode::Ok:
- // All good
- break;
- case HttpStatusCode::TooManyRequests:
- case HttpStatusCode::ServiceUnavailable:
- {
- THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));
- }
- default:
- THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));
- }
-
- // Get the length from the response
- if (response.Content().Headers().HasKey(L"Content-Length"))
- {
- std::wstring contentLength(response.Content().Headers().Lookup(L"Content-Length"));
- m_sizeInBytes = std::stoll(contentLength);
- }
- else
- {
- m_sizeInBytes = 0;
- }
-
- // Get the extension from the redirect URI
- m_redirectUri = response.RequestMessage().RequestUri();
-
- m_contentType = response.Content().Headers().HasKey(L"Content-Type") ?
- response.Content().Headers().Lookup(L"Content-Type")
- : L"";
-
- // If the size wasn't resolved try with a GET 0-0 request
- if (m_sizeInBytes == 0)
- {
- co_await SendHttpRequestAsync(0, 1);
- }
- }
-
-#ifdef WINGET_DISABLE_FOR_FUZZING
-#pragma warning( push )
-#pragma warning( disable : 4714) // HRESULT_FROM_WIN32 marked as forceinline not inlined
-#endif
-
- std::future HttpClientWrapper::SendHttpRequestAsync(
- _In_ ULONG64 startPosition,
- _In_ UINT32 requestedSizeInBytes)
- {
- unsigned long long endPosition = 0;
-
- winrt::check_hresult(ULong64Add(startPosition, requestedSizeInBytes, &endPosition));
-
- // Subtracting one should be safe, as the consumer of the stream should not request
- // an empty range, so this number can't go negative.
- endPosition -= 1;
-
- std::wstring rangeHeaderValue = L"bytes=" + std::to_wstring(startPosition) + L"-" + std::to_wstring(endPosition);
-
- HttpRequestMessage request(HttpMethod::Get(), m_requestUri);
- request.Headers().Append(L"Range", rangeHeaderValue);
-
- if (!Utility::IsEmptyOrWhitespace(m_etagHeader))
- {
- request.Headers().Append(L"If-Match", m_etagHeader);
- }
-
- if (!Utility::IsEmptyOrWhitespace(m_lastModifiedHeader))
- {
- request.Headers().Append(L"If-Unmodified-Since", m_lastModifiedHeader);
- }
-
- HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);
- HttpContentHeaderCollection contentHeaders = response.Content().Headers();
-
- switch (response.StatusCode())
- {
- case HttpStatusCode::Ok:
- case HttpStatusCode::PartialContent:
- // All good
- break;
- case HttpStatusCode::TooManyRequests:
- case HttpStatusCode::ServiceUnavailable:
- {
- THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));
- }
- default:
- THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));
- }
-
- if (response.StatusCode() != HttpStatusCode::PartialContent && startPosition != 0)
- {
- // throw HRESULT used for range-request error
- THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));
- }
-
- if (response.Headers().HasKey(L"Accept-Ranges") &&
- Utility::ToLower(std::wstring(response.Headers().Lookup(L"Accept-Ranges"))) == L"none")
- {
- // throw HRESULT used for range-request error
- THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));
- }
-
- if (Utility::IsEmptyOrWhitespace(m_etagHeader) && response.Headers().HasKey(L"ETag"))
- {
- m_etagHeader = response.Headers().Lookup(L"ETag");
- }
-
- if (Utility::IsEmptyOrWhitespace(m_lastModifiedHeader) && contentHeaders.HasKey(L"Last-Modified"))
- {
- m_lastModifiedHeader = contentHeaders.Lookup(L"Last-Modified");
- }
-
- // If we don't know the size, parse it from the Content-Range field.
- if (m_sizeInBytes == 0 && contentHeaders.HasKey(L"Content-Range"))
- {
- // format: a-b/x where x is either a number or *
- std::wstring contentRange(contentHeaders.Lookup(L"Content-Range"));
- std::wstring length = contentRange.substr(contentRange.find(L"/") + 1);
- m_sizeInBytes = (length == L"*") ? 0 : std::stoll(length);
- }
-
- co_return co_await response.Content().ReadAsBufferAsync();
- }
-
-#ifdef WINGET_DISABLE_FOR_FUZZING
-#pragma warning( pop )
-#endif
-
- std::future HttpClientWrapper::DownloadRangeAsync(
- const ULONG64 startPosition,
- const UINT32 requestedSizeInBytes,
- const InputStreamOptions& options)
- {
- std::vector byteArray(requestedSizeInBytes);
- IBuffer buffer = CryptographicBuffer::CreateFromByteArray(byteArray);
-
- co_return co_await SendHttpRequestAsync(startPosition, requestedSizeInBytes);
- }
-}
\ No newline at end of file
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "Public/AppInstallerStrings.h"
+#include "HttpClientWrapper.h"
+#include "Public/AppInstallerRuntime.h"
+#include "Public/AppInstallerDownloader.h"
+
+using namespace winrt::Windows::Foundation;
+using namespace winrt::Windows::Security::Cryptography;
+using namespace winrt::Windows::Storage;
+using namespace winrt::Windows::Storage::Streams;
+using namespace winrt::Windows::Web::Http;
+using namespace winrt::Windows::Web::Http::Headers;
+using namespace winrt::Windows::Web::Http::Filters;
+
+// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API
+// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
+// The HRESULTs will be mapped to UI error code by the appropriate component
+namespace AppInstaller::Utility::HttpStream
+{
+ std::shared_ptr HttpClientWrapper::Create(const Uri& uri)
+ {
+ // TODO: Use proxy info. HttpClient does not support using a custom proxy, only using the system-wide one.
+ std::shared_ptr instance = std::make_shared();
+
+ // Use an HTTP filter to disable the default caching behavior and use the Most Recent caching behavior instead
+ // so we don't use a stale cached resource. Note: this wrapper object is used in the custom HTTP stream implementation
+ // so this affects the parsing of HTTP-based packages/bundles.
+ HttpBaseProtocolFilter filter;
+ filter.CacheControl().ReadBehavior(HttpCacheReadBehavior::MostRecent);
+ instance->m_httpClient = HttpClient(filter);
+ instance->m_requestUri = uri;
+
+ instance->m_httpClient.DefaultRequestHeaders().Connection().Clear();
+ instance->m_httpClient.DefaultRequestHeaders().Append(L"Connection", L"Keep-Alive");
+ instance->m_httpClient.DefaultRequestHeaders().UserAgent().ParseAdd(Utility::ConvertToUTF16(Runtime::GetDefaultUserAgent().get()));
+
+ return instance;
+ }
+
+ // this function will issue a HEAD request to determine the size of the file and the redirect URI
+ IAsyncAction HttpClientWrapper::PopulateInfoAsync()
+ {
+ HttpRequestMessage request(HttpMethod::Head(), m_requestUri);
+
+ HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);
+
+ switch (response.StatusCode())
+ {
+ case HttpStatusCode::Ok:
+ // All good
+ break;
+ case HttpStatusCode::TooManyRequests:
+ case HttpStatusCode::ServiceUnavailable:
+ {
+ THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));
+ }
+ default:
+ THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));
+ }
+
+ // Get the length from the response
+ if (response.Content().Headers().HasKey(L"Content-Length"))
+ {
+ std::wstring contentLength(response.Content().Headers().Lookup(L"Content-Length"));
+ m_sizeInBytes = std::stoll(contentLength);
+ }
+ else
+ {
+ m_sizeInBytes = 0;
+ }
+
+ // Get the extension from the redirect URI
+ m_redirectUri = response.RequestMessage().RequestUri();
+
+ m_contentType = response.Content().Headers().HasKey(L"Content-Type") ?
+ response.Content().Headers().Lookup(L"Content-Type")
+ : L"";
+
+ // If the size wasn't resolved try with a GET 0-0 request
+ if (m_sizeInBytes == 0)
+ {
+ co_await SendHttpRequestAsync(0, 1);
+ }
+ }
+
+#ifdef WINGET_DISABLE_FOR_FUZZING
+#pragma warning( push )
+#pragma warning( disable : 4714) // HRESULT_FROM_WIN32 marked as forceinline not inlined
+#endif
+
+ IAsyncOperation HttpClientWrapper::SendHttpRequestAsync(
+ _In_ ULONG64 startPosition,
+ _In_ UINT32 requestedSizeInBytes)
+ {
+ unsigned long long endPosition = 0;
+
+ winrt::check_hresult(ULong64Add(startPosition, requestedSizeInBytes, &endPosition));
+
+ // Subtracting one should be safe, as the consumer of the stream should not request
+ // an empty range, so this number can't go negative.
+ endPosition -= 1;
+
+ std::wstring rangeHeaderValue = L"bytes=" + std::to_wstring(startPosition) + L"-" + std::to_wstring(endPosition);
+
+ HttpRequestMessage request(HttpMethod::Get(), m_requestUri);
+ request.Headers().Append(L"Range", rangeHeaderValue);
+
+ if (!Utility::IsEmptyOrWhitespace(m_etagHeader))
+ {
+ request.Headers().Append(L"If-Match", m_etagHeader);
+ }
+
+ if (!Utility::IsEmptyOrWhitespace(m_lastModifiedHeader))
+ {
+ request.Headers().Append(L"If-Unmodified-Since", m_lastModifiedHeader);
+ }
+
+ HttpResponseMessage response = co_await m_httpClient.SendRequestAsync(request, HttpCompletionOption::ResponseHeadersRead);
+ HttpContentHeaderCollection contentHeaders = response.Content().Headers();
+
+ switch (response.StatusCode())
+ {
+ case HttpStatusCode::Ok:
+ case HttpStatusCode::PartialContent:
+ // All good
+ break;
+ case HttpStatusCode::TooManyRequests:
+ case HttpStatusCode::ServiceUnavailable:
+ {
+ THROW_EXCEPTION(ServiceUnavailableException(GetRetryAfter(response)));
+ }
+ default:
+ THROW_HR(MAKE_HRESULT(SEVERITY_ERROR, FACILITY_HTTP, response.StatusCode()));
+ }
+
+ if (response.StatusCode() != HttpStatusCode::PartialContent && startPosition != 0)
+ {
+ // throw HRESULT used for range-request error
+ THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));
+ }
+
+ if (response.Headers().HasKey(L"Accept-Ranges") &&
+ Utility::ToLower(std::wstring(response.Headers().Lookup(L"Accept-Ranges"))) == L"none")
+ {
+ // throw HRESULT used for range-request error
+ THROW_HR(HRESULT_FROM_WIN32(ERROR_NO_RANGES_PROCESSED));
+ }
+
+ if (Utility::IsEmptyOrWhitespace(m_etagHeader) && response.Headers().HasKey(L"ETag"))
+ {
+ m_etagHeader = response.Headers().Lookup(L"ETag");
+ }
+
+ if (Utility::IsEmptyOrWhitespace(m_lastModifiedHeader) && contentHeaders.HasKey(L"Last-Modified"))
+ {
+ m_lastModifiedHeader = contentHeaders.Lookup(L"Last-Modified");
+ }
+
+ // If we don't know the size, parse it from the Content-Range field.
+ if (m_sizeInBytes == 0 && contentHeaders.HasKey(L"Content-Range"))
+ {
+ // format: a-b/x where x is either a number or *
+ std::wstring contentRange(contentHeaders.Lookup(L"Content-Range"));
+ std::wstring length = contentRange.substr(contentRange.find(L"/") + 1);
+ m_sizeInBytes = (length == L"*") ? 0 : std::stoll(length);
+ }
+
+ co_return co_await response.Content().ReadAsBufferAsync();
+ }
+
+#ifdef WINGET_DISABLE_FOR_FUZZING
+#pragma warning( pop )
+#endif
+
+ IAsyncOperation HttpClientWrapper::DownloadRangeAsync(
+ const ULONG64 startPosition,
+ const UINT32 requestedSizeInBytes,
+ const InputStreamOptions&)
+ {
+ return SendHttpRequestAsync(startPosition, requestedSizeInBytes);
+ }
+}
diff --git a/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.h b/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.h
index 9924c48e19..c9d3f92684 100644
--- a/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.h
+++ b/src/AppInstallerCommonCore/HttpStream/HttpClientWrapper.h
@@ -1,51 +1,52 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-#pragma once
-#include
-#include
-
-namespace AppInstaller::Utility::HttpStream
-{
- // Wrapper around HTTP client. When created, an object of this class will send a HTTP
- // head request to determine the size of the data source.
- class HttpClientWrapper
- {
- public:
- static std::future> CreateAsync(const winrt::Windows::Foundation::Uri& uri);
-
- std::future DownloadRangeAsync(
- const ULONG64 startPosition,
- const UINT32 requestedSizeInBytes,
- const winrt::Windows::Storage::Streams::InputStreamOptions& options);
-
- unsigned long long GetFullFileSize()
- {
- return m_sizeInBytes;
- }
-
- winrt::Windows::Foundation::Uri GetRedirectUri()
- {
- return m_redirectUri;
- }
-
- std::wstring GetContentType()
- {
- return m_contentType;
- }
-
- private:
- winrt::Windows::Web::Http::HttpClient m_httpClient;
- winrt::Windows::Foundation::Uri m_requestUri = nullptr;
- winrt::Windows::Foundation::Uri m_redirectUri = nullptr;
- std::wstring m_contentType;
- unsigned long long m_sizeInBytes = 0;
- std::wstring m_etagHeader;
- std::wstring m_lastModifiedHeader;
-
- std::future PopulateInfoAsync();
-
- std::future SendHttpRequestAsync(
- _In_ ULONG64 startPosition,
- _In_ UINT32 requestedSizeInBytes);
- };
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+#pragma once
+#include
+#include
+
+namespace AppInstaller::Utility::HttpStream
+{
+ // Wrapper around HTTP client. When created, an object of this class will send a HTTP
+ // head request to determine the size of the data source.
+ class HttpClientWrapper
+ {
+ public:
+ // Create returns an uninitialized wrapper. Callers must co_await PopulateInfoAsync() before use.
+ static std::shared_ptr Create(const winrt::Windows::Foundation::Uri& uri);
+
+ winrt::Windows::Foundation::IAsyncAction PopulateInfoAsync();
+
+ winrt::Windows::Foundation::IAsyncOperation DownloadRangeAsync(
+ const ULONG64 startPosition,
+ const UINT32 requestedSizeInBytes,
+ const winrt::Windows::Storage::Streams::InputStreamOptions& options);
+
+ unsigned long long GetFullFileSize()
+ {
+ return m_sizeInBytes;
+ }
+
+ winrt::Windows::Foundation::Uri GetRedirectUri()
+ {
+ return m_redirectUri;
+ }
+
+ std::wstring GetContentType()
+ {
+ return m_contentType;
+ }
+
+ private:
+ winrt::Windows::Web::Http::HttpClient m_httpClient;
+ winrt::Windows::Foundation::Uri m_requestUri = nullptr;
+ winrt::Windows::Foundation::Uri m_redirectUri = nullptr;
+ std::wstring m_contentType;
+ unsigned long long m_sizeInBytes = 0;
+ std::wstring m_etagHeader;
+ std::wstring m_lastModifiedHeader;
+
+ winrt::Windows::Foundation::IAsyncOperation SendHttpRequestAsync(
+ _In_ ULONG64 startPosition,
+ _In_ UINT32 requestedSizeInBytes);
+ };
}
\ No newline at end of file
diff --git a/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.cpp b/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.cpp
index c8fb2fba63..9b87e4e42f 100644
--- a/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.cpp
+++ b/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.cpp
@@ -1,246 +1,246 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-#include "pch.h"
-#include "HttpLocalCache.h"
-
-using namespace Windows::Storage::Streams;
-using namespace winrt::Windows::Storage::Streams;
-using namespace winrt::Windows::Security::Cryptography;
-
-// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API
-// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
-// The HRESULTs will be mapped to UI error code by the appropriate component
-namespace AppInstaller::Utility::HttpStream
-{
- std::future HttpLocalCache::ReadFromCacheAndDownloadIfNecessaryAsync(
- const ULONG64 requestedPosition,
- const UINT32 requestedSize,
- HttpClientWrapper* httpClientWrapper,
- InputStreamOptions httpInputStreamOptions)
- {
- // Increment cache access counter user for implementing LRU replacement
- m_accessCounter++;
-
- // Find all the pages for the given request, and the pages that are missing
- std::vector allPages;
- std::vector unsatisfiablePages;
- FindCachePages(requestedPosition, requestedSize, allPages, unsatisfiablePages);
-
- // download the missing pages
- co_await DownloadAndSaveToCacheAsync(
- unsatisfiablePages,
- httpClientWrapper,
- httpInputStreamOptions);
-
- // At this point, everything should be in the cache
- IBuffer constructedBuffer = {};
-
- for (UINT32 i = 0; i < allPages.size(); i++)
- {
- UINT64 pageOffset = allPages[i];
- IBuffer cachedPageBuffer = ReadPageFromCache(pageOffset);
- constructedBuffer = ConcatenateBuffers(constructedBuffer, cachedPageBuffer);
- }
-
- // trim buffer to match requested range
- IBuffer requestedBuffer = TrimBufferToSatisfyRequest(
- constructedBuffer,
- requestedPosition,
- requestedSize,
- allPages);
-
- VacateStaleEntriesFromCache();
-
- co_return requestedBuffer;
- }
-
- void HttpLocalCache::FindCachePages(
- ULONG64 requestedPosition,
- UINT32 requestedSize,
- std::vector& allPages,
- std::vector& unsatisfiablePages)
- {
- ULONG64 requestedEndPosition;
- ULONG64 currentPageOffset;
- winrt::check_hresult(ULong64Add(requestedPosition, requestedSize, &requestedEndPosition));
- winrt::check_hresult(ULong64Mult((requestedPosition / PAGE_SIZE), PAGE_SIZE, ¤tPageOffset));
-
- // There's always at least one page for the range
- do
- {
- allPages.push_back(currentPageOffset);
-
- if (m_localCache.find(currentPageOffset) == m_localCache.end())
- {
- unsatisfiablePages.push_back(currentPageOffset);
- }
-
- winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, ¤tPageOffset));
-
- } while (currentPageOffset < requestedEndPosition);
- }
-
- // Breaks the provided buffer into smaller buffers and saves them to the cache at the corresponding
- // page offset position, starting at firstPageOffset. The smaller buffers are all PAGE_SIZE bytes,
- // except for the one corresponding to the last page in the file
- void HttpLocalCache::SaveBufferToCache(const IBuffer& buffer, const ULONG64 firstPageOffset)
- {
- UINT32 remainingBufferSize = buffer.Length();
- UINT32 currentBufferIndex = 0;
- ULONG64 currentPageOffset = firstPageOffset;
-
- while (remainingBufferSize > 0)
- {
- // Extract the sub-buffer
- UINT32 currentPageSize = std::min(remainingBufferSize, PAGE_SIZE);
- IBuffer currentPageBuffer = CreateTrimmedBuffer(buffer, currentBufferIndex, currentPageSize);
-
- // Add it to the cache
- CachedPage currentPage;
- currentPage.lastAccessCounter = m_accessCounter;
- currentPage.buffer = currentPageBuffer;
- m_localCache[currentPageOffset] = currentPage;
-
- // update loop vars
- winrt::check_hresult(UInt32Sub(remainingBufferSize, currentPageSize, &remainingBufferSize));
- winrt::check_hresult(UInt32Add(currentBufferIndex, currentPageSize, ¤tBufferIndex));
- winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, ¤tPageOffset));
- }
- }
-
- IBuffer HttpLocalCache::ReadPageFromCache(const ULONG64 pageOffset)
- {
- if (!(m_localCache.find(pageOffset) != m_localCache.end()))
- {
- THROW_HR(E_INVALIDARG);
- }
-
- CachedPage& page = m_localCache[pageOffset];
- page.lastAccessCounter = m_accessCounter;
-
- return page.buffer;
- }
-
- // Trims a buffer that was constructed (by fetching pages from cache and downloading missing pages)
- // in order to satisfy a request and return the exact buffer the consumer asked for.
- IBuffer HttpLocalCache::TrimBufferToSatisfyRequest(
- const IBuffer& constructedBuffer,
- const ULONG64 requestedPosition,
- const UINT32 requestedSize,
- const std::vector allPages)
- {
- ULONG64 fullBufferStartOffset = allPages[0];
-
- ULONG64 trimmedBufferStartRelativeIndex;
- winrt::check_hresult(ULong64Sub(requestedPosition, fullBufferStartOffset, &trimmedBufferStartRelativeIndex));
-
- IBuffer requestedBuffer = CreateTrimmedBuffer(
- constructedBuffer,
- (UINT32)trimmedBufferStartRelativeIndex, // Conversion is safe as buffer size is a UINT32.
- requestedSize);
-
- return requestedBuffer;
- }
-
- // Downloads a chunk of the file, saves it to the cache, and returns the corresponding buffer
- // If the requested size is 0, this method returns an empty buffer without making HTTP calls
- std::future HttpLocalCache::DownloadAndSaveToCacheAsync(
- const std::vector unsatisfiablePages,
- HttpClientWrapper* httpClientWrapper,
- InputStreamOptions httpInputStreamOptions)
- {
- // Determine the download job
- // To make things easy, we will download the contiguous range that includes all the unsatisfiable ranges.
- // Note that in theory, this may include cached pages. However, this situation is rarely expected to happen,
- // if at all. The package reader usually reads things in chunks of 64 KB or less, so, we should expect to
- // always have up to two satisfiable and unsatisfiable pages in total.
- UINT64 fileSize = httpClientWrapper->GetFullFileSize();
- ULONG64 downloadJobStartPosition = 0U;
- ULONG64 downloadJobEndPosition = 0U;
- ULONG64 downloadJobSize = 0U;
- if (unsatisfiablePages.size() > 0U)
- {
- downloadJobStartPosition = unsatisfiablePages[0];
- ULONG64 lastUnsatisfiableJob = unsatisfiablePages[unsatisfiablePages.size() - 1];
- winrt::check_hresult(ULong64Add(lastUnsatisfiableJob, PAGE_SIZE, &downloadJobEndPosition));
-
- // make sure to not overflow file size
- downloadJobEndPosition = std::min(downloadJobEndPosition, fileSize);
- winrt::check_hresult(ULong64Sub(downloadJobEndPosition, downloadJobStartPosition, &downloadJobSize));
- }
-
- if (downloadJobSize != 0U)
- {
- // start download job
- IBuffer downloadedBuffer = co_await httpClientWrapper->DownloadRangeAsync(
- downloadJobStartPosition,
- (UINT32)downloadJobSize,
- httpInputStreamOptions);
-
- SaveBufferToCache(downloadedBuffer, downloadJobStartPosition);
- }
- }
-
- void HttpLocalCache::VacateStaleEntriesFromCache()
- {
- // Copy page offsets into vector and sort by the access counter
- std::vector> orderedPageOffsets;
- for (auto pageIter = m_localCache.begin(); pageIter != m_localCache.end(); pageIter++)
- {
- orderedPageOffsets.push_back(std::pair(pageIter->first, pageIter->second.lastAccessCounter));
- }
-
- // Compare function to sort by access counter
- auto cmp = [](std::pair const & a, std::pair const & b)
- {
- return a.second != b.second ? a.second < b.second : a.first < b.first;
- };
-
- std::sort(orderedPageOffsets.begin(), orderedPageOffsets.end(), cmp);
-
- for (auto pageIter = orderedPageOffsets.begin(); pageIter != orderedPageOffsets.end(); pageIter++)
- {
- if (m_localCache.size() > MAX_PAGES)
- {
- m_localCache.erase(pageIter->first);
- }
- else
- {
- break;
- }
- }
- }
-
- IBuffer HttpLocalCache::CreateTrimmedBuffer(
- const IBuffer& originalBuffer,
- UINT32 trimStartIndex,
- UINT32 size)
- {
- uint32_t bufferLength = originalBuffer.Length();
- THROW_HR_IF(E_INVALIDARG, trimStartIndex > bufferLength);
-
- originalBuffer.as<::IInspectable>();
-
- // Get the byte array from the IBuffer object
- Microsoft::WRL::ComPtr bufferByteAccess;
- ::IInspectable* bufferAbi = (::IInspectable*)winrt::get_abi(originalBuffer);
- bufferAbi->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
- byte* byteBuffer = nullptr;
- bufferByteAccess->Buffer(&byteBuffer);
-
- // Create the array of bytes holding the trimmed bytes
- IBuffer trimmedBuffer = CryptographicBuffer::CreateFromByteArray(
- { byteBuffer + trimStartIndex, std::min(size, bufferLength - trimStartIndex) });
-
- return trimmedBuffer;
- }
-
- IBuffer HttpLocalCache::ConcatenateBuffers(const IBuffer& buffer1, const IBuffer& buffer2)
- {
- DataWriter writer;
- writer.WriteBuffer(buffer1);
- writer.WriteBuffer(buffer2);
- return writer.DetachBuffer();
- }
-}
\ No newline at end of file
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "HttpLocalCache.h"
+
+using namespace Windows::Storage::Streams;
+using namespace winrt::Windows::Storage::Streams;
+using namespace winrt::Windows::Security::Cryptography;
+
+// Note: this class is used by the HttpRandomAccessStream which is passed to the AppxPackaging COM API
+// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
+// The HRESULTs will be mapped to UI error code by the appropriate component
+namespace AppInstaller::Utility::HttpStream
+{
+ winrt::Windows::Foundation::IAsyncOperation HttpLocalCache::ReadFromCacheAndDownloadIfNecessaryAsync(
+ const ULONG64 requestedPosition,
+ const UINT32 requestedSize,
+ HttpClientWrapper* httpClientWrapper,
+ InputStreamOptions httpInputStreamOptions)
+ {
+ // Increment cache access counter user for implementing LRU replacement
+ m_accessCounter++;
+
+ // Find all the pages for the given request, and the pages that are missing
+ std::vector allPages;
+ std::vector unsatisfiablePages;
+ FindCachePages(requestedPosition, requestedSize, allPages, unsatisfiablePages);
+
+ // download the missing pages
+ co_await DownloadAndSaveToCacheAsync(
+ unsatisfiablePages,
+ httpClientWrapper,
+ httpInputStreamOptions);
+
+ // At this point, everything should be in the cache
+ IBuffer constructedBuffer = {};
+
+ for (UINT32 i = 0; i < allPages.size(); i++)
+ {
+ UINT64 pageOffset = allPages[i];
+ IBuffer cachedPageBuffer = ReadPageFromCache(pageOffset);
+ constructedBuffer = ConcatenateBuffers(constructedBuffer, cachedPageBuffer);
+ }
+
+ // trim buffer to match requested range
+ IBuffer requestedBuffer = TrimBufferToSatisfyRequest(
+ constructedBuffer,
+ requestedPosition,
+ requestedSize,
+ allPages);
+
+ VacateStaleEntriesFromCache();
+
+ co_return requestedBuffer;
+ }
+
+ void HttpLocalCache::FindCachePages(
+ ULONG64 requestedPosition,
+ UINT32 requestedSize,
+ std::vector& allPages,
+ std::vector& unsatisfiablePages)
+ {
+ ULONG64 requestedEndPosition;
+ ULONG64 currentPageOffset;
+ winrt::check_hresult(ULong64Add(requestedPosition, requestedSize, &requestedEndPosition));
+ winrt::check_hresult(ULong64Mult((requestedPosition / PAGE_SIZE), PAGE_SIZE, ¤tPageOffset));
+
+ // There's always at least one page for the range
+ do
+ {
+ allPages.push_back(currentPageOffset);
+
+ if (m_localCache.find(currentPageOffset) == m_localCache.end())
+ {
+ unsatisfiablePages.push_back(currentPageOffset);
+ }
+
+ winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, ¤tPageOffset));
+
+ } while (currentPageOffset < requestedEndPosition);
+ }
+
+ // Breaks the provided buffer into smaller buffers and saves them to the cache at the corresponding
+ // page offset position, starting at firstPageOffset. The smaller buffers are all PAGE_SIZE bytes,
+ // except for the one corresponding to the last page in the file
+ void HttpLocalCache::SaveBufferToCache(const IBuffer& buffer, const ULONG64 firstPageOffset)
+ {
+ UINT32 remainingBufferSize = buffer.Length();
+ UINT32 currentBufferIndex = 0;
+ ULONG64 currentPageOffset = firstPageOffset;
+
+ while (remainingBufferSize > 0)
+ {
+ // Extract the sub-buffer
+ UINT32 currentPageSize = std::min(remainingBufferSize, PAGE_SIZE);
+ IBuffer currentPageBuffer = CreateTrimmedBuffer(buffer, currentBufferIndex, currentPageSize);
+
+ // Add it to the cache
+ CachedPage currentPage;
+ currentPage.lastAccessCounter = m_accessCounter;
+ currentPage.buffer = currentPageBuffer;
+ m_localCache[currentPageOffset] = currentPage;
+
+ // update loop vars
+ winrt::check_hresult(UInt32Sub(remainingBufferSize, currentPageSize, &remainingBufferSize));
+ winrt::check_hresult(UInt32Add(currentBufferIndex, currentPageSize, ¤tBufferIndex));
+ winrt::check_hresult(ULong64Add(currentPageOffset, PAGE_SIZE, ¤tPageOffset));
+ }
+ }
+
+ IBuffer HttpLocalCache::ReadPageFromCache(const ULONG64 pageOffset)
+ {
+ if (!(m_localCache.find(pageOffset) != m_localCache.end()))
+ {
+ THROW_HR(E_INVALIDARG);
+ }
+
+ CachedPage& page = m_localCache[pageOffset];
+ page.lastAccessCounter = m_accessCounter;
+
+ return page.buffer;
+ }
+
+ // Trims a buffer that was constructed (by fetching pages from cache and downloading missing pages)
+ // in order to satisfy a request and return the exact buffer the consumer asked for.
+ IBuffer HttpLocalCache::TrimBufferToSatisfyRequest(
+ const IBuffer& constructedBuffer,
+ const ULONG64 requestedPosition,
+ const UINT32 requestedSize,
+ const std::vector allPages)
+ {
+ ULONG64 fullBufferStartOffset = allPages[0];
+
+ ULONG64 trimmedBufferStartRelativeIndex;
+ winrt::check_hresult(ULong64Sub(requestedPosition, fullBufferStartOffset, &trimmedBufferStartRelativeIndex));
+
+ IBuffer requestedBuffer = CreateTrimmedBuffer(
+ constructedBuffer,
+ (UINT32)trimmedBufferStartRelativeIndex, // Conversion is safe as buffer size is a UINT32.
+ requestedSize);
+
+ return requestedBuffer;
+ }
+
+ // Downloads a chunk of the file, saves it to the cache, and returns the corresponding buffer
+ // If the requested size is 0, this method returns an empty buffer without making HTTP calls
+ winrt::Windows::Foundation::IAsyncAction HttpLocalCache::DownloadAndSaveToCacheAsync(
+ const std::vector unsatisfiablePages,
+ HttpClientWrapper* httpClientWrapper,
+ InputStreamOptions httpInputStreamOptions)
+ {
+ // Determine the download job
+ // To make things easy, we will download the contiguous range that includes all the unsatisfiable ranges.
+ // Note that in theory, this may include cached pages. However, this situation is rarely expected to happen,
+ // if at all. The package reader usually reads things in chunks of 64 KB or less, so, we should expect to
+ // always have up to two satisfiable and unsatisfiable pages in total.
+ UINT64 fileSize = httpClientWrapper->GetFullFileSize();
+ ULONG64 downloadJobStartPosition = 0U;
+ ULONG64 downloadJobEndPosition = 0U;
+ ULONG64 downloadJobSize = 0U;
+ if (unsatisfiablePages.size() > 0U)
+ {
+ downloadJobStartPosition = unsatisfiablePages[0];
+ ULONG64 lastUnsatisfiableJob = unsatisfiablePages[unsatisfiablePages.size() - 1];
+ winrt::check_hresult(ULong64Add(lastUnsatisfiableJob, PAGE_SIZE, &downloadJobEndPosition));
+
+ // make sure to not overflow file size
+ downloadJobEndPosition = std::min(downloadJobEndPosition, fileSize);
+ winrt::check_hresult(ULong64Sub(downloadJobEndPosition, downloadJobStartPosition, &downloadJobSize));
+ }
+
+ if (downloadJobSize != 0U)
+ {
+ // start download job
+ IBuffer downloadedBuffer = co_await httpClientWrapper->DownloadRangeAsync(
+ downloadJobStartPosition,
+ (UINT32)downloadJobSize,
+ httpInputStreamOptions);
+
+ SaveBufferToCache(downloadedBuffer, downloadJobStartPosition);
+ }
+ }
+
+ void HttpLocalCache::VacateStaleEntriesFromCache()
+ {
+ // Copy page offsets into vector and sort by the access counter
+ std::vector> orderedPageOffsets;
+ for (auto pageIter = m_localCache.begin(); pageIter != m_localCache.end(); pageIter++)
+ {
+ orderedPageOffsets.push_back(std::pair(pageIter->first, pageIter->second.lastAccessCounter));
+ }
+
+ // Compare function to sort by access counter
+ auto cmp = [](std::pair const & a, std::pair const & b)
+ {
+ return a.second != b.second ? a.second < b.second : a.first < b.first;
+ };
+
+ std::sort(orderedPageOffsets.begin(), orderedPageOffsets.end(), cmp);
+
+ for (auto pageIter = orderedPageOffsets.begin(); pageIter != orderedPageOffsets.end(); pageIter++)
+ {
+ if (m_localCache.size() > MAX_PAGES)
+ {
+ m_localCache.erase(pageIter->first);
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ IBuffer HttpLocalCache::CreateTrimmedBuffer(
+ const IBuffer& originalBuffer,
+ UINT32 trimStartIndex,
+ UINT32 size)
+ {
+ uint32_t bufferLength = originalBuffer.Length();
+ THROW_HR_IF(E_INVALIDARG, trimStartIndex > bufferLength);
+
+ originalBuffer.as<::IInspectable>();
+
+ // Get the byte array from the IBuffer object
+ Microsoft::WRL::ComPtr bufferByteAccess;
+ ::IInspectable* bufferAbi = (::IInspectable*)winrt::get_abi(originalBuffer);
+ bufferAbi->QueryInterface(IID_PPV_ARGS(&bufferByteAccess));
+ byte* byteBuffer = nullptr;
+ bufferByteAccess->Buffer(&byteBuffer);
+
+ // Create the array of bytes holding the trimmed bytes
+ IBuffer trimmedBuffer = CryptographicBuffer::CreateFromByteArray(
+ { byteBuffer + trimStartIndex, std::min(size, bufferLength - trimStartIndex) });
+
+ return trimmedBuffer;
+ }
+
+ IBuffer HttpLocalCache::ConcatenateBuffers(const IBuffer& buffer1, const IBuffer& buffer2)
+ {
+ DataWriter writer;
+ writer.WriteBuffer(buffer1);
+ writer.WriteBuffer(buffer2);
+ return writer.DetachBuffer();
+ }
+}
diff --git a/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.h b/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.h
index 97b04ff8e5..6338a86661 100644
--- a/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.h
+++ b/src/AppInstallerCommonCore/HttpStream/HttpLocalCache.h
@@ -1,70 +1,71 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-#pragma once
-
-#include "HttpClientWrapper.h"
-
-namespace AppInstaller::Utility::HttpStream
-{
- // Represents an entry in the cache.
- struct CachedPage
- {
- int lastAccessCounter = 0;
- winrt::Windows::Storage::Streams::IBuffer buffer;
- };
-
- // A cache used internally by the custom HttpRandomAccessStream to reduce round-trips
- class HttpLocalCache
- {
- public:
- static constexpr UINT32 PAGE_SIZE = 2 << 16; // each entry in the cache is 64 KB
- static constexpr UINT32 MAX_PAGES = 200; // cache size capped at 12.5 MB (200 * 64KB)
-
- // Returns a buffer matching the requested range by reading the parts of the range that are cached
- // and downloading the rest using the provided httpClientWrapper object
- std::future ReadFromCacheAndDownloadIfNecessaryAsync(
- const ULONG64 requestedPosition,
- const UINT32 requestedSize,
- HttpClientWrapper* httpClientWrapper,
- winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);
-
- private:
- std::map m_localCache;
- UINT32 m_accessCounter = 0U;
-
- // Returns a vector of all pages corresponding to a range, and another (subset)
- // vector of the pages missing from the cache.
- void FindCachePages(
- const ULONG64 requestedPosition,
- const UINT32 requestedSize,
- std::vector& allPages,
- std::vector& unsatisfiablePages);
-
- void SaveBufferToCache(const winrt::Windows::Storage::Streams::IBuffer& buffer, const ULONG64 firstPageOffset);
-
- winrt::Windows::Storage::Streams::IBuffer ReadPageFromCache(const ULONG64 pageOffset);
-
- void VacateStaleEntriesFromCache();
-
- std::future DownloadAndSaveToCacheAsync(
- const std::vector unsatisfiablePages,
- HttpClientWrapper* httpClientWrapper,
- const winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);
-
- winrt::Windows::Storage::Streams::IBuffer TrimBufferToSatisfyRequest(
- const winrt::Windows::Storage::Streams::IBuffer& constructedBuffer,
- const ULONG64 requestedPosition,
- const UINT32 requestedSize,
- const std::vector allPages);
-
- winrt::Windows::Storage::Streams::IBuffer CreateTrimmedBuffer(
- const winrt::Windows::Storage::Streams::IBuffer& originalBuffer,
- UINT32 trimStartIndex,
- UINT32 size);
-
- winrt::Windows::Storage::Streams::IBuffer ConcatenateBuffers(
- const winrt::Windows::Storage::Streams::IBuffer& buffer1,
- const winrt::Windows::Storage::Streams::IBuffer& buffer2);
- };
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#pragma once
+
+#include
+#include "HttpClientWrapper.h"
+
+namespace AppInstaller::Utility::HttpStream
+{
+ // Represents an entry in the cache.
+ struct CachedPage
+ {
+ int lastAccessCounter = 0;
+ winrt::Windows::Storage::Streams::IBuffer buffer;
+ };
+
+ // A cache used internally by the custom HttpRandomAccessStream to reduce round-trips
+ class HttpLocalCache
+ {
+ public:
+ static constexpr UINT32 PAGE_SIZE = 2 << 16; // each entry in the cache is 64 KB
+ static constexpr UINT32 MAX_PAGES = 200; // cache size capped at 12.5 MB (200 * 64KB)
+
+ // Returns a buffer matching the requested range by reading the parts of the range that are cached
+ // and downloading the rest using the provided httpClientWrapper object
+ winrt::Windows::Foundation::IAsyncOperation ReadFromCacheAndDownloadIfNecessaryAsync(
+ const ULONG64 requestedPosition,
+ const UINT32 requestedSize,
+ HttpClientWrapper* httpClientWrapper,
+ winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);
+
+ private:
+ std::map m_localCache;
+ UINT32 m_accessCounter = 0U;
+
+ // Returns a vector of all pages corresponding to a range, and another (subset)
+ // vector of the pages missing from the cache.
+ void FindCachePages(
+ const ULONG64 requestedPosition,
+ const UINT32 requestedSize,
+ std::vector& allPages,
+ std::vector& unsatisfiablePages);
+
+ void SaveBufferToCache(const winrt::Windows::Storage::Streams::IBuffer& buffer, const ULONG64 firstPageOffset);
+
+ winrt::Windows::Storage::Streams::IBuffer ReadPageFromCache(const ULONG64 pageOffset);
+
+ void VacateStaleEntriesFromCache();
+
+ winrt::Windows::Foundation::IAsyncAction DownloadAndSaveToCacheAsync(
+ const std::vector unsatisfiablePages,
+ HttpClientWrapper* httpClientWrapper,
+ const winrt::Windows::Storage::Streams::InputStreamOptions httpInputStreamOptions);
+
+ winrt::Windows::Storage::Streams::IBuffer TrimBufferToSatisfyRequest(
+ const winrt::Windows::Storage::Streams::IBuffer& constructedBuffer,
+ const ULONG64 requestedPosition,
+ const UINT32 requestedSize,
+ const std::vector allPages);
+
+ winrt::Windows::Storage::Streams::IBuffer CreateTrimmedBuffer(
+ const winrt::Windows::Storage::Streams::IBuffer& originalBuffer,
+ UINT32 trimStartIndex,
+ UINT32 size);
+
+ winrt::Windows::Storage::Streams::IBuffer ConcatenateBuffers(
+ const winrt::Windows::Storage::Streams::IBuffer& buffer1,
+ const winrt::Windows::Storage::Streams::IBuffer& buffer2);
+ };
}
\ No newline at end of file
diff --git a/src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.cpp b/src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.cpp
index 1e4264996f..f352618e2e 100644
--- a/src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.cpp
+++ b/src/AppInstallerCommonCore/HttpStream/HttpRandomAccessStream.cpp
@@ -1,102 +1,104 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License.
-
-#include "pch.h"
-#include "HttpRandomAccessStream.h"
-#include "Public/AppInstallerDownloader.h"
-
-using namespace winrt::Windows::Foundation;
-using namespace winrt::Windows::Storage::Streams;
-
-// Note: the HttpRandomAccessStream is passed to the AppxPackaging COM API
-// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
-// The HRESULTs will be mapped to UI error code by the appropriate component
-namespace AppInstaller::Utility::HttpStream
-{
- IAsyncOperation HttpRandomAccessStream::InitializeAsync(const Uri& uri)
- {
- auto strong_this{ get_strong() };
-
- try
- {
- strong_this->m_httpHelper = co_await HttpClientWrapper::CreateAsync(uri);
- strong_this->m_size = strong_this->m_httpHelper->GetFullFileSize();
- strong_this->m_httpLocalCache = std::make_unique();
- }
- catch (const ServiceUnavailableException& e)
- {
- strong_this->m_retryAfter = e.RetryAfter();
- throw;
- }
-
- co_return strong_this.as();
- }
-
- uint64_t HttpRandomAccessStream::Size() const
- {
- return m_size;
- }
-
- void HttpRandomAccessStream::Size(uint64_t value)
- {
- UNREFERENCED_PARAMETER(value);
- THROW_HR(E_NOTIMPL);
- }
-
- uint64_t HttpRandomAccessStream::Position() const
- {
- return m_requestedPosition;
- }
-
- bool HttpRandomAccessStream::CanRead() const
- {
- return true;
- }
-
- bool HttpRandomAccessStream::CanWrite() const
- {
- return false;
- }
-
- IInputStream HttpRandomAccessStream::GetInputStreamAt(uint64_t position) const
- {
- UNREFERENCED_PARAMETER(position);
- THROW_HR(E_NOTIMPL);
- }
-
- IOutputStream HttpRandomAccessStream::GetOutputStreamAt(uint64_t position) const
- {
- UNREFERENCED_PARAMETER(position);
- THROW_HR(E_NOTIMPL);
- }
-
- IRandomAccessStream HttpRandomAccessStream::CloneStream() const
- {
- THROW_HR(E_NOTIMPL);
- }
-
- void HttpRandomAccessStream::Seek(uint64_t position)
- {
- m_requestedPosition = position;
- }
-
- IAsyncOperationWithProgress HttpRandomAccessStream::ReadAsync(
- IBuffer buffer,
- uint32_t count,
- InputStreamOptions options)
- {
- IBuffer result = co_await m_httpLocalCache->ReadFromCacheAndDownloadIfNecessaryAsync(
- m_requestedPosition,
- count,
- m_httpHelper.get(),
- options);
- winrt::check_hresult(ULong64Add(m_requestedPosition, result.Length(), &m_requestedPosition));
-
- co_return result;
- }
-
- std::chrono::seconds HttpRandomAccessStream::RetryAfter() const
- {
- return m_retryAfter;
- }
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+
+#include "pch.h"
+#include "HttpRandomAccessStream.h"
+#include "Public/AppInstallerDownloader.h"
+
+using namespace winrt::Windows::Foundation;
+using namespace winrt::Windows::Storage::Streams;
+
+// Note: the HttpRandomAccessStream is passed to the AppxPackaging COM API
+// All exceptions thrown across dll boundaries should be WinRT exception not custom exceptions.
+// The HRESULTs will be mapped to UI error code by the appropriate component
+namespace AppInstaller::Utility::HttpStream
+{
+ IAsyncOperation HttpRandomAccessStream::InitializeAsync(const Uri& uri)
+ {
+ auto strong_this{ get_strong() };
+
+ try
+ {
+ auto httpHelper = HttpClientWrapper::Create(uri);
+ co_await httpHelper->PopulateInfoAsync();
+ strong_this->m_httpHelper = std::move(httpHelper);
+ strong_this->m_size = strong_this->m_httpHelper->GetFullFileSize();
+ strong_this->m_httpLocalCache = std::make_unique();
+ }
+ catch (const ServiceUnavailableException& e)
+ {
+ strong_this->m_retryAfter = e.RetryAfter();
+ throw;
+ }
+
+ co_return strong_this.as();
+ }
+
+ uint64_t HttpRandomAccessStream::Size() const
+ {
+ return m_size;
+ }
+
+ void HttpRandomAccessStream::Size(uint64_t value)
+ {
+ UNREFERENCED_PARAMETER(value);
+ THROW_HR(E_NOTIMPL);
+ }
+
+ uint64_t HttpRandomAccessStream::Position() const
+ {
+ return m_requestedPosition;
+ }
+
+ bool HttpRandomAccessStream::CanRead() const
+ {
+ return true;
+ }
+
+ bool HttpRandomAccessStream::CanWrite() const
+ {
+ return false;
+ }
+
+ IInputStream HttpRandomAccessStream::GetInputStreamAt(uint64_t position) const
+ {
+ UNREFERENCED_PARAMETER(position);
+ THROW_HR(E_NOTIMPL);
+ }
+
+ IOutputStream HttpRandomAccessStream::GetOutputStreamAt(uint64_t position) const
+ {
+ UNREFERENCED_PARAMETER(position);
+ THROW_HR(E_NOTIMPL);
+ }
+
+ IRandomAccessStream HttpRandomAccessStream::CloneStream() const
+ {
+ THROW_HR(E_NOTIMPL);
+ }
+
+ void HttpRandomAccessStream::Seek(uint64_t position)
+ {
+ m_requestedPosition = position;
+ }
+
+ IAsyncOperationWithProgress HttpRandomAccessStream::ReadAsync(
+ IBuffer buffer,
+ uint32_t count,
+ InputStreamOptions options)
+ {
+ IBuffer result = co_await m_httpLocalCache->ReadFromCacheAndDownloadIfNecessaryAsync(
+ m_requestedPosition,
+ count,
+ m_httpHelper.get(),
+ options);
+ winrt::check_hresult(ULong64Add(m_requestedPosition, result.Length(), &m_requestedPosition));
+
+ co_return result;
+ }
+
+ std::chrono::seconds HttpRandomAccessStream::RetryAfter() const
+ {
+ return m_retryAfter;
+ }
}
\ No newline at end of file
diff --git a/src/AppInstallerCommonCore/packages.config b/src/AppInstallerCommonCore/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/AppInstallerCommonCore/packages.config
+++ b/src/AppInstallerCommonCore/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj
index 34cc155a46..1d58afec51 100644
--- a/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj
+++ b/src/AppInstallerRepositoryCore/AppInstallerRepositoryCore.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -514,14 +514,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
\ No newline at end of file
diff --git a/src/AppInstallerRepositoryCore/packages.config b/src/AppInstallerRepositoryCore/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/AppInstallerRepositoryCore/packages.config
+++ b/src/AppInstallerRepositoryCore/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj
index adf3c4c6c6..22329e730e 100644
--- a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj
+++ b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -410,15 +410,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters
index 61457db664..142e046444 100644
--- a/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters
+++ b/src/AppInstallerSharedLib/AppInstallerSharedLib.vcxproj.filters
@@ -248,5 +248,6 @@
+
\ No newline at end of file
diff --git a/src/AppInstallerSharedLib/packages.config b/src/AppInstallerSharedLib/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/AppInstallerSharedLib/packages.config
+++ b/src/AppInstallerSharedLib/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/ComInprocTestbed/ComInprocTestbed.vcxproj b/src/ComInprocTestbed/ComInprocTestbed.vcxproj
index b95fad10ff..91e232c838 100644
--- a/src/ComInprocTestbed/ComInprocTestbed.vcxproj
+++ b/src/ComInprocTestbed/ComInprocTestbed.vcxproj
@@ -1,6 +1,6 @@
-
+
15.0
{E5BCFF58-7D0C-4770-ABB9-AECE1027CD94}
@@ -169,9 +169,6 @@
-
-
-
{9ac3c6a4-1875-4d3e-bf9c-c31e81eff6b4}
@@ -209,15 +206,18 @@
+
+
+
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
\ No newline at end of file
diff --git a/src/ComInprocTestbed/ComInprocTestbed.vcxproj.filters b/src/ComInprocTestbed/ComInprocTestbed.vcxproj.filters
index fab38937e9..3fba5fb97e 100644
--- a/src/ComInprocTestbed/ComInprocTestbed.vcxproj.filters
+++ b/src/ComInprocTestbed/ComInprocTestbed.vcxproj.filters
@@ -28,9 +28,6 @@
Source Files
-
-
-
@@ -48,4 +45,7 @@
Header Files
+
+
+
\ No newline at end of file
diff --git a/src/ComInprocTestbed/packages.config b/src/ComInprocTestbed/packages.config
index f32f48b009..0495acb040 100644
--- a/src/ComInprocTestbed/packages.config
+++ b/src/ComInprocTestbed/packages.config
@@ -1,4 +1,4 @@
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj b/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj
index d52da7bcf5..6c7e1404f1 100644
--- a/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj
+++ b/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -413,15 +413,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj.filters b/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj.filters
index 15c52c8a46..20e2b09d55 100644
--- a/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj.filters
+++ b/src/Microsoft.Management.Configuration.OutOfProc/Microsoft.Management.Configuration.OutOfProc.vcxproj.filters
@@ -56,5 +56,6 @@
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration.OutOfProc/packages.config b/src/Microsoft.Management.Configuration.OutOfProc/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/Microsoft.Management.Configuration.OutOfProc/packages.config
+++ b/src/Microsoft.Management.Configuration.OutOfProc/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj
index 53dfe11d66..b96262fccf 100644
--- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj
+++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -312,15 +312,15 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters
index 3901ba8f1b..a20087bd56 100644
--- a/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters
+++ b/src/Microsoft.Management.Configuration/Microsoft.Management.Configuration.vcxproj.filters
@@ -382,5 +382,6 @@
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Configuration/packages.config b/src/Microsoft.Management.Configuration/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/Microsoft.Management.Configuration/packages.config
+++ b/src/Microsoft.Management.Configuration/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj b/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj
index 25367bc4b5..da95005d3f 100644
--- a/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj
+++ b/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -370,19 +370,18 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj.filters b/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj.filters
index 94cb824253..d9b8b2a279 100644
--- a/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj.filters
+++ b/src/Microsoft.Management.Deployment.InProc/Microsoft.Management.Deployment.InProc.vcxproj.filters
@@ -39,5 +39,6 @@
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.InProc/packages.config b/src/Microsoft.Management.Deployment.InProc/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/Microsoft.Management.Deployment.InProc/packages.config
+++ b/src/Microsoft.Management.Deployment.InProc/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj b/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj
index 292dc22273..6043186d32 100644
--- a/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj
+++ b/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -411,15 +411,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj.filters b/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj.filters
index 0a8e916016..ad773990ff 100644
--- a/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj.filters
+++ b/src/Microsoft.Management.Deployment.OutOfProc/Microsoft.Management.Deployment.OutOfProc.vcxproj.filters
@@ -54,5 +54,6 @@
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment.OutOfProc/packages.config b/src/Microsoft.Management.Deployment.OutOfProc/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/Microsoft.Management.Deployment.OutOfProc/packages.config
+++ b/src/Microsoft.Management.Deployment.OutOfProc/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj
index 5eb84d2782..2894e42bac 100644
--- a/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj
+++ b/src/Microsoft.Management.Deployment/Microsoft.Management.Deployment.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -272,15 +272,15 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
\ No newline at end of file
diff --git a/src/Microsoft.Management.Deployment/packages.config b/src/Microsoft.Management.Deployment/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/Microsoft.Management.Deployment/packages.config
+++ b/src/Microsoft.Management.Deployment/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/WinGetUtil/WinGetUtil.vcxproj b/src/WinGetUtil/WinGetUtil.vcxproj
index 12066a2a3b..4e4d707f75 100644
--- a/src/WinGetUtil/WinGetUtil.vcxproj
+++ b/src/WinGetUtil/WinGetUtil.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -269,15 +269,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/WinGetUtil/packages.config b/src/WinGetUtil/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/WinGetUtil/packages.config
+++ b/src/WinGetUtil/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/src/WinGetYamlFuzzing/WinGetYamlFuzzing.vcxproj b/src/WinGetYamlFuzzing/WinGetYamlFuzzing.vcxproj
index f47a72e910..30a25c1a78 100644
--- a/src/WinGetYamlFuzzing/WinGetYamlFuzzing.vcxproj
+++ b/src/WinGetYamlFuzzing/WinGetYamlFuzzing.vcxproj
@@ -1,6 +1,6 @@
-
+
Fuzzing
@@ -98,14 +98,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
+
\ No newline at end of file
diff --git a/src/WinGetYamlFuzzing/packages.config b/src/WinGetYamlFuzzing/packages.config
index f83207db21..132d149574 100644
--- a/src/WinGetYamlFuzzing/packages.config
+++ b/src/WinGetYamlFuzzing/packages.config
@@ -1,5 +1,5 @@
+
-
\ No newline at end of file
diff --git a/src/WindowsPackageManager/ConfigurationStaticFunctions.cpp b/src/WindowsPackageManager/ConfigurationStaticFunctions.cpp
index 6322b83dad..e904c39101 100644
--- a/src/WindowsPackageManager/ConfigurationStaticFunctions.cpp
+++ b/src/WindowsPackageManager/ConfigurationStaticFunctions.cpp
@@ -1,324 +1,324 @@
-// Copyright (c) Microsoft Corporation.
-// Licensed under the MIT License
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace AppInstaller::SelfManagement;
-using namespace winrt::Microsoft::Management::Deployment;
-using namespace winrt::Windows::Foundation::Collections;
-
-namespace ConfigurationShim
-{
- namespace
- {
- static std::atomic_bool s_canBeCreated{ true };
-
- auto GetInternalStatics()
- {
- return winrt::Microsoft::Management::Configuration::ConfigurationStaticFunctions().as();
- }
-
- void BlockNewWorkForShutdown(AppInstaller::CancelReason)
- {
- GetInternalStatics()->BlockNewWorkForShutdown();
- }
-
- void BeginShutdown(AppInstaller::CancelReason)
- {
- GetInternalStatics()->BeginShutdown();
- }
-
- void WaitForShutdown()
- {
- GetInternalStatics()->WaitForShutdown();
- }
-
- void RegisterForShutdownSynchronization()
- {
- static std::once_flag registerComponentOnceFlag;
- std::call_once(registerComponentOnceFlag,
- [&]()
- {
- using namespace AppInstaller::ShutdownMonitoring;
-
- ServerShutdownSynchronization::ComponentSystem component;
- component.BlockNewWork = BlockNewWorkForShutdown;
- component.BeginShutdown = BeginShutdown;
- component.Wait = WaitForShutdown;
-
- ServerShutdownSynchronization::AddComponent(component);
- });
- }
- }
-
- CLSID CLSID_ConfigurationObjectLifetimeWatcher = { 0x89a8f1d4,0x1e24,0x46a4,{0x9f,0x6c,0x65,0x78,0xb0,0x47,0xf2,0xf7} };
-
- struct
- DECLSPEC_UUID("89a8f1d4-1e24-46a4-9f6c-6578b047f2f7")
- ConfigurationObjectLifetimeWatcher : winrt::implements
- {
- };
-
- struct
- DECLSPEC_UUID(WINGET_OUTOFPROC_COM_CLSID_ConfigurationStaticFunctions)
- ConfigurationStaticFunctionsShim : winrt::implements
- {
- ConfigurationStaticFunctionsShim()
- {
- auto threadGlobalsRestore = m_threadGlobals.SetForCurrentThread();
- auto& diagnosticsLogger = m_threadGlobals.GetDiagnosticLogger();
- diagnosticsLogger.SetEnabledChannels(AppInstaller::Logging::Channel::All);
- diagnosticsLogger.SetLevel(AppInstaller::Logging::Level::Verbose);
- diagnosticsLogger.AddLogger(std::make_unique("WinGetCFG"sv));
-
- if (IsConfigurationAvailable())
- {
- m_statics = winrt::Microsoft::Management::Configuration::ConfigurationStaticFunctions().as();
- RegisterForShutdownSynchronization();
- }
- }
-
- winrt::Microsoft::Management::Configuration::ConfigurationUnit CreateConfigurationUnit()
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (!m_statics)
- {
- THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
- }
-
- auto result = m_statics.CreateConfigurationUnit();
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- return result;
- }
-
- winrt::Microsoft::Management::Configuration::ConfigurationSet CreateConfigurationSet()
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (!m_statics)
- {
- THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
- }
-
- auto result = m_statics.CreateConfigurationSet();
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- return result;
- }
-
- winrt::Windows::Foundation::IAsyncOperation CreateConfigurationSetProcessorFactoryAsync(winrt::hstring const& handler)
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- auto strong_this{ get_strong() };
- std::wstring lowerHandler = AppInstaller::Utility::ToLower(handler);
-
- co_await winrt::resume_background();
-
- auto threadGlobalsRestore = m_threadGlobals.SetForCurrentThread();
- winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory result;
-
- if (lowerHandler == AppInstaller::Configuration::PowerShellHandlerIdentifier)
- {
- result = AppInstaller::CLI::ConfigurationRemoting::CreateOutOfProcessFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::PowerShell);
- }
- else if (lowerHandler == AppInstaller::Configuration::DynamicRuntimeHandlerIdentifier)
- {
- result = AppInstaller::CLI::ConfigurationRemoting::CreateDynamicRuntimeFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::PowerShell);
- }
- else if (lowerHandler == AppInstaller::Configuration::DSCv3HandlerIdentifier)
- {
- result = AppInstaller::CLI::ConfigurationRemoting::CreateOutOfProcessFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::DSCv3);
- }
- else if (lowerHandler == AppInstaller::Configuration::DSCv3DynamicRuntimeHandlerIdentifier)
- {
- result = AppInstaller::CLI::ConfigurationRemoting::CreateDynamicRuntimeFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::DSCv3);
- }
-
- if (result)
- {
- // Objects returned here *must* implement ILifetimeWatcher for now.
- // If we create OOP objects implemented elsewhere in the future, decide then how to exempt those while still ensuring we
- // don't accidentally create a lifetime bug by basing it solely off the QI result.
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- co_return result;
- }
-
- AICLI_LOG(Config, Error, << "Unknown handler in CreateConfigurationSetProcessorFactory: " << AppInstaller::Utility::ConvertToUTF8(handler));
- THROW_HR(E_NOT_SET);
- }
-
- winrt::Microsoft::Management::Configuration::ConfigurationProcessor CreateConfigurationProcessor(winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory const& factory)
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (!m_statics)
- {
- THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
- }
-
- auto result = m_statics.CreateConfigurationProcessor(factory);
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- return result;
- }
-
- bool IsConfigurationAvailable()
- {
- return !IsStubPackage();
- }
-
- winrt::Windows::Foundation::IAsyncActionWithProgress EnsureConfigurationAvailableAsync()
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (IsConfigurationAvailable())
- {
- return;
- }
-
- auto strong_this{ get_strong() };
- co_await winrt::resume_background();
-
- SetStubPreferred(false);
-
- PackageManager packageManager;
- PackageCatalogReference catalogRef{ packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::MicrosoftStore) };
- THROW_HR_IF(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, !catalogRef);
-
- ConnectResult connectResult = catalogRef.Connect();
- THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED, connectResult.Status() != ConnectResultStatus::Ok);
-
- PackageCatalog catalog = connectResult.PackageCatalog();
-
- FindPackagesOptions findPackagesOptions;
- PackageMatchFilter filter;
- filter.Field(PackageMatchField::Id);
- filter.Option(PackageFieldMatchOption::Equals);
- filter.Value(AppInstaller::MSStore::s_AppInstallerProductId);
- findPackagesOptions.Filters().Append(filter);
-
- FindPackagesResult findPackagesResult{ catalog.FindPackages(findPackagesOptions) };
-
- auto matches = findPackagesResult.Matches();
- THROW_HR_IF(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE, matches.Size() == 0);
- auto catalogPackage = matches.GetAt(0).CatalogPackage();
-
- InstallOptions installOptions;
- installOptions.AcceptPackageAgreements(true);
- installOptions.AllowUpgradeToUnknownVersion(true);
- installOptions.Force(true);
-
- auto progress = co_await winrt::get_progress_token();
-
- // Don't use UpgradePackageAsync, we don't support upgrade for packages from the msstore
- // it has to be install and internally we know is an update.
- auto installTask = packageManager.InstallPackageAsync(catalogPackage, installOptions);
- installTask.Progress([progress](auto const&, InstallProgress installProgress)
- {
- if (installProgress.State == PackageInstallProgressState::Downloading && installProgress.BytesRequired != 0)
- {
- progress((uint32_t)(installProgress.DownloadProgress * 80));
- }
- else if (installProgress.State == PackageInstallProgressState::Installing)
- {
- progress(((uint32_t)installProgress.InstallationProgress * 20) + 80);
- }
- });
-
- co_await installTask;
- s_canBeCreated = false;
- }
-
- winrt::Microsoft::Management::Configuration::ConfigurationParameter CreateConfigurationParameter()
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (!m_statics)
- {
- THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
- }
-
- auto result = m_statics.CreateConfigurationParameter();
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- return result;
- }
-
- winrt::Microsoft::Management::Configuration::FindUnitProcessorsOptions CreateFindUnitProcessorsOptions()
- {
- THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- if (!m_statics)
- {
- THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
- }
-
- auto result = m_statics.CreateFindUnitProcessorsOptions();
- result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
- return result;
- }
-
- private:
- // Returns a lifetime watcher object that is currently *unowned*.
- IUnknown* CreateLifetimeWatcher()
- {
- ::Microsoft::WRL::ComPtr factory;
- THROW_IF_FAILED(::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::GetModule().GetClassObject(CLSID_ConfigurationObjectLifetimeWatcher, IID_PPV_ARGS(&factory)));
- winrt::com_ptr out;
- THROW_IF_FAILED(factory->CreateInstance(nullptr, __uuidof(IUnknown), out.put_void()));
- return out.detach();
- }
-
- winrt::Microsoft::Management::Configuration::IConfigurationStatics3 m_statics = nullptr;
- AppInstaller::ThreadLocalStorage::WingetThreadGlobals m_threadGlobals;
- };
-
- // Enable custom code to run before creating any object through the factory.
- template
- class ConfigurationFactory : public ::wil::wrl_factory_for_winrt_com_class
- {
- public:
- IFACEMETHODIMP CreateInstance(_In_opt_::IUnknown* unknownOuter, REFIID riid, _COM_Outptr_ void** object) noexcept try
- {
- *object = nullptr;
- RETURN_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet));
- RETURN_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::Configuration));
- RETURN_HR_IF(E_ACCESSDENIED, !::AppInstaller::Security::IsCOMCallerSameUserAndIntegrityLevel());
-
- RETURN_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
-
- return ::wil::wrl_factory_for_winrt_com_class::CreateInstance(unknownOuter, riid, object);
- }
- CATCH_RETURN()
- };
-
-#define CoCreatableMicrosoftManagementConfigurationClass(className) \
- CoCreatableClassWithFactory(className, ::ConfigurationShim::ConfigurationFactory)
-
- // Disable 6388 as it seems to be falsely warning
-#pragma warning(push)
-#pragma warning(disable : 6388)
- CoCreatableCppWinRtClass(ConfigurationObjectLifetimeWatcher);
- CoCreatableMicrosoftManagementConfigurationClass(ConfigurationStaticFunctionsShim);
-#pragma warning(pop)
-}
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace AppInstaller::SelfManagement;
+using namespace winrt::Microsoft::Management::Deployment;
+using namespace winrt::Windows::Foundation::Collections;
+
+namespace ConfigurationShim
+{
+ namespace
+ {
+ static std::atomic_bool s_canBeCreated{ true };
+
+ auto GetInternalStatics()
+ {
+ return winrt::Microsoft::Management::Configuration::ConfigurationStaticFunctions().as();
+ }
+
+ void BlockNewWorkForShutdown(AppInstaller::CancelReason)
+ {
+ GetInternalStatics()->BlockNewWorkForShutdown();
+ }
+
+ void BeginShutdown(AppInstaller::CancelReason)
+ {
+ GetInternalStatics()->BeginShutdown();
+ }
+
+ void WaitForShutdown()
+ {
+ GetInternalStatics()->WaitForShutdown();
+ }
+
+ void RegisterForShutdownSynchronization()
+ {
+ static std::once_flag registerComponentOnceFlag;
+ std::call_once(registerComponentOnceFlag,
+ [&]()
+ {
+ using namespace AppInstaller::ShutdownMonitoring;
+
+ ServerShutdownSynchronization::ComponentSystem component;
+ component.BlockNewWork = BlockNewWorkForShutdown;
+ component.BeginShutdown = BeginShutdown;
+ component.Wait = WaitForShutdown;
+
+ ServerShutdownSynchronization::AddComponent(component);
+ });
+ }
+ }
+
+ CLSID CLSID_ConfigurationObjectLifetimeWatcher = { 0x89a8f1d4,0x1e24,0x46a4,{0x9f,0x6c,0x65,0x78,0xb0,0x47,0xf2,0xf7} };
+
+ struct
+ DECLSPEC_UUID("89a8f1d4-1e24-46a4-9f6c-6578b047f2f7")
+ ConfigurationObjectLifetimeWatcher : winrt::implements
+ {
+ };
+
+ struct
+ DECLSPEC_UUID(WINGET_OUTOFPROC_COM_CLSID_ConfigurationStaticFunctions)
+ ConfigurationStaticFunctionsShim : winrt::implements
+ {
+ ConfigurationStaticFunctionsShim()
+ {
+ auto threadGlobalsRestore = m_threadGlobals.SetForCurrentThread();
+ auto& diagnosticsLogger = m_threadGlobals.GetDiagnosticLogger();
+ diagnosticsLogger.SetEnabledChannels(AppInstaller::Logging::Channel::All);
+ diagnosticsLogger.SetLevel(AppInstaller::Logging::Level::Verbose);
+ diagnosticsLogger.AddLogger(std::make_unique("WinGetCFG"sv));
+
+ if (IsConfigurationAvailable())
+ {
+ m_statics = winrt::Microsoft::Management::Configuration::ConfigurationStaticFunctions().as();
+ RegisterForShutdownSynchronization();
+ }
+ }
+
+ winrt::Microsoft::Management::Configuration::ConfigurationUnit CreateConfigurationUnit()
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (!m_statics)
+ {
+ THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
+ }
+
+ auto result = m_statics.CreateConfigurationUnit();
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ return result;
+ }
+
+ winrt::Microsoft::Management::Configuration::ConfigurationSet CreateConfigurationSet()
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (!m_statics)
+ {
+ THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
+ }
+
+ auto result = m_statics.CreateConfigurationSet();
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ return result;
+ }
+
+ winrt::Windows::Foundation::IAsyncOperation CreateConfigurationSetProcessorFactoryAsync(winrt::hstring const& handler)
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ auto strong_this{ get_strong() };
+ std::wstring lowerHandler = AppInstaller::Utility::ToLower(handler);
+
+ co_await winrt::resume_background();
+
+ auto threadGlobalsRestore = m_threadGlobals.SetForCurrentThread();
+ winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory result;
+
+ if (lowerHandler == AppInstaller::Configuration::PowerShellHandlerIdentifier)
+ {
+ result = AppInstaller::CLI::ConfigurationRemoting::CreateOutOfProcessFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::PowerShell);
+ }
+ else if (lowerHandler == AppInstaller::Configuration::DynamicRuntimeHandlerIdentifier)
+ {
+ result = AppInstaller::CLI::ConfigurationRemoting::CreateDynamicRuntimeFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::PowerShell);
+ }
+ else if (lowerHandler == AppInstaller::Configuration::DSCv3HandlerIdentifier)
+ {
+ result = AppInstaller::CLI::ConfigurationRemoting::CreateOutOfProcessFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::DSCv3);
+ }
+ else if (lowerHandler == AppInstaller::Configuration::DSCv3DynamicRuntimeHandlerIdentifier)
+ {
+ result = AppInstaller::CLI::ConfigurationRemoting::CreateDynamicRuntimeFactory(AppInstaller::CLI::ConfigurationRemoting::ProcessorEngine::DSCv3);
+ }
+
+ if (result)
+ {
+ // Objects returned here *must* implement ILifetimeWatcher for now.
+ // If we create OOP objects implemented elsewhere in the future, decide then how to exempt those while still ensuring we
+ // don't accidentally create a lifetime bug by basing it solely off the QI result.
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ co_return result;
+ }
+
+ AICLI_LOG(Config, Error, << "Unknown handler in CreateConfigurationSetProcessorFactory: " << AppInstaller::Utility::ConvertToUTF8(handler));
+ THROW_HR(E_NOT_SET);
+ }
+
+ winrt::Microsoft::Management::Configuration::ConfigurationProcessor CreateConfigurationProcessor(winrt::Microsoft::Management::Configuration::IConfigurationSetProcessorFactory const& factory)
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (!m_statics)
+ {
+ THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
+ }
+
+ auto result = m_statics.CreateConfigurationProcessor(factory);
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ return result;
+ }
+
+ bool IsConfigurationAvailable()
+ {
+ return !IsStubPackage();
+ }
+
+ winrt::Windows::Foundation::IAsyncActionWithProgress EnsureConfigurationAvailableAsync()
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (IsConfigurationAvailable())
+ {
+ co_return;
+ }
+
+ auto strong_this{ get_strong() };
+ co_await winrt::resume_background();
+
+ SetStubPreferred(false);
+
+ PackageManager packageManager;
+ PackageCatalogReference catalogRef{ packageManager.GetPredefinedPackageCatalog(PredefinedPackageCatalog::MicrosoftStore) };
+ THROW_HR_IF(APPINSTALLER_CLI_ERROR_INTERNAL_ERROR, !catalogRef);
+
+ ConnectResult connectResult = catalogRef.Connect();
+ THROW_HR_IF(APPINSTALLER_CLI_ERROR_SOURCE_OPEN_FAILED, connectResult.Status() != ConnectResultStatus::Ok);
+
+ PackageCatalog catalog = connectResult.PackageCatalog();
+
+ FindPackagesOptions findPackagesOptions;
+ PackageMatchFilter filter;
+ filter.Field(PackageMatchField::Id);
+ filter.Option(PackageFieldMatchOption::Equals);
+ filter.Value(AppInstaller::MSStore::s_AppInstallerProductId);
+ findPackagesOptions.Filters().Append(filter);
+
+ FindPackagesResult findPackagesResult{ catalog.FindPackages(findPackagesOptions) };
+
+ auto matches = findPackagesResult.Matches();
+ THROW_HR_IF(APPINSTALLER_CLI_ERROR_MISSING_PACKAGE, matches.Size() == 0);
+ auto catalogPackage = matches.GetAt(0).CatalogPackage();
+
+ InstallOptions installOptions;
+ installOptions.AcceptPackageAgreements(true);
+ installOptions.AllowUpgradeToUnknownVersion(true);
+ installOptions.Force(true);
+
+ auto progress = co_await winrt::get_progress_token();
+
+ // Don't use UpgradePackageAsync, we don't support upgrade for packages from the msstore
+ // it has to be install and internally we know is an update.
+ auto installTask = packageManager.InstallPackageAsync(catalogPackage, installOptions);
+ installTask.Progress([progress](auto const&, InstallProgress installProgress)
+ {
+ if (installProgress.State == PackageInstallProgressState::Downloading && installProgress.BytesRequired != 0)
+ {
+ progress((uint32_t)(installProgress.DownloadProgress * 80));
+ }
+ else if (installProgress.State == PackageInstallProgressState::Installing)
+ {
+ progress(((uint32_t)installProgress.InstallationProgress * 20) + 80);
+ }
+ });
+
+ co_await installTask;
+ s_canBeCreated = false;
+ }
+
+ winrt::Microsoft::Management::Configuration::ConfigurationParameter CreateConfigurationParameter()
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (!m_statics)
+ {
+ THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
+ }
+
+ auto result = m_statics.CreateConfigurationParameter();
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ return result;
+ }
+
+ winrt::Microsoft::Management::Configuration::FindUnitProcessorsOptions CreateFindUnitProcessorsOptions()
+ {
+ THROW_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ if (!m_statics)
+ {
+ THROW_HR(APPINSTALLER_CLI_ERROR_PACKAGE_IS_STUB);
+ }
+
+ auto result = m_statics.CreateFindUnitProcessorsOptions();
+ result.as()->SetLifetimeWatcher(CreateLifetimeWatcher());
+ return result;
+ }
+
+ private:
+ // Returns a lifetime watcher object that is currently *unowned*.
+ IUnknown* CreateLifetimeWatcher()
+ {
+ ::Microsoft::WRL::ComPtr factory;
+ THROW_IF_FAILED(::Microsoft::WRL::Module<::Microsoft::WRL::ModuleType::OutOfProc>::GetModule().GetClassObject(CLSID_ConfigurationObjectLifetimeWatcher, IID_PPV_ARGS(&factory)));
+ winrt::com_ptr out;
+ THROW_IF_FAILED(factory->CreateInstance(nullptr, __uuidof(IUnknown), out.put_void()));
+ return out.detach();
+ }
+
+ winrt::Microsoft::Management::Configuration::IConfigurationStatics3 m_statics = nullptr;
+ AppInstaller::ThreadLocalStorage::WingetThreadGlobals m_threadGlobals;
+ };
+
+ // Enable custom code to run before creating any object through the factory.
+ template
+ class ConfigurationFactory : public ::wil::wrl_factory_for_winrt_com_class
+ {
+ public:
+ IFACEMETHODIMP CreateInstance(_In_opt_::IUnknown* unknownOuter, REFIID riid, _COM_Outptr_ void** object) noexcept try
+ {
+ *object = nullptr;
+ RETURN_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::WinGet));
+ RETURN_HR_IF(APPINSTALLER_CLI_ERROR_BLOCKED_BY_POLICY, !::AppInstaller::Settings::GroupPolicies().IsEnabled(::AppInstaller::Settings::TogglePolicy::Policy::Configuration));
+ RETURN_HR_IF(E_ACCESSDENIED, !::AppInstaller::Security::IsCOMCallerSameUserAndIntegrityLevel());
+
+ RETURN_HR_IF(CO_E_CLASS_DISABLED, !s_canBeCreated);
+
+ return ::wil::wrl_factory_for_winrt_com_class::CreateInstance(unknownOuter, riid, object);
+ }
+ CATCH_RETURN()
+ };
+
+#define CoCreatableMicrosoftManagementConfigurationClass(className) \
+ CoCreatableClassWithFactory(className, ::ConfigurationShim::ConfigurationFactory)
+
+ // Disable 6388 as it seems to be falsely warning
+#pragma warning(push)
+#pragma warning(disable : 6388)
+ CoCreatableCppWinRtClass(ConfigurationObjectLifetimeWatcher);
+ CoCreatableMicrosoftManagementConfigurationClass(ConfigurationStaticFunctionsShim);
+#pragma warning(pop)
+}
diff --git a/src/WindowsPackageManager/WindowsPackageManager.vcxproj b/src/WindowsPackageManager/WindowsPackageManager.vcxproj
index f8ab04be8e..ad65971af0 100644
--- a/src/WindowsPackageManager/WindowsPackageManager.vcxproj
+++ b/src/WindowsPackageManager/WindowsPackageManager.vcxproj
@@ -1,6 +1,6 @@
-
+
true
true
@@ -431,15 +431,14 @@
-
+
This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
-
-
+
+
-
-
+
\ No newline at end of file
diff --git a/src/WindowsPackageManager/packages.config b/src/WindowsPackageManager/packages.config
index 3a8e0698a3..132d149574 100644
--- a/src/WindowsPackageManager/packages.config
+++ b/src/WindowsPackageManager/packages.config
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file