#include #include #include #include #include #include "PrintFunctions.h" #include "HttpClient.h" BOOL HttpsDownloadFullFile(LPCWSTR domain, LPCWSTR uri, PBYTE* output, SIZE_T* output_size) { ///wprintf_or_not(L"Downloading https://%s%s...\n", domain, uri); // Get proxy configuration WINHTTP_CURRENT_USER_IE_PROXY_CONFIG proxyConfig; WinHttpGetIEProxyConfigForCurrentUser(&proxyConfig); BOOL proxySet = !(proxyConfig.fAutoDetect || proxyConfig.lpszAutoConfigUrl != NULL); DWORD proxyAccessType = proxySet ? ((proxyConfig.lpszProxy == NULL) ? WINHTTP_ACCESS_TYPE_NO_PROXY : WINHTTP_ACCESS_TYPE_NAMED_PROXY) : WINHTTP_ACCESS_TYPE_NO_PROXY; LPCWSTR proxyName = proxySet ? proxyConfig.lpszProxy : WINHTTP_NO_PROXY_NAME; LPCWSTR proxyBypass = proxySet ? proxyConfig.lpszProxyBypass : WINHTTP_NO_PROXY_BYPASS; // Initialize HTTP session and request HINTERNET hSession = WinHttpOpen(L"WinHTTP/1.0", proxyAccessType, proxyName, proxyBypass, 0); if (hSession == NULL) { printf_or_not("WinHttpOpen failed with error : 0x%x\n", GetLastError()); return FALSE; } HINTERNET hConnect = WinHttpConnect(hSession, domain, INTERNET_DEFAULT_HTTPS_PORT, 0); if (!hConnect) { printf_or_not("WinHttpConnect failed with error : 0x%x\n", GetLastError()); return FALSE; } HINTERNET hRequest = WinHttpOpenRequest(hConnect, L"GET", uri, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); if (!hRequest) { return FALSE; } // Configure proxy manually if (!proxySet) { WINHTTP_AUTOPROXY_OPTIONS autoProxyOptions; autoProxyOptions.dwFlags = proxyConfig.lpszAutoConfigUrl != NULL ? WINHTTP_AUTOPROXY_CONFIG_URL : WINHTTP_AUTOPROXY_AUTO_DETECT; autoProxyOptions.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A; autoProxyOptions.fAutoLogonIfChallenged = TRUE; if (proxyConfig.lpszAutoConfigUrl != NULL) autoProxyOptions.lpszAutoConfigUrl = proxyConfig.lpszAutoConfigUrl; WCHAR szUrl[MAX_PATH] = { 0 }; swprintf_s(szUrl, _countof(szUrl), L"https://%ws%ws", domain, uri); WINHTTP_PROXY_INFO proxyInfo; WinHttpGetProxyForUrl( hSession, szUrl, &autoProxyOptions, &proxyInfo); WinHttpSetOption(hRequest, WINHTTP_OPTION_PROXY, &proxyInfo, sizeof(proxyInfo)); DWORD logonPolicy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW; WinHttpSetOption(hRequest, WINHTTP_OPTION_AUTOLOGON_POLICY, &logonPolicy, sizeof(logonPolicy)); } // Perform request BOOL bRequestSent; do { bRequestSent = WinHttpSendRequest(hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); } while (!bRequestSent && GetLastError() == ERROR_WINHTTP_RESEND_REQUEST); if (!bRequestSent) { return FALSE; } BOOL bResponseReceived = WinHttpReceiveResponse(hRequest, NULL); if (!bResponseReceived) { return FALSE; } // Read response DWORD dwAvailableSize = 0; DWORD dwDownloadedSize = 0; SIZE_T allocatedSize = 4096; if (!WinHttpQueryDataAvailable(hRequest, &dwAvailableSize)) { return FALSE; } *output = (PBYTE) malloc(allocatedSize); *output_size = 0; while (dwAvailableSize) { while (*output_size + dwAvailableSize > allocatedSize) { allocatedSize *= 2; PBYTE new_output = (PBYTE)realloc(*output, allocatedSize); if (new_output == NULL) { return FALSE; } *output = new_output; } if (!WinHttpReadData(hRequest, *output + *output_size, dwAvailableSize, &dwDownloadedSize)) { return FALSE; } *output_size += dwDownloadedSize; WinHttpQueryDataAvailable(hRequest, &dwAvailableSize); } PBYTE new_output = (PBYTE)realloc(*output, *output_size); if (new_output == NULL) { return FALSE; } *output = new_output; WinHttpCloseHandle(hRequest); WinHttpCloseHandle(hConnect); WinHttpCloseHandle(hSession); return TRUE; }