using System; using System.Linq; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; using Vanara.InteropServices; namespace Vanara.PInvoke; /// Items from the WinHTTP.dll. public static partial class WinHTTP { /// Represents an application-defined proxy change callback function. /// /// Type: _In_ ULONGLONG /// The flag passed to the WinHttpRegisterProxyChangeNotification function (for example, WINHTTP_PROXY_NOTIFY_CHANGE). /// /// /// Type: _In_ PVOID /// The context object pointer passed to the WinHttpRegisterProxyChangeNotification function. /// /// None // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nc-winhttp-winhttp_proxy_change_callback WINHTTP_PROXY_CHANGE_CALLBACK // WinhttpProxyChangeCallback; void WinhttpProxyChangeCallback( ULONGLONG ullFlags, PVOID pvContext ) {...} [PInvokeData("winhttp.h", MSDNShortId = "NC:winhttp.WINHTTP_PROXY_CHANGE_CALLBACK")] [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] public delegate void WINHTTP_PROXY_CHANGE_CALLBACK(ulong ullFlags, IntPtr pvContext); /// Frees the data retrieved from a previous call to WinHttpGetProxySettingsResultEx. /// /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE /// A proxy settings type. /// /// /// Type: _In_ PVOID /// A pointer to a WINHTTP_PROXY_SETTINGS_EX structure that was retrieved from a previous call to WinHttpGetProxySettingsResultEx. /// /// This function does not return a value. // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpfreeproxysettingsex WINHTTPAPI DWORD // WinHttpFreeProxySettingsEx( WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PVOID pProxySettingsEx ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpFreeProxySettingsEx")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpFreeProxySettingsEx(WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, IntPtr pProxySettingsEx); /// Retrieves extended proxy settings. /// /// Type: _In_ HINTERNET /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. /// /// /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE /// A proxy settings type. /// /// /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM /// An optional pointer to a WINHTTP_PROXY_SETTINGS_PARAM. /// /// /// Type: _In_opt_ DWORD_PTR /// An optional pointer to a DWORD containing context data that will be passed to the completion callback function. /// /// /// /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). /// /// /// /// Code /// Description /// /// /// ERROR_IO_PENDING /// The operation is continuing asynchronously. /// /// /// // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsex WINHTTPAPI DWORD // WinHttpGetProxySettingsEx( HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PWINHTTP_PROXY_SETTINGS_PARAM // pProxySettingsParam, DWORD_PTR pContext ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsEx")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, in WINHTTP_PROXY_SETTINGS_PARAM pProxySettingsParam, IntPtr pContext); /// Retrieves extended proxy settings. /// /// Type: _In_ HINTERNET /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. /// /// /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE /// A proxy settings type. /// /// /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM /// An optional pointer to a WINHTTP_PROXY_SETTINGS_PARAM. /// /// /// Type: _In_opt_ DWORD_PTR /// An optional pointer to a DWORD containing context data that will be passed to the completion callback function. /// /// /// /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). /// /// /// /// Code /// Description /// /// /// ERROR_IO_PENDING /// The operation is continuing asynchronously. /// /// /// // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsex WINHTTPAPI DWORD // WinHttpGetProxySettingsEx( HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PWINHTTP_PROXY_SETTINGS_PARAM // pProxySettingsParam, DWORD_PTR pContext ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsEx")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, [In, Optional] IntPtr pProxySettingsParam, IntPtr pContext); /// Retrieves the results of a call to WinHttpGetProxySettingsEx. /// /// Type: _In_ HINTERNET /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. /// /// /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE /// A proxy settings type. /// /// /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM /// An optional WINHTTP_PROXY_SETTINGS_PARAM. /// /// A WINHTTP_PROXY_SETTINGS_EX structure. // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsresultex WINHTTPAPI DWORD // WinHttpGetProxySettingsResultEx( HINTERNET hResolver, PVOID pProxySettingsEx ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsResultEx")] public static Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, WINHTTP_PROXY_SETTINGS_PARAM? pProxySettingsParam, out WINHTTP_PROXY_SETTINGS_EX_MGD pProxySettingsEx) { pProxySettingsEx = default; using var pParam = pProxySettingsParam.HasValue ? new SafeCoTaskMemStruct(pProxySettingsParam.Value) : SafeCoTaskMemStruct.Null; var ret = WinHttpGetProxySettingsEx(hResolver, ProxySettingsType, pParam, default); if (ret.Failed) return ret; IntPtr ptr = default; ret = WinHttpGetProxySettingsResultEx(hResolver, ptr); if (ret.Failed) return ret; pProxySettingsEx = ptr.ToStructure(); WinHttpFreeProxySettingsEx(ProxySettingsType, ptr); return ret; } /// Retrieves the results of a call to WinHttpGetProxySettingsEx. /// /// Type: _In_ HINTERNET /// The resolver handle used to issue a previously completed call to WinHttpGetProxySettingsEx. /// /// /// A pointer to a WINHTTP_PROXY_SETTINGS_EX structure. The memory occupied by the structure is allocated by /// WinHttpGetProxySettingsResultEx, so you need to free that memory by passing this pointer to WinHttpFreeProxySettingsEx. /// // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsresultex // WINHTTPAPI DWORD WinHttpGetProxySettingsResultEx( HINTERNET hResolver, PVOID pProxySettingsEx ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsResultEx")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpGetProxySettingsResultEx(HINTERNET hResolver, IntPtr pProxySettingsEx); /// The WinHttpQueryOption function queries an Internet option on the specified handle. /// /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying a /// particular option. /// /// /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. /// /// /// A pointer to a buffer that receives the option setting. Strings returned by the WinHttpQueryOption function are globally /// allocated, so the calling application must globally free the string when it finishes using it. Setting this parameter to NULL /// causes this function to return FALSE. Calling GetLastError then returns ERROR_INSUFFICIENT_BUFFER and lpdwBufferLength /// contains the number of bytes required to hold the requested information. /// /// /// A pointer to an unsigned long integer variable that contains the length of lpBuffer, in bytes. When the function returns, the /// variable receives the length of the data placed into lpBuffer. If GetLastError returns ERROR_INSUFFICIENT_BUFFER, this /// parameter receives the number of bytes required to hold the requested information. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. To get a specific error message, call GetLastError. Among the error /// codes returned are the following: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_INVALID_OPTION /// An invalid option value was specified. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// /// GetLastError returns the ERROR_INVALID_PARAMETER if an option flag that is invalid for the specified handle type is passed to the /// dwOption parameter. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// This example demonstrates retrieving the connection time-out value: /// /// DWORD data; DWORD dwSize = sizeof(DWORD); // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpQueryOption to retrieve internet options. if (WinHttpQueryOption( hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &data, &dwSize)) { printf("Connection timeout: %u ms\n\n",data); } else { printf( "Error %u in WinHttpQueryOption.\n", GetLastError()); } // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [Out, Optional] IntPtr lpBuffer, ref uint lpdwBufferLength); /// The WinHttpQueryOption function queries an Internet option on the specified handle. /// The type of the option. /// /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying a /// particular option. /// /// /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. /// /// The option setting. /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] public static T WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption) { Type rType = CorrespondingTypeAttribute.GetCorrespondingTypes(dwOption, CorrespondingAction.Get).FirstOrDefault() ?? typeof(T); if (typeof(T) != typeof(object)) { rType = typeof(T); } uint sz = 0; WinHttpQueryOption(hInternet, dwOption, default, ref sz); Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); using SafeHGlobalHandle buffer = new(sz); Win32Error.ThrowLastErrorIfFalse(WinHttpQueryOption(hInternet, dwOption, buffer, ref sz)); return (T)buffer.DangerousGetHandle().Convert(sz, rType, CharSet.Unicode); } /// Also see WinHttpReadDataEx. /// /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable must /// have been called for this handle and must have completed before WinHttpReadData is called. Although calling /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing so /// requires that the application use a fixed-length buffer for reading. /// /// /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. /// /// Unsigned long integer value that contains the number of bytes to read. /// /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to zero /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the /// information in the callback function; not doing so can cause a memory fault. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table /// identifies the error codes that are returned. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to /// the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking /// information before giving the data to the application. /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call /// GetLastError to get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// completion to determine whether this function was successful and the value of the parameters. The /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. /// /// /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL and /// retrieve the bytes read in the callback function; otherwise, a memory fault can occur. /// /// /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// completion triggers another call to WinHttpReadData, the situation can result in a stack overflow. In general, it is best to /// use a read buffer that is comparable in size, or larger than the internal read buffer used by WinHTTP, which is 8 KB. /// /// /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, the /// transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a local /// file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the /// dwStatusInformationLength parameter set to zero when the end of a response is found. /// /// /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the /// response. If sufficient data has not arrived from the server, the buffer is not filled. /// /// /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse /// must be made on the handle before WinHttpReadData can be used. /// /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. /// /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow can /// result. It is best to use a read buffer that is 8 Kilobytes or larger in size. /// /// /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML encoded /// directory entries, it must be large enough to hold at least one complete entry. /// /// /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications that /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for /// available data: /// /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED /// /// /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer Protocol /// (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS server, then /// opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much /// data is available for download, then WinHttpReadData is used to read that data. This process repeats until the entire document /// has been retrieved and displayed. /// /// /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET hRequest, // [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, out uint lpdwNumberOfBytesRead); /// Also see WinHttpReadDataEx. /// /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable must /// have been called for this handle and must have completed before WinHttpReadData is called. Although calling /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing so /// requires that the application use a fixed-length buffer for reading. /// /// /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. /// /// Unsigned long integer value that contains the number of bytes to read. /// /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to zero /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the /// information in the callback function; not doing so can cause a memory fault. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table /// identifies the error codes that are returned. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to /// the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking /// information before giving the data to the application. /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call /// GetLastError to get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// completion to determine whether this function was successful and the value of the parameters. The /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. /// /// /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL and /// retrieve the bytes read in the callback function; otherwise, a memory fault can occur. /// /// /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// completion triggers another call to WinHttpReadData, the situation can result in a stack overflow. In general, it is best to /// use a read buffer that is comparable in size, or larger than the internal read buffer used by WinHTTP, which is 8 KB. /// /// /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, the /// transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a local /// file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the /// dwStatusInformationLength parameter set to zero when the end of a response is found. /// /// /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the /// response. If sufficient data has not arrived from the server, the buffer is not filled. /// /// /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse /// must be made on the handle before WinHttpReadData can be used. /// /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. /// /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow can /// result. It is best to use a read buffer that is 8 Kilobytes or larger in size. /// /// /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML encoded /// directory entries, it must be large enough to hold at least one complete entry. /// /// /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications that /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for /// available data: /// /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED /// /// /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE /// /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer Protocol /// (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS server, then /// opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much /// data is available for download, then WinHttpReadData is used to read that data. This process repeats until the entire document /// has been retrieved and displayed. /// /// /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET hRequest, // [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, out int lpdwNumberOfBytesRead); /// Reads data from a handle opened by the WinHttpOpenRequest function. /// /// Type: IN HINTERNET /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. /// /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length buffer /// for reading. /// /// /// /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID /// /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. /// /// /// /// Type: IN DWORD /// Unsigned long integer value that contains the number of bytes to read. /// /// /// Type: OUT LPDWORD /// /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to zero /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the /// information in the callback function; not doing so can cause a memory fault. /// /// /// /// Type: IN ULONGLONG /// /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until the /// provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API equivalent to /// that of WinHttpReadData. /// /// /// /// Type: IN DWORD /// Reserved. Pass 0. /// /// /// Type: _In_reads_bytes_opt_(cbProperty) PVOID /// Reserved. Pass NULL. /// /// /// A status code indicating the result of the operation. Among the error codes returned are the following. /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the function /// won't always completely fill the buffer that you provide). /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( HINTERNET // hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD cbProperty, PVOID // pvProperty ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, out uint lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); /// Reads data from a handle opened by the WinHttpOpenRequest function. /// /// Type: IN HINTERNET /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. /// /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length buffer /// for reading. /// /// /// /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID /// /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. /// /// /// /// Type: IN DWORD /// Unsigned long integer value that contains the number of bytes to read. /// /// /// Type: OUT LPDWORD /// /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to zero /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the /// information in the callback function; not doing so can cause a memory fault. /// /// /// /// Type: IN ULONGLONG /// /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until the /// provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API equivalent to /// that of WinHttpReadData. /// /// /// /// Type: IN DWORD /// Reserved. Pass 0. /// /// /// Type: _In_reads_bytes_opt_(cbProperty) PVOID /// Reserved. Pass NULL. /// /// /// A status code indicating the result of the operation. Among the error codes returned are the following. /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the function /// won't always completely fill the buffer that you provide). /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( HINTERNET // hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD cbProperty, PVOID // pvProperty ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, out int lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); /// /// The WinHttpReceiveResponse function waits to receive the response to an HTTP request initiated by WinHttpSendRequest. When /// WinHttpReceiveResponse completes successfully, the status code and response headers have been received and are available for /// the application to inspect using WinHttpQueryHeaders. An application must call WinHttpReceiveResponse before it can use /// WinHttpQueryDataAvailable and WinHttpReadData to access the response entity body (if any). /// /// /// HINTERNET handle returned by WinHttpOpenRequest and sent by WinHttpSendRequest. Wait until WinHttpSendRequest has completed /// for this handle before calling WinHttpReceiveResponse. /// /// This parameter is reserved and must be NULL. /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are the following. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CANNOT_CONNECT /// Returned if connection to the server failed. /// /// /// ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW /// Returned when an overflow condition is encountered in the course of parsing chunked encoding. /// /// /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED /// Returned when the server requests client authentication. /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// version 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_HEADER_COUNT_EXCEEDED /// Returned when a larger number of headers were present in a response than WinHTTP could receive. /// /// /// ERROR_WINHTTP_HEADER_SIZE_OVERFLOW /// Returned by WinHttpReceiveResponse when the size of headers received exceeds the limit for the request handle. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_INVALID_SERVER_RESPONSE /// The server response could not be parsed. /// /// /// ERROR_WINHTTP_INVALID_URL /// The URL is invalid. /// /// /// ERROR_WINHTTP_LOGIN_FAILURE /// /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new request /// handle must be created before retrying the function that originally produced this error. /// /// /// /// ERROR_WINHTTP_NAME_NOT_RESOLVED /// The server name could not be resolved. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_REDIRECT_FAILED /// The redirection failed because either the scheme changed or all attempts made to redirect failed (default is five attempts). /// /// /// ERROR_WINHTTP_RESEND_REQUEST /// The WinHTTP function failed. The desired function can be retried on the same request handle. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_SECURE_FAILURE /// /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error was /// encountered, check for a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more information, see WINHTTP_STATUS_CALLBACK. /// /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME /// The URL specified a scheme other than "http:" or "https:". /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call /// GetLastError to get extended error information. If this function returns TRUE, the application should expect either the /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE completion callback, indicating success, or the /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion callback, indicating that the operation completed asynchronously, but failed. /// /// /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in receiving the response: /// /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE /// /// /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_REDIRECT /// /// /// /// If the server closes the connection, the following notifications will also be reported, provided that they have been set in the /// dwNotificationFlags parameter of WinHttpSetStatusCallback: /// /// /// /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED /// /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is /// fictitious and must be replaced with the name of a server for which you have write access. /// /// /// LPSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreceiveresponse WINHTTPAPI BOOL WinHttpReceiveResponse( // [in] HINTERNET hRequest, [in] LPVOID lpReserved ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReceiveResponse")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpReceiveResponse(HINTERNET hRequest, [In, Optional] IntPtr lpReserved); /// Registers a callback function that WinHTTP calls when the effective proxy settings change. /// /// Type: _In_ ULONGLONG /// The flag to pass to the callback (for example, WINHTTP_PROXY_NOTIFY_CHANGE). /// /// /// Type: _In_ WINHTTP_PROXY_CHANGE_CALLBACK /// A pointer to the callback function that should be called when the effective proxy settings change. /// /// /// Type: _In_ PVOID /// A pointer to a context object to pass to the callback. /// /// /// Type: _Out_ WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE* /// /// A handle that identifies the registration of the callback function. To unregister, pass this value to /// WinHttpUnregisterProxyChangeNotification. WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE is equivalent to PVOID. /// /// /// /// /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). /// /// /// /// Code /// Description /// /// /// ERROR_SUCCESS /// The operation succeeded. /// /// /// // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpregisterproxychangenotification WINHTTPAPI DWORD // WinHttpRegisterProxyChangeNotification( ULONGLONG ullFlags, WINHTTP_PROXY_CHANGE_CALLBACK pfnCallback, PVOID pvContext, // WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE *hRegistration ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpRegisterProxyChangeNotification")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpRegisterProxyChangeNotification(ulong ullFlags, WINHTTP_PROXY_CHANGE_CALLBACK pfnCallback, IntPtr pvContext, ref WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration); /// The WinHttpResetAutoProxy function resets the auto-proxy. /// A valid HINTERNET WinHTTP session handle returned by a previous call to the WinHttpOpen function. /// /// A set of flags that affects the reset operation. /// The following flags are supported as defined in the Winhttp.h header file. /// /// /// Value /// Meaning /// /// /// WINHTTP_RESET_STATE 0x00000001 /// Forces a flush and retry of non-persistent proxy information on the current network. /// /// /// WINHTTP_RESET_SWPAD_CURRENT_NETWORK 0x00000002 /// Flush the PAD information for the current network. /// /// /// WINHTTP_RESET_SWPAD_ALL 0x00000004 /// Flush the PAD information for all networks. /// /// /// WINHTTP_RESET_SCRIPT_CACHE 0x00000008 /// Flush the persistent HTTP cache of proxy scripts. /// /// /// WINHTTP_RESET_ALL 0x0000FFFF /// Forces a flush and retry of all proxy information on the current network. /// /// /// WINHTTP_RESET_NOTIFY_NETWORK_CHANGED 0x00010000 /// Flush the current proxy information and notify that the network changed. /// /// /// WINHTTP_RESET_OUT_OF_PROC 0x00020000 /// /// Act on the autoproxy service instead of the current process. Applications that use the WinHttpGetProxyForUrl function to purge /// in-process caching should close the hInternet handle and open a new handle for future calls. /// /// /// /// /// /// A code indicating the success or failure of the operation. /// /// /// Return code /// Description /// /// /// ERROR_SUCCESS /// The operation was successful. /// /// /// ERROR_INVALID_HANDLE /// The hSession parameter is not a valid handle. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE TYPE /// The hSession parameter is not the product of a call to WinHttpOpen. /// /// /// /// /// To reset everything, set the dwFlags parameter to include WINHTTP_RESET_ALL and WINHTTP_RESET_OUT_OF_PROC. /// /// Note If you make subsequent calls to the WinHttpResetAutoProxy function, there must be at least 30 seconds delay /// between calls to reset the state of the auto-proxy. If there is less than 30 seconds, the WinHttpResetAutoProxy function call /// may return ERROR_SUCCESS but the reset won't happen. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpresetautoproxy WINHTTPAPI DWORD WinHttpResetAutoProxy( // [in] HINTERNET hSession, [in] DWORD dwFlags ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpResetAutoProxy")] public static extern Win32Error WinHttpResetAutoProxy(HINTERNET hSession, WINHTTP_RESET dwFlags); /// The WinHttpSendRequest function sends the specified request to the HTTP server. /// An HINTERNET handle returned by WinHttpOpenRequest. /// /// A pointer to a string that contains the additional headers to append to the request. This parameter can be /// WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to append. /// /// /// An unsigned long integer value that contains the length, in characters, of the additional headers. If this parameter is -1L /// and pwszHeaders is not NULL, this function assumes that pwszHeaders is null-terminated, and the length is calculated. /// /// /// /// A pointer to a buffer that contains any optional data to send immediately after the request headers. This parameter is generally used /// for POST and PUT operations. The optional data can be the resource or data posted to the server. This parameter can be /// WINHTTP_NO_REQUEST_DATA if there is no optional data to send. /// /// If the dwOptionalLength parameter is 0, this parameter is ignored and set to NULL. /// This buffer must remain available until the request handle is closed or the call to WinHttpReceiveResponse has completed. /// /// /// /// An unsigned long integer value that contains the length, in bytes, of the optional data. This parameter can be zero if there is no /// optional data to send. /// /// /// This parameter must contain a valid length when the lpOptional parameter is not NULL. Otherwise, lpOptional is /// ignored and set to NULL. /// /// /// /// /// An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the /// Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, /// then WinHttpWriteData can be used to send additional data. /// /// /// dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs /// to be changed, the caller should create a new request. /// /// /// /// A pointer to a pointer-sized variable that contains an application-defined value that is passed, with the request handle, to any /// callback functions. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Error codes are /// listed in the following table. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CANNOT_CONNECT /// Returned if connection to the server failed. /// /// /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED /// /// The secure HTTP server requires a client certificate. The application retrieves the list of certificate issuers by calling /// WinHttpQueryOption with the WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST option. If the server requests the client certificate, but /// does not require it, the application can alternately call WinHttpSetOption with the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. /// In this case, the application specifies the WINHTTP_NO_CLIENT_CERT_CONTEXT macro in the lpBuffer parameter of /// WinHttpSetOption. For more information, see the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. Windows Server 2003 with /// SP1, Windows XP with SP2 and Windows 2000: This error is not supported. /// /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// version 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_INVALID_URL /// The URL is invalid. /// /// /// ERROR_WINHTTP_LOGIN_FAILURE /// /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new request /// handle must be created before retrying the function that originally produced this error. /// /// /// /// ERROR_WINHTTP_NAME_NOT_RESOLVED /// The server name cannot be resolved. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW /// Returned when an incoming response exceeds an internal WinHTTP size limit. /// /// /// ERROR_WINHTTP_SECURE_FAILURE /// /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error was /// encountered, verify through a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more /// information, see WINHTTP_STATUS_CALLBACK. /// /// /// /// ERROR_WINHTTP_SHUTDOWN /// The WinHTTP function support is shut down or unloaded. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request timed out. /// /// /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME /// The URL specified a scheme other than "http:" or "https:". /// /// /// ERROR_NOT_ENOUGH_MEMORY /// /// Not enough memory was available to complete the requested operation. (Windows error code) Windows Server 2003, Windows XP and /// Windows 2000: The TCP reservation range set with the WINHTTP_OPTION_PORT_RESERVATION option is not large enough to send /// this request. /// /// /// /// ERROR_INVALID_PARAMETER /// /// The content length specified in the dwTotalLength parameter does not match the length specified in the Content-Length header. /// The lpOptional parameter must be NULL and the dwOptionalLength parameter must be zero when the Transfer-Encoding /// header is present. The Content-Length header cannot be present when the Transfer-Encoding header is present. /// /// /// /// ERROR_WINHTTP_RESEND_REQUEST /// /// The application must call WinHttpSendRequest again due to a redirect or authentication challenge. Windows Server 2003 with SP1, /// Windows XP with SP2 and Windows 2000: This error is not supported. /// /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode, that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen, this function /// can operate either synchronously or asynchronously. In either case, if the request is sent successfully, the application is called /// back with the completion status set to WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. The /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. Upon /// receiving the WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE status callback, the application can start to receive a response /// from the server with WinHttpReceiveResponse. Before then, no other asynchronous functions can be called, otherwise, /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE is returned. /// /// /// An application must not delete or alter the buffer pointed to by lpOptional until the request handle is closed or the call to /// WinHttpReceiveResponse has completed, because an authentication challenge or redirect that required the optional data could be /// encountered in the course of receiving the response. If the operation must be aborted with WinHttpCloseHandle, the application must /// keep the buffer valid until it receives the callback WINHTTP_CALLBACK_STATUS_REQUEST_ERROR with an /// ERROR_WINHTTP_OPERATION_CANCELLED error code. /// /// /// If WinHTTP is used synchronously, that is, when WINHTP_FLAG_ASYNC was not set in WinHttpOpen, an application is not called /// with a completion status even if a callback function is registered. While in this mode, the application can call /// WinHttpReceiveResponse when WinHttpSendRequest returns. /// /// /// The WinHttpSendRequest function sends the specified request to the HTTP server and allows the client to specify additional /// headers to send along with the request. /// /// /// This function also lets the client specify optional data to send to the HTTP server immediately following the request headers. This /// feature is generally used for write operations such as PUT and POST. /// /// /// An application can use the same HTTP request handle in multiple calls to WinHttpSendRequest to re-send the same request, but /// the application must read all data returned from the previous call before calling this function again. /// /// /// The name and value of request headers added with this function are validated. Headers must be well formed. For more information about /// valid HTTP headers, see RFC 2616. If an invalid header is used, this function fails and GetLastError returns ERROR_INVALID_PARAMETER. /// The invalid header is not added. /// /// Windows 2000: When sending requests from multiple threads, there may be a significant decrease in network and CPU performance. /// Windows XP and Windows 2000: See Run-Time Requirements. /// WinHttpSetStatusCallback /// /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate the progress in sending the request: /// /// /// /// WINHTTP_CALLBACK_STATUS_DETECTING_PROXY (not implemented) /// /// /// WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE (only in asynchronous mode) /// /// /// WINHTTP_CALLBACK_STATUS_REDIRECT /// /// /// WINHTTP_CALLBACK_STATUS_SECURE_FAILURE /// /// /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE /// /// /// Note On Windows 7 and Windows Server 2008 R2, all of the following notifications are deprecated. /// /// /// WINHTTP_CALLBACK_STATUS_RESOLVING_NAME /// /// /// WINHTTP_CALLBACK_STATUS_NAME_RESOLVED /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER /// /// /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST /// /// /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// /// If the server closes the connection, the following notifications are also sent, provided that they have been set in the /// dwNotificationFlags parameter of WinHttpSetStatusCallback: /// /// /// /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION /// /// /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED /// /// /// Support for Greater Than 4-GB Upload /// /// Starting in Windows Vista and Windows Server 2008, WinHttp supports uploading files up to the size of a LARGE_INTEGER (2^64 /// bytes) using the Content-Length header. Payload lengths specified in the call to WinHttpSendRequest are limited to the size of /// a DWORD (2^32 bytes). To upload data to a URL larger than a DWORD, the application must provide the length in the /// Content-Length header of the request. In this case, the WinHttp client application calls WinHttpSendRequest with the /// dwTotalLength parameter set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH. /// /// /// If the Content-Length header specifies a length less than a 2^32, the application must also specify the content length in the call to /// WinHttpSendRequest. If the dwTotalLength parameter does not match the length specified in the Content-Length header, /// the call fails and returns ERROR_INVALID_PARAMETER. /// /// /// The Content-Length header can be added in the call to WinHttpAddRequestHeaders, or it can be specified in the lpszHeader /// parameter of WinHttpSendRequest as shown in the following code example. /// /// /// BOOL fRet = WinHttpSendRequest( hReq, L"Content-Length: 68719476735\r\n", -1L, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, pMyContent); /// /// Transfer-Encoding Header /// /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to /// the server. When the Transfer-Encoding header is present on the WinHttp request, the dwTotalLength parameter in the call to /// WinHttpSendRequest is set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH and the application sends the entity body in one or /// more calls to WinHttpWriteData. The lpOptional parameter of WinHttpSendRequest must be NULL and the /// dwOptionLength parameter must be zero, otherwise an ERROR_WINHTTP_INVALID_PARAMETER error is returned. To terminate the /// chunked data transfer, the application generates a zero length chunk and sends it in the last call to WinHttpWriteData. /// /// Examples /// /// The following code example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that /// header to the server. /// /// /// BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // Place additional code here. // Report errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsendrequest BOOL WinHttpSendRequest( [in] HINTERNET // hRequest, [in, optional] LPCWSTR lpszHeaders, [in] DWORD dwHeadersLength, [in, optional] LPVOID lpOptional, [in] DWORD // dwOptionalLength, [in] DWORD dwTotalLength, [in] DWORD_PTR dwContext ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSendRequest")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSendRequest(HINTERNET hRequest, [Optional, MarshalAs(UnmanagedType.LPWStr)] string lpszHeaders, [Optional] int dwHeadersLength, [In, Optional] IntPtr lpOptional, [Optional] uint dwOptionalLength, [Optional] uint dwTotalLength, [In, Optional] IntPtr dwContext); /// The WinHttpSetCredentials function passes the required authorization credentials to the server. /// Valid HINTERNET handle returned by WinHttpOpenRequest. /// /// /// An unsigned integer that specifies a flag that contains the authentication target. Can be one of the values in the following table. /// /// /// /// Value /// Meaning /// /// /// WINHTTP_AUTH_TARGET_SERVER /// Credentials are passed to a server. /// /// /// WINHTTP_AUTH_TARGET_PROXY /// Credentials are passed to a proxy. /// /// /// /// /// /// An unsigned integer that specifies a flag that contains the authentication scheme. Must be one of the supported authentication /// schemes returned from WinHttpQueryAuthSchemes. The following table identifies the possible values. /// /// /// /// Value /// Meaning /// /// /// WINHTTP_AUTH_SCHEME_BASIC /// Use basic authentication. /// /// /// WINHTTP_AUTH_SCHEME_NTLM /// Use NTLM authentication. /// /// /// WINHTTP_AUTH_SCHEME_PASSPORT /// Use passport authentication. /// /// /// WINHTTP_AUTH_SCHEME_DIGEST /// Use digest authentication. /// /// /// WINHTTP_AUTH_SCHEME_NEGOTIATE /// Selects between NTLM and Kerberos authentication. /// /// /// /// Pointer to a string that contains a valid user name. /// Pointer to a string that contains a valid password. The password can be blank. /// This parameter is reserved and must be NULL. /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table /// identifies the error codes returned. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation (Windows error code). /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// /// The credentials set by WinHttpSetCredentials are only used for a single request; WinHTTP does not cache these credentials for /// use in subsequent requests. As a result, applications must be written so that they can respond to multiple challenges. If an /// authenticated connection is re-used, subsequent requests cannot be challenged, but your code should be able to respond to a challenge /// at any point. /// /// For sample code that illustrates the use of WinHttpSetCredentials, see Authentication in WinHTTP. /// /// When using Passport authentication and responding to a 407 status code, a WinHTTP application must use /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport /// authentication; in all other circumstances, use WinHttpSetCredentials, because WinHttpSetOption is less secure. /// /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetcredentials BOOL WinHttpSetCredentials( [in] HINTERNET // hRequest, [in] DWORD AuthTargets, [in] DWORD AuthScheme, [in] LPCWSTR pwszUserName, [in] LPCWSTR pwszPassword, [in] LPVOID pAuthParams ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetCredentials")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSetCredentials(HINTERNET hRequest, WINHTTP_AUTH_TARGET AuthTargets, WINHTTP_AUTH_SCHEME AuthScheme, [MarshalAs(UnmanagedType.LPWStr)] string pwszUserName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszPassword, IntPtr pAuthParams = default); /// The WinHttpSetDefaultProxyConfiguration function sets the default WinHTTP proxy configuration in the registry. /// A pointer to a variable of type WINHTTP_PROXY_INFO that specifies the default proxy configuration. /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are the following. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// The default proxy configuration set by WinHttpSetDefaultProxyConfiguration can be overridden for an existing WinHTTP session /// by calling WinHttpSetOption and specifying the WINHTTP_OPTION_PROXY flag. The default proxy configuration can be overridden for a new /// session by specifying the configuration with the WinHttpOpen function. /// /// /// The dwAccessType member of the WINHTTP_PROXY_INFO structure pointed to by pProxyInfo should be set to /// WINHTTP_ACCESS_TYPE_NAMED_PROXY if a proxy is specified. Otherwise, it should be set to WINHTTP_ACCESS_TYPE_DEFAULT_PROXY. /// /// Any new sessions created after calling this function use the new default proxy configuration. /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetdefaultproxyconfiguration WINHTTPAPI BOOL // WinHttpSetDefaultProxyConfiguration( [in] WINHTTP_PROXY_INFO *pProxyInfo ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetDefaultProxyConfiguration")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSetDefaultProxyConfiguration(in WINHTTP_PROXY_INFO pProxyInfo); /// The WinHttpSetOption function sets an Internet option. /// /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on what /// option is being set. For more information about how to determine which handle is appropriate to use in setting a particular option, /// see the Option Flags. /// /// /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. /// /// A pointer to a buffer that contains the option setting. /// /// Unsigned long integer value that contains the length of the lpBuffer buffer. The length of the buffer is specified in /// characters for the following options; for all other options, the length is specified in bytes. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are the following: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_INVALID_OPTION /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower /// than 15000. /// /// /// /// ERROR_WINHTTP_OPTION_NOT_SETTABLE /// The requested option cannot be set, only queried. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower /// than 15000. /// /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. /// /// /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport /// authentication; in all other circumstances, use WinHttpSetCredentials. /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [In] IntPtr lpBuffer, uint dwBufferLength); /// The WinHttpSetOption function sets an Internet option. /// /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on what /// option is being set. For more information about how to determine which handle is appropriate to use in setting a particular option, /// see the Option Flags. /// /// /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. /// /// The option setting. /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are the following: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_INVALID_OPTION /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower /// than 15000. /// /// /// /// ERROR_WINHTTP_OPTION_NOT_SETTABLE /// The requested option cannot be set, only queried. /// /// /// ERROR_INVALID_PARAMETER /// /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower /// than 15000. /// /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. /// /// /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport /// authentication; in all other circumstances, use WinHttpSetCredentials. /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] public static bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, in T value) where T : struct { using SafeHGlobalHandle mem = SafeHGlobalHandle.CreateFromStructure(value); return WinHttpSetOption(hInternet, dwOption, mem, mem.Size); } /// /// The WinHttpSetStatusCallback function sets up a callback function that WinHTTP can call as progress is made during an operation. /// /// HINTERNET handle for which the callback is to be set. /// /// Pointer to the callback function to call when progress is made. Set this to NULL to remove the existing callback function. For /// more information about the callback function, see WINHTTP_STATUS_CALLBACK. /// /// /// Unsigned long integer value that specifies flags to indicate which events activate the callback function. /// The possible values are as follows. /// /// /// Value /// Meaning /// /// /// WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS /// /// Activates upon any completion notification. This flag specifies that all notifications required for read or write operations are /// used. See WINHTTP_STATUS_CALLBACK for a list of completions. /// /// /// /// WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS /// Activates upon any status change notification including completions. See WINHTTP_STATUS_CALLBACK for a list of notifications. /// /// /// WINHTTP_CALLBACK_FLAG_RESOLVE_NAME /// Activates upon beginning and completing name resolution. /// /// /// WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER /// Activates upon beginning and completing connection to the server. /// /// /// WINHTTP_CALLBACK_FLAG_DETECTING_PROXY /// Activates when detecting the proxy server. /// /// /// WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE /// Activates when completing a query for data. /// /// /// WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE /// Activates when the response headers are available for retrieval. /// /// /// WINHTTP_CALLBACK_FLAG_READ_COMPLETE /// Activates upon completion of a data-read operation. /// /// /// WINHTTP_CALLBACK_FLAG_REQUEST_ERROR /// Activates when an asynchronous error occurs. /// /// /// WINHTTP_CALLBACK_FLAG_SEND_REQUEST /// Activates upon beginning and completing the sending of a request header with WinHttpSendRequest. /// /// /// WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE /// Activates when a request header has been sent with WinHttpSendRequest. /// /// /// WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE /// Activates upon completion of a data-post operation. /// /// /// WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE /// Activates upon beginning and completing the receipt of a resource from the HTTP server. /// /// /// WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION /// Activates when beginning and completing the closing of an HTTP connection. /// /// /// WINHTTP_CALLBACK_FLAG_HANDLES /// Activates when an HINTERNET handle is created or closed. /// /// /// WINHTTP_CALLBACK_FLAG_REDIRECT /// Activates when the request is redirected. /// /// /// WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE /// Activates when receiving an intermediate (100 level) status code message from the server. /// /// /// WINHTTP_CALLBACK_FLAG_SECURE_FAILURE /// Activates upon a secure connection failure. /// /// /// /// This parameter is reserved and must be NULL. /// /// /// If successful, returns a pointer to the previously defined status callback function or NULL if there was no previously defined /// status callback function. Returns WINHTTP_INVALID_STATUS_CALLBACK if the callback function could not be installed. For /// extended error information, call GetLastError. Among the error codes returned are the following. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// If you set the callback on the session handle before creating the request handle, the request handle inherits the callback function /// pointer from its parent session. /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// /// Both synchronous and asynchronous functions use the callback function to indicate the progress of the request, such as resolving a /// name, connecting to a server, and so on. The callback function is required for an asynchronous operation. /// /// /// A callback function can be set on any handle and is inherited by derived handles. A callback function can be changed using /// WinHttpSetStatusCallback, provided there are no pending requests that need to use the previous callback value. However, /// changing the callback function on a handle does not change the callbacks on derived handles, such as that returned by WinHttpConnect. /// You must change the callback function at each level. /// /// Many WinHTTP functions perform several operations on the network. Each operation can take time to complete and each can fail. /// /// After initiating the WinHttpSetStatusCallback function, the callback function can be accessed from within WinHTTP for /// monitoring time-intensive network operations. /// /// /// At the end of asynchronous processing, the application may set the callback function to NULL. This prevents the client /// application from receiving additional notifications. /// /// The following code snippet shows the recommended method for setting the callback function to NULL. /// WinHttpSetStatusCallback( hOpen, NULL, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL ); /// /// Note, however, that WinHTTP does not synchronize WinHttpSetStatusCallback with worker threads. If a callback originating in /// another thread is in progress when an application calls WinHttpSetStatusCallback, the application still receives a callback /// notification even after WinHttpSetStatusCallback successfully sets the callback function to NULL and returns. /// /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// /// The following example shows how to install a callback function for asynchronous WinHTTP functions. The example assumes that a /// WINHTTP_STATUS_CALLBACK function named "AsyncCallback( )" has been previously implemented: /// /// /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Install the status callback function. WINHTTP_STATUS_CALLBACK isCallback = WinHttpSetStatusCallback( hSession, (WINHTTP_STATUS_CALLBACK)AsyncCallback, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL); // Place additional code here. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetstatuscallback WINHTTPAPI WINHTTP_STATUS_CALLBACK // WinHttpSetStatusCallback( [in] HINTERNET hInternet, [in] WINHTTP_STATUS_CALLBACK lpfnInternetCallback, [in] DWORD dwNotificationFlags, // [in] DWORD_PTR dwReserved ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetStatusCallback")] public static extern IntPtr WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, WINHTTP_CALLBACK_FLAG dwNotificationFlags, IntPtr dwReserved = default); /// The WinHttpSetTimeouts function sets time-outs involved with HTTP transactions. /// The HINTERNET handle returned by WinHttpOpen or WinHttpOpenRequest. /// /// /// A value of type integer that specifies the time-out value, in milliseconds, to use for name resolution. If resolution takes longer /// than this time-out value, the action is canceled. The initial value is zero, meaning no time-out (infinite). /// /// /// Windows Vista and Windows XP: If DNS timeout is specified using NAME_RESOLUTION_TIMEOUT, there is an overhead of one thread /// per request. /// /// /// /// /// A value of type integer that specifies the time-out value, in milliseconds, to use for server connection requests. If a connection /// request takes longer than this time-out value, the request is canceled. The initial value is 60,000 (60 seconds). /// /// TCP/IP can time out while setting up the socket during the three leg SYN/ACK exchange, regardless of the value of this parameter. /// /// /// A value of type integer that specifies the time-out value, in milliseconds, to use for sending requests. If sending a request takes /// longer than this time-out value, the send is canceled. The initial value is 30,000 (30 seconds). /// /// /// A value of type integer that specifies the time-out value, in milliseconds, to receive a response to a request. If a response takes /// longer than this time-out value, the request is canceled. The initial value is 30,000 (30 seconds). /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are the following. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// ERROR_INVALID_PARAMETER /// One or more of the timeout parameters has a negative value other than -1. /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// /// A value of 0 or -1 sets a time-out to wait infinitely. A value greater than 0 sets the time-out value in milliseconds. For example, /// 30,000 would set the time-out to 30 seconds. All negative values other than -1 cause the function to fail with ERROR_INVALID_PARAMETER. /// /// /// Important If a small timeout is set using WinHttpSetOption and WINHTTP_OPTION_RECEIVE_TIMEOUT, it can override the value set /// with the dwReceiveTimeout parameter, causing a response to terminate earlier than expected. To avoid this, do not set a /// timeout with the WINHTTP_OPTION_RECEIVE_TIMEOUT option that is smaller than the value set using dwReceiveTimeout. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. /// Examples /// This example shows how to set new time-out values using WinHttpSetTimeouts. /// /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpSetTimeouts to set a new time-out values. if (!WinHttpSetTimeouts( hSession, 10000, 10000, 10000, 10000)) printf( "Error %u in WinHttpSetTimeouts.\n", GetLastError()); // PLACE ADDITIONAL CODE HERE. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsettimeouts BOOL WinHttpSetTimeouts( [in] HINTERNET // hInternet, [in] int nResolveTimeout, [in] int nConnectTimeout, [in] int nSendTimeout, [in] int nReceiveTimeout ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetTimeouts")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpSetTimeouts(HINTERNET hInternet, int nResolveTimeout = 0, int nConnectTimeout = 60000, int nSendTimeout = 30000, int nReceiveTimeout = 30000); /// The WinHttpTimeFromSystemTime function formats a date and time according to the HTTP version 1.0 specification. /// A pointer to a SYSTEMTIME structure that contains the date and time to format. /// /// A pointer to a string buffer that receives the formatted date and time. The buffer should equal to the size, in bytes, of WINHTTP_TIME_FORMAT_BUFSIZE. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError. Error codes /// include the following. /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP Start Page. /// Examples /// The following code example code shows how to convert a SYSTEMTIME structure to a string that contains the time in HTTP format. /// /// SYSTEMTIME sTime; LPWSTR pwszTimeStr; // Get the current time. GetSystemTime(&sTime); // Allocate memory for the string. // Note: WINHTTP_TIME_FORMAT_BUFSIZE is a byte count. // Therefore, you must divide the array by // sizeof WCHAR to get the proper string length. pwszTimeStr = new WCHAR[WINHTTP_TIME_FORMAT_BUFSIZE/sizeof(WCHAR)]; // Convert the current time to HTTP format. if(!WinHttpTimeFromSystemTime( &sTime, pwszTimeStr)) { printf( "Error %u in WinHttpTimeFromSystemTime.\n", GetLastError()); } else { // Print the time. printf("Current time is (%S)\n", pwszTimeStr); } // Free the memory. delete [] pwszTimeStr; /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimefromsystemtime BOOL WinHttpTimeFromSystemTime( [in] // const SYSTEMTIME *pst, [out] LPWSTR pwszTime ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeFromSystemTime")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpTimeFromSystemTime(in SYSTEMTIME pst, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszTime); /// The WinHttpTimeToSystemTime function takes an HTTP time/date string and converts it to a SYSTEMTIME structure. /// /// Pointer to a null-terminated date/time string to convert. This value must use the format defined in section 3.3 of the RFC2616. /// /// Pointer to the SYSTEMTIME structure that receives the converted time. /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned is: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. /// Examples /// This example shows how to convert an HTTP formatted date to a SYSTEMTIME structure. /// /// SYSTEMTIME sTime; LPCWSTR pwszTimeStr = L"Tue, 21 Nov 2000 01:06:53 GMT"; // Convert the HTTP string to a SYSTEMTIME structure. if (!WinHttpTimeToSystemTime( pwszTimeStr, &sTime)) { printf( "Error %u in WinHttpTimeToSystemTime.\n", GetLastError()); } else { // Print the date. printf( "The U.S. formatted date is (%u/%u/%u)\n", sTime.wMonth, sTime.wDay, sTime.wYear); } /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimetosystemtime BOOL WinHttpTimeToSystemTime( [in] // LPCWSTR pwszTime, [out] SYSTEMTIME *pst ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeToSystemTime")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpTimeToSystemTime([MarshalAs(UnmanagedType.LPWStr)] string pwszTime, out SYSTEMTIME pst); /// Unregisters a callback function that was registered by calling WinHttpRegisterProxyChangeNotification. /// /// Type: _In_ WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE* /// The handle that was returned from WinHttpRegisterProxyChangeNotification. /// /// A DWORD containing a status code indicating the result of the operation. // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpunregisterproxychangenotification WINHTTPAPI DWORD // WinHttpUnregisterProxyChangeNotification( WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration ); [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpUnregisterProxyChangeNotification")] [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] public static extern Win32Error WinHttpUnregisterProxyChangeNotification(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration); /// The WinHttpWebSocketClose function closes a WebSocket connection. /// /// Type: HINTERNET /// Handle to a WebSocket. /// /// /// Type: USHORT /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. /// /// /// Type: PVOID /// A detailed reason for the close. /// /// /// Type: DWORD /// The length of pvReason, in bytes. /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. /// /// /// Type: DWORD /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. /// /// /// /// Description /// /// /// ERROR_INVALID_OPERATION /// A close or send is pending. /// /// /// ERROR_INVALID_PARAMETER /// A parameter is invalid. /// /// /// ERROR_INVALID_SERVER_RESPONSE /// Invalid data was received from the server. /// /// /// /// /// /// WinHttpWebSocketClose completely closes a WebSocket connection. To close the send channel while still leaving the receive /// channel open, use WinHttpWebSocketShutdown. /// /// /// It is possible to receive a close frame during regular receive operations. In this case, WinHttpWebSocketClose will also send /// a close frame. /// /// The close timer can be set by the property WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT. The default is 10 seconds. /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketclose WINHTTPAPI DWORD WinHttpWebSocketClose( // [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD dwReasonLength ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketClose")] public static extern Win32Error WinHttpWebSocketClose(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); /// The WinHttpWebSocketCompleteUpgrade function completes a WebSocket handshake started by WinHttpSendRequest. /// /// Type: HINTERNET /// HTTP request handle used to send a WebSocket handshake. /// /// /// Type: DWORD_PTR /// Context to be associated with the new handle. /// /// /// Type: HINTERNET /// A new WebSocket handle. If NULL, call GetLastError to determine the cause of failure. /// /// /// /// WinHttpWebSocketCompleteUpgrade can be called on an open HTTP request to get a WebSocket handle for performing other WebSocket operations. /// /// /// The request handle must be marked as a WebSocket upgrade by calling WinHttpSetOption with WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET /// before sending the request. /// /// /// The caller should check the HTTP status code returned by the server and call this function only if the status code was 101. Calling /// it with any other status code will result in a failure. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketcompleteupgrade WINHTTPAPI HINTERNET // WinHttpWebSocketCompleteUpgrade( [in] HINTERNET hRequest, [in, optional] DWORD_PTR pContext ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketCompleteUpgrade")] public static extern SafeHINTERNET WinHttpWebSocketCompleteUpgrade(HINTERNET hRequest, [In, Optional] IntPtr pContext); /// The WinHttpWebSocketQueryCloseStatus function retrieves the close status sent by a server. /// /// Type: HINTERNET /// Handle to a WebSocket /// /// /// Type: USHORT* /// A pointer to a close status code that will be filled upon return. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. /// /// /// Type: PVOID /// A pointer to a buffer that will receive a close reason on return. /// /// /// Type: DWORD /// The length of the pvReason buffer, in bytes. /// /// /// Type: DWORD* /// /// The number of bytes consumed. If pvReason is NULL and dwReasonLength is 0, pdwReasonLengthConsumed will /// contain the size of the buffer that needs to be allocated by the calling application. /// /// /// /// Type: DWORD /// NO_ERROR on success. Otherwise an error code. /// /// /// /// Description /// /// /// ERROR_INSUFFICIENT_BUFFER /// There is not enough space in pvReason to write the whole close reason. /// /// /// ERROR_INVALID_OPERATION /// No close frame has been received yet. /// /// /// ERROR_INVALID_PARAMETER /// A parameter is invalid. /// /// /// /// /// /// Call WinHttpWebSocketQueryCloseStatus only after WinHttpWebSocketClose succeeds or if WinHttpWebSocketReceive returns WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE. /// /// /// pdwReasonLengthConsumed will never be greater than 123, so allocating buffer with at least 123 will guarantee that /// ERROR_INSUFFICIENT_BUFFER will never be returned. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketqueryclosestatus WINHTTPAPI DWORD // WinHttpWebSocketQueryCloseStatus( [in] HINTERNET hWebSocket, [out] USHORT *pusStatus, [out] PVOID pvReason, [in] DWORD dwReasonLength, // [out] DWORD *pdwReasonLengthConsumed ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketQueryCloseStatus")] public static extern Win32Error WinHttpWebSocketQueryCloseStatus(HINTERNET hWebSocket, out WINHTTP_WEB_SOCKET_CLOSE_STATUS pusStatus, [Out] IntPtr pvReason, uint dwReasonLength, out uint pdwReasonLengthConsumed); /// The WinHttpWebSocketReceive function receives data from a WebSocket connection. /// /// Type: HINTERNET /// Handle to a WebSocket. /// /// /// Type: PVOID /// Pointer to a buffer to receive the data. /// /// /// Type: DWORD /// Length of pvBuffer, in bytes. /// /// /// Type: DWORD* /// /// Pointer to a DWORD that receives the number of bytes read from the connection at the end of the operation. This is set only if /// WinHttpWebSocketReceive returns NO_ERROR and the handle was opened in synchronous mode. /// /// /// /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE* /// /// The type of a returned buffer. This is only set if WinHttpWebSocketReceive returns NO_ERROR and the handle was opened /// in synchronous mode. /// /// /// /// Type: DWORD /// NO_ERROR on success. Otherwise an error code. /// /// /// /// Description /// /// /// ERROR_INVALID_OPERATION /// A close or send is pending, or the receive channel has already been closed. /// /// /// ERROR_INVALID_PARAMETER /// A parameter is invalid. /// /// /// ERROR_INVALID_SERVER_RESPONSE /// Invalid data was received from the server. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was cancelled because WinHttpWebSocketClose was called to close the connection. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketreceive WINHTTPAPI DWORD // WinHttpWebSocketReceive( [in] HINTERNET hWebSocket, [out] PVOID pvBuffer, [in] DWORD dwBufferLength, [out] DWORD *pdwBytesRead, [out] // WINHTTP_WEB_SOCKET_BUFFER_TYPE *peBufferType ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketReceive")] public static extern Win32Error WinHttpWebSocketReceive(HINTERNET hWebSocket, [Out] IntPtr pvBuffer, uint dwBufferLength, out uint pdwBytesRead, out WINHTTP_WEB_SOCKET_BUFFER_TYPE peBufferType); /// The WinHttpWebSocketSend function sends data over a WebSocket connection. /// /// Type: HINTERNET /// Handle to a websocket. /// /// /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE /// Type of buffer. /// /// /// Type: PVOID /// Pointer to a buffer containing the data to send. Can be NULL only if dwBufferLength is 0. /// /// /// Type: DWORD /// Length of pvBuffer. /// /// /// Type: DWORD /// NO_ERROR on success. Otherwise an error code. /// /// /// /// Description /// /// /// ERROR_INVALID_OPERATION /// A close or send is pending, or the send channel has already been closed. /// /// /// ERROR_INVALID_PARAMETER /// A parameter is invalid. /// /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketsend WINHTTPAPI DWORD WinHttpWebSocketSend( [in] // HINTERNET hWebSocket, [in] WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, [in] PVOID pvBuffer, [in] DWORD dwBufferLength ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketSend")] public static extern Win32Error WinHttpWebSocketSend(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, [In, Optional] IntPtr pvBuffer, [In, Optional] uint dwBufferLength); /// /// The WinHttpWebSocketShutdown function sends a close frame to a WebSocket server to close the send channel, but leaves the /// receive channel open. /// /// /// Type: HINTERNET /// Handle to a WebSocket. /// /// /// Type: USHORT /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. /// /// /// Type: PVOID /// A detailed reason for the close. /// /// /// Type: DWORD /// The length of pvReason, in bytes. /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. /// /// /// Type: DWORD /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. /// /// /// /// Description /// /// /// ERROR_IO_PENDING /// The operation will complete asynchronously. /// /// /// /// /// /// WinHttpWebSocketShutdown sends a close frame and prevents additional data from being sent over the WebSocket connection. It /// does not close the receive channel. Use WinHttpWebSocketClose when you want to completely close the connection and prevent any /// subsequent receive operations. /// /// The application is responsible for receiving the close frame from the server (through regular receive operations). /// /// After WinHttpWebSocketShutdown is called, the application can call WinHttpWebSocketClose if it does not want to receive a /// close frame on its own and delegate it to the stack. /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketshutdown WINHTTPAPI DWORD // WinHttpWebSocketShutdown( [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD dwReasonLength ); [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketShutdown")] public static extern Win32Error WinHttpWebSocketShutdown(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); /// The WinHttpWriteData function writes request data to an HTTP server. /// /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. /// /// /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after /// WinHttpWriteData completes. /// /// Unsigned long integer value that contains the number of bytes to be written to the file. /// /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must be /// set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// version 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to get extended /// error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion to determine /// whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates /// that the operation completed asynchronously, but failed. /// /// /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. /// /// /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is called, /// then the data transfer is aborted. /// /// /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server: /// /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN /// /// /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST /// /// /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT /// /// /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE /// /// /// /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. NTLM /// and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails if the /// connection is broken prematurely. /// /// /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for /// each authentication legs. This can be very inefficient for large data uploads. /// /// /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the same /// socket as long as the socket is not pooled with concurrent requests competing for it. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. /// Examples /// /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is /// fictitious and must be replaced with the name of a server for which you have write access. /// /// /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET hRequest, // [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] IntPtr lpBuffer, uint dwNumberOfBytesToWrite, out uint lpdwNumberOfBytesWritten); /// The WinHttpWriteData function writes request data to an HTTP server. /// /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. /// /// /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after /// WinHttpWriteData completes. /// /// Unsigned long integer value that contains the number of bytes to be written to the file. /// /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must be /// set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. /// /// /// /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error /// codes returned are: /// /// /// /// Error Code /// Description /// /// /// ERROR_WINHTTP_CONNECTION_ERROR /// /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP /// version 5.1 does not support SSL2 unless the client specifically enables it. /// /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE /// The requested operation cannot be carried out because the handle supplied is not in the correct state. /// /// /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE /// The type of handle supplied is incorrect for this operation. /// /// /// ERROR_WINHTTP_INTERNAL_ERROR /// An internal error has occurred. /// /// /// ERROR_WINHTTP_OPERATION_CANCELLED /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. /// /// /// ERROR_WINHTTP_TIMEOUT /// The request has timed out. /// /// /// ERROR_NOT_ENOUGH_MEMORY /// Not enough memory was available to complete the requested operation. (Windows error code) /// /// /// /// /// /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function /// can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to get extended /// error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion to determine /// whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates /// that the operation completed asynchronously, but failed. /// /// /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. /// /// /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is called, /// then the data transfer is aborted. /// /// /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server: /// /// /// /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE /// /// /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED /// /// /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN /// /// /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST /// /// /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT /// /// /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE /// /// /// /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. NTLM /// and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails if the /// connection is broken prematurely. /// /// /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for /// each authentication legs. This can be very inefficient for large data uploads. /// /// /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the same /// socket as long as the socket is not pooled with concurrent requests competing for it. /// /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. /// Examples /// /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is /// fictitious and must be replaced with the name of a server for which you have write access. /// /// /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET hRequest, // [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] byte[] lpBuffer, int dwNumberOfBytesToWrite, out int lpdwNumberOfBytesWritten); }