Skip to content

Commit

Permalink
Add implementation for EnumDownloads (#158)
Browse files Browse the repository at this point in the history
  • Loading branch information
JeffreySaathoff authored Feb 15, 2023
1 parent 4561954 commit 8df51fc
Show file tree
Hide file tree
Showing 15 changed files with 218 additions and 71 deletions.
2 changes: 1 addition & 1 deletion sdk-cpp/include/do_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

/*
This file exposes apis for helping set an iot_connection_string for the DO agent, so that an application can supply a Microsoft Connected Cache device's hostname
While this file will compile for all platforms, they only serve a purpose for the DeliveryOptimization Agent on linux devices, all other usage will fail and return e_not_impl
While this file will compile for all platforms, they only serve a purpose for the DeliveryOptimization Agent on linux devices, all other usage will fail and return errc::not_impl
*/

#ifdef __cplusplus
Expand Down
12 changes: 10 additions & 2 deletions sdk-cpp/include/do_download.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <chrono>
#include <memory>
#include <string>
#include <vector>

#include "do_download_status.h"
#include "do_download_property.h"
Expand Down Expand Up @@ -48,7 +49,7 @@ class download
static std::error_code download_url_to_path(const std::string& uri, const std::string& downloadFilePath, const std::atomic_bool& isCancelled, std::chrono::seconds timeoutSecs = std::chrono::hours(24)) noexcept;

// Certain properties are not supported on older versions of Windows, resulting in
// msdo::errc::do_e_unknown_property_id from the following methods. See do_download_property.h.
// msdo::errc::unknown_property_id from the following methods. See do_download_property.h.
std::error_code set_property(download_property prop, const download_property_value& value) noexcept;
std::error_code get_property(download_property prop, download_property_value& value) noexcept;

Expand Down Expand Up @@ -82,10 +83,17 @@ class download
return set_property(download_property::cost_policy, static_cast<uint32_t>(value));
}

// Returns existing downloads
static std::error_code get_downloads(std::vector<std::unique_ptr<download>>& out) noexcept;

// Returns existing downloads, filtered by download_property::id, uri, catalog_id, caller_name or download_file_path
static std::error_code get_downloads(download_property prop, const std::string& value, std::vector<std::unique_ptr<download>>& out) noexcept;
static std::error_code get_downloads(download_property prop, const std::wstring& value, std::vector<std::unique_ptr<download>>& out) noexcept;

private:
download();

std::shared_ptr<details::IDownload> _download;
std::unique_ptr<details::IDownload> _download;
};

} // namespace deliveryoptimization
Expand Down
23 changes: 12 additions & 11 deletions sdk-cpp/include/do_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,20 @@ namespace microsoft
{
namespace deliveryoptimization
{

enum class errc : int32_t
namespace errc
{
e_not_impl = static_cast<int32_t>(0x80004001), // E_NOTIMPL
unexpected = static_cast<int32_t>(0x8000FFFF), // E_UNEXPECTED
invalid_arg = static_cast<int32_t>(0x80070057), // E_INVALIDARG
not_found = static_cast<int32_t>(0x80070490), // E_NOT_SET (ERROR_NOT_FOUND)
no_service = static_cast<int32_t>(0x80D01001), // DO_E_NO_SERVICE
download_no_progress = static_cast<int32_t>(0x80D02002), // DO_E_DOWNLOAD_NO_PROGRESS
do_e_unknown_property_id = static_cast<int32_t>(0x80D02011), // DO_E_UNKNOWN_PROPERTY_ID
do_e_invalid_state = static_cast<int32_t>(0x80D02013), // DO_E_INVALID_STATE
};

constexpr auto not_impl = static_cast<int32_t>(0x80004001); // E_NOTIMPL
constexpr auto unexpected = static_cast<int32_t>(0x8000FFFF); // E_UNEXPECTED
constexpr auto invalid_arg = static_cast<int32_t>(0x80070057); // E_INVALIDARG
constexpr auto not_found = static_cast<int32_t>(0x80070490); // E_NOT_SET (ERROR_NOT_FOUND)
constexpr auto no_service = static_cast<int32_t>(0x80D01001); // DO_E_NO_SERVICE
constexpr auto download_no_progress = static_cast<int32_t>(0x80D02002); // DO_E_DOWNLOAD_NO_PROGRESS
constexpr auto no_downloads = static_cast<int32_t>(0x80D02005); // DO_E_NO_DOWNLOADS
constexpr auto unknown_property_id = static_cast<int32_t>(0x80D02011); // DO_E_UNKNOWN_PROPERTY_ID
constexpr auto invalid_state = static_cast<int32_t>(0x80D02013); // DO_E_INVALID_STATE

} //namespace errc
} //namespace deliveryoptimization
} //namespace microsoft

Expand Down
47 changes: 44 additions & 3 deletions sdk-cpp/src/do_download.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace deliveryoptimization

download::download()
{
_download = std::make_shared<msdod::CDownloadImpl>();
_download = std::make_unique<msdod::CDownloadImpl>();
}

download::~download() = default;
Expand All @@ -36,7 +36,6 @@ std::error_code download::make(const std::string& uri, const std::string& downlo
{
out.reset();
std::unique_ptr<download> tmp(new download());
tmp->_download = std::make_shared<msdod::CDownloadImpl>();
DO_RETURN_IF_FAILED(tmp->_download->Init(uri, downloadFilePath));
out = std::move(tmp);
return DO_OK;
Expand Down Expand Up @@ -166,7 +165,7 @@ static std::error_code g_TryOverrideDownlevelOsSetPropertyError(download_propert
{
// Temporary backward-compatibility for MSEdge.
// These properties were not supported in IDODownload interface until build 19041.
if ((ec.value() == static_cast<int>(errc::do_e_unknown_property_id)) &&
if ((ec.value() == errc::unknown_property_id) &&
((prop == download_property::correlation_vector) || (prop == download_property::integrity_check_info)))
{
return DO_OK;
Expand All @@ -188,5 +187,47 @@ std::error_code download::get_property(download_property prop, download_property
return _download->GetProperty(prop, val);
}

std::error_code download::get_downloads(std::vector<std::unique_ptr<download>>& out) noexcept
{
out.clear();
std::vector<std::unique_ptr<details::IDownload>> results;
DO_RETURN_IF_FAILED(msdod::CDownloadImpl::EnumDownloads(results));
for (auto& result : results)
{
std::unique_ptr<download> tmp(new download());
tmp->_download = std::move(result);
out.push_back(std::move(tmp));
}
return DO_OK;
}

std::error_code download::get_downloads(download_property prop, const std::string& value, std::vector<std::unique_ptr<download>>& out) noexcept
{
out.clear();
std::vector<std::unique_ptr<details::IDownload>> results;
DO_RETURN_IF_FAILED(msdod::CDownloadImpl::EnumDownloads(prop, value, results));
for (auto& result : results)
{
std::unique_ptr<download> tmp(new download());
tmp->_download = std::move(result);
out.push_back(std::move(tmp));
}
return DO_OK;
}

std::error_code download::get_downloads(download_property prop, const std::wstring& value, std::vector<std::unique_ptr<download>>& out) noexcept
{
out.clear();
std::vector<std::unique_ptr<details::IDownload>> results;
DO_RETURN_IF_FAILED(msdod::CDownloadImpl::EnumDownloads(prop, value, results));
for (auto& result : results)
{
std::unique_ptr<download> tmp(new download());
tmp->_download = std::move(result);
out.push_back(std::move(tmp));
}
return DO_OK;
}

} // namespace deliveryoptimization
} // namespace microsoft
2 changes: 1 addition & 1 deletion sdk-cpp/src/internal/com/do_config_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace msdo = microsoft::deliveryoptimization;

int internal_set_iot_connection_string(const char* value)
{
return static_cast<int>(msdo::errc::e_not_impl);
return msdo::errc::not_impl;
}

char* internal_get_components_version()
Expand Down
4 changes: 2 additions & 2 deletions sdk-cpp/src/internal/com/do_download_property_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace deliveryoptimization
namespace details
{

static std::error_code UTF8toWstr(const std::string& str, std::wstring& wstr)
std::error_code UTF8toWstr(const std::string& str, std::wstring& wstr)
{
wstr.clear();
size_t cch = str.size();
Expand All @@ -33,7 +33,7 @@ static std::error_code UTF8toWstr(const std::string& str, std::wstring& wstr)
return DO_OK;
}

static std::error_code WstrToUTF8(const std::wstring& wstr, std::string& str)
std::error_code WstrToUTF8(const std::wstring& wstr, std::string& str)
{
str.clear();
size_t cch = wstr.size();
Expand Down
68 changes: 67 additions & 1 deletion sdk-cpp/src/internal/com/download_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ std::error_code CDownloadImpl::Init(const std::string& uri, const std::string& d
ComPtr<IDODownload> spDownload;
RETURN_IF_FAILED(manager->CreateDownload(&spDownload));

RETURN_IF_FAILED(CoSetProxyBlanket(static_cast<IUnknown*>(spDownload.Get()), RPC_C_AUTHN_DEFAULT,
RETURN_IF_FAILED(CoSetProxyBlanket(spDownload.Get(), RPC_C_AUTHN_DEFAULT,
RPC_C_AUTHZ_NONE, COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr, EOAC_STATIC_CLOAKING));

Expand Down Expand Up @@ -295,6 +295,72 @@ std::error_code CDownloadImpl::SetRanges(const download_range* ranges, size_t co
return DO_OK;
}

std::error_code CDownloadImpl::EnumDownloads(std::vector<std::unique_ptr<IDownload>>& out) noexcept
{
out.clear();
return _EnumDownloads(nullptr, out);
}

std::error_code CDownloadImpl::EnumDownloads(download_property prop, const std::string& value, std::vector<std::unique_ptr<IDownload>>& out) noexcept
{
out.clear();
std::wstring wval;
DO_RETURN_IF_FAILED(UTF8toWstr(value, wval));
return EnumDownloads(prop, wval, out);
}

std::error_code CDownloadImpl::EnumDownloads(download_property prop, const std::wstring& value, std::vector<std::unique_ptr<IDownload>>& out) noexcept
{
out.clear();
DO_DOWNLOAD_ENUM_CATEGORY category;
DO_RETURN_IF_FAILED(ConvertToComProperty(prop, category.Property));
category.Value = value.c_str();
return _EnumDownloads(&category, out);
}

std::error_code CDownloadImpl::_EnumDownloads(const DO_DOWNLOAD_ENUM_CATEGORY* pCategory, std::vector<std::unique_ptr<IDownload>>& out) noexcept
{
out.clear();
ComPtr<IDOManager> manager;
RETURN_IF_FAILED(CoCreateInstance(__uuidof(DeliveryOptimization), nullptr, CLSCTX_LOCAL_SERVER, IID_PPV_ARGS(&manager)));
ComPtr<IEnumUnknown> spEnum;
RETURN_IF_FAILED(manager->EnumDownloads(pCategory, &spEnum));

std::vector<std::unique_ptr<IDownload>> results;
ULONG cFetched = 0;
do
{
ComPtr<IUnknown> spunk;
RETURN_IF_FAILED(spEnum->Next(1, &spunk, &cFetched));
if (cFetched == 1)
{
ComPtr<IDODownload> spDownload;
RETURN_IF_FAILED(spunk->QueryInterface(IID_PPV_ARGS(&spDownload)));

RETURN_IF_FAILED(CoSetProxyBlanket(spDownload.Get(), RPC_C_AUTHN_DEFAULT,
RPC_C_AUTHZ_NONE, COLE_DEFAULT_PRINCIPAL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
nullptr, EOAC_STATIC_CLOAKING));

auto tmp = std::make_unique<CDownloadImpl>();
tmp->_spDownload = std::move(spDownload);

// Assume full file in created state, else leave ranges null
msdo::download_status status;
DO_RETURN_IF_FAILED(tmp->GetStatus(status));
if (status.state() == msdo::download_state::created)
{
tmp->_spRanges = std::make_unique<DO_DOWNLOAD_RANGES_INFO>();
tmp->_spRanges->RangeCount = 0; // empty == full file
}

results.push_back(std::move(tmp));
}
} while (cFetched > 0);

out = std::move(results);
return DO_OK;
}

} // namespace details
} // namespace deliveryoptimization
} // namespace microsoft
3 changes: 3 additions & 0 deletions sdk-cpp/src/internal/do_download_property_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ namespace details
{

#if defined(DO_INTERFACE_COM)
std::error_code UTF8toWstr(const std::string& str, std::wstring& wstr);
std::error_code WstrToUTF8(const std::wstring& wstr, std::string& str);

struct unique_variant : VARIANT
{
unique_variant();
Expand Down
21 changes: 1 addition & 20 deletions sdk-cpp/src/internal/do_error_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,19 +52,10 @@ inline std::error_code make_error_code(int32_t e)
return std::error_code(e, do_category());
}

inline std::error_code make_error_code(errc e)
{
return std::error_code(static_cast<int32_t>(e), do_category());
}

#ifndef FAILED
#define FAILED(hr) (((int32_t)(hr)) < 0)
#endif

#ifndef RETURN_IF_FAILED
#define RETURN_IF_FAILED(hr) { \
int32_t __hr = (hr); \
if (FAILED(__hr)) return std::error_code(__hr, do_category()); }
if (__hr < 0) return std::error_code(__hr, do_category()); }
#endif

#ifdef DO_ENABLE_EXCEPTIONS
Expand All @@ -83,11 +74,6 @@ class exception : public std::exception
{
}

exception(errc code) :
exception(std::error_code(static_cast<int32_t>(code), do_category()))
{
}

const char* what() const noexcept override
{
return _msg.c_str();
Expand Down Expand Up @@ -128,11 +114,6 @@ inline void ThrowException(int32_t errorCode)
throw exception(errorCode);
}

inline void ThrowException(errc errorCode)
{
throw exception(errorCode);
}

#endif // DO_ENABLE_EXCEPTIONS

} // namespace details
Expand Down
8 changes: 8 additions & 0 deletions sdk-cpp/src/internal/download_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#ifndef _DELIVERY_OPTIMIZATION_DOWNLOAD_IMPL_H
#define _DELIVERY_OPTIMIZATION_DOWNLOAD_IMPL_H

#include <vector>

#include "download_interface.h"

#if defined(DO_INTERFACE_COM)
Expand Down Expand Up @@ -39,8 +41,14 @@ class CDownloadImpl : public IDownload
std::error_code SetProperty(download_property key, const download_property_value& val) noexcept override;
std::error_code SetRanges(const download_range* ranges, size_t count) noexcept override;

static std::error_code EnumDownloads(std::vector<std::unique_ptr<IDownload>>& out) noexcept;
static std::error_code EnumDownloads(download_property prop, const std::string& value, std::vector<std::unique_ptr<IDownload>>& out) noexcept;
static std::error_code EnumDownloads(download_property prop, const std::wstring& value, std::vector<std::unique_ptr<IDownload>>& out) noexcept;

private:
#if defined(DO_INTERFACE_COM)
static std::error_code CDownloadImpl::_EnumDownloads(const DO_DOWNLOAD_ENUM_CATEGORY* pCategory, std::vector<std::unique_ptr<IDownload>>& out) noexcept;

Microsoft::WRL::ComPtr<IDODownload> _spDownload;
std::unique_ptr<DO_DOWNLOAD_RANGES_INFO> _spRanges;
#elif defined(DO_INTERFACE_REST)
Expand Down
4 changes: 2 additions & 2 deletions sdk-cpp/src/internal/rest/do_config_internal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "do_persistence.h"
#include "do_version.h"
#elif defined(DO_CLIENT_DOSVC)
#include "do_errors.h" // msdo::errc::e_not_impl
#include "do_errors.h" // msdo::errc::not_impl
#endif

namespace msdo = microsoft::deliveryoptimization;
Expand Down Expand Up @@ -190,7 +190,7 @@ void internal_free_version_buf(char** ppBuffer)

int internal_set_iot_connection_string(const char* value)
{
return static_cast<int>(msdo::errc::e_not_impl);
return msdo::errc::not_impl;
}

char* internal_get_components_version()
Expand Down
Loading

0 comments on commit 8df51fc

Please sign in to comment.