// WinHttpCreateProxyResolver is not declared in WinHttp.h when using the GDK.
WINHTTPAPI DWORD WINAPI WinHttpCreateProxyResolver(HINTERNET hSession, HINTERNET* phResolver);
std::string ResolveXboxProxy()
{
HINTERNET session = WinHttpOpen(
L"CustomHttp/1.0",
WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
WINHTTP_FLAG_ASYNC);
if (!session)
return {};
struct ProxyContext
{
HANDLE event;
DWORD error;
};
ProxyContext ctx{ CreateEventW(nullptr, TRUE, FALSE, nullptr), ERROR_SUCCESS };
WinHttpSetStatusCallback(session,
[](HINTERNET, DWORD_PTR context, DWORD status, LPVOID info, DWORD)
{
auto* c = reinterpret_cast<ProxyContext*>(context);
if (status == WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE)
{
c->error = ERROR_SUCCESS;
SetEvent(c->event);
}
else if (status == WINHTTP_CALLBACK_STATUS_REQUEST_ERROR)
{
c->error = reinterpret_cast<WINHTTP_ASYNC_RESULT*>(info)->dwError;
SetEvent(c->event);
}
},
WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS,
0);
HINTERNET resolver = nullptr;
if (WinHttpCreateProxyResolver(session, &resolver) != ERROR_SUCCESS)
{
CloseHandle(ctx.event);
WinHttpCloseHandle(session);
return {};
}
DWORD result = WinHttpGetProxySettingsEx(
resolver,
WinHttpProxySettingsTypeXBox,
nullptr,
reinterpret_cast<DWORD_PTR>(&ctx));
if (result == ERROR_IO_PENDING)
{
// Wait for the async callback to fire (5-second timeout).
WaitForSingleObject(ctx.event, 5000);
result = ctx.error;
}
std::string proxyAddress;
if (result == ERROR_SUCCESS)
{
WINHTTP_PROXY_SETTINGS_EX proxySettings{};
if (WinHttpGetProxySettingsResultEx(resolver, &proxySettings) == ERROR_SUCCESS)
{
PCWSTR proxy =
proxySettings.pcwszSecureProxy != nullptr
? proxySettings.pcwszSecureProxy
: proxySettings.pcwszProxy;
if (proxy != nullptr)
{
// Example function for conversion.
proxyAddress = Utf16ToUtf8(std::wstring(proxy));
}
WinHttpFreeProxySettingsEx(WinHttpProxySettingsTypeXBox, &proxySettings);
}
}
CloseHandle(ctx.event);
WinHttpCloseHandle(resolver);
WinHttpCloseHandle(session);
return proxyAddress;
}
std::string proxyAddress = ResolveXboxProxy();
if (!proxyAddress.empty())
{
curl_easy_setopt(curlHandle, CURLOPT_PROXY, proxyAddress.c_str());
}