mirror of https://github.com/dahall/Vanara.git
2734 lines
157 KiB
C#
2734 lines
157 KiB
C#
using System;
|
||
using System.Linq;
|
||
using System.Runtime.InteropServices;
|
||
using System.Text;
|
||
using Vanara.Extensions;
|
||
using Vanara.InteropServices;
|
||
using static Vanara.PInvoke.Schannel;
|
||
using static Vanara.PInvoke.Ws2_32;
|
||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||
using INTERNET_PORT = System.UInt16;
|
||
|
||
namespace Vanara.PInvoke
|
||
{
|
||
/// <summary>Items from the WinHTTP.dll.</summary>
|
||
public static partial class WinHTTP
|
||
{
|
||
private const string Lib_Winhttp = "WinHTTP.dll";
|
||
|
||
/// <summary>The <c>WINHTTP_STATUS_CALLBACK</c> type represents an application-defined status callback function.</summary>
|
||
/// <param name="hInternet">The handle for which the callback function is called.</param>
|
||
/// <param name="dwContext">
|
||
/// <para>
|
||
/// A pointer to a <c>DWORD</c> that specifies the application-defined context value associated with the handle in the
|
||
/// <c>hInternet</c> parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// A context value can be assigned to a Session, Connect, or Request handle by calling WinHttpSetOption with the
|
||
/// WINHTTP_OPTION_CONTEXT_VALUE option. Alternatively, WinHttpSendRequest can be used to associate a context value with a Request handle.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwInternetStatus">
|
||
/// <para>
|
||
/// Points to a <c>DWORD</c> that specifies the status code that indicates why the callback function is called. This can be one of
|
||
/// the following values:
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION</para>
|
||
/// <para>Closing the connection to the server. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER</para>
|
||
/// <para>
|
||
/// Successfully connected to the server. The <c>lpvStatusInformation</c> parameter contains a pointer to an <c>LPWSTR</c> that
|
||
/// indicates the IP address of the server in dotted notation.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER</para>
|
||
/// <para>
|
||
/// Connecting to the server. The <c>lpvStatusInformation</c> parameter contains a pointer to an <c>LPWSTR</c> that indicates the IP
|
||
/// address of the server in dotted notation.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED</para>
|
||
/// <para>Successfully closed the connection to the server. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE</para>
|
||
/// <para>
|
||
/// Data is available to be retrieved with WinHttpReadData. The <c>lpvStatusInformation</c> parameter points to a <c>DWORD</c> that
|
||
/// contains the number of bytes of data available. The <c>dwStatusInformationLength</c> parameter itself is 4 (the size of a <c>DWORD</c>).
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_HANDLE_CREATED</para>
|
||
/// <para>An HINTERNET handle has been created. The <c>lpvStatusInformation</c> parameter contains a pointer to the HINTERNET handle.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</para>
|
||
/// <para>
|
||
/// This handle value has been terminated. The <c>lpvStatusInformation</c> parameter contains a pointer to the HINTERNET handle.
|
||
/// There will be no more callbacks for this handle.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE</para>
|
||
/// <para>
|
||
/// The response header has been received and is available with WinHttpQueryHeaders. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE</para>
|
||
/// <para>
|
||
/// Received an intermediate (100 level) status code message from the server. The <c>lpvStatusInformation</c> parameter contains a
|
||
/// pointer to a <c>DWORD</c> that indicates the status code.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_NAME_RESOLVED</para>
|
||
/// <para>
|
||
/// Successfully found the IP address of the server. The <c>lpvStatusInformation</c> parameter contains a pointer to a <c>LPWSTR</c>
|
||
/// that indicates the name that was resolved.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_READ_COMPLETE</para>
|
||
/// <para>
|
||
/// Data was successfully read from the server. The <c>lpvStatusInformation</c> parameter contains a pointer to the buffer specified
|
||
/// in the call to WinHttpReadData. The <c>dwStatusInformationLength</c> parameter contains the number of bytes read.
|
||
/// </para>
|
||
/// <para>
|
||
/// When used by WinHttpWebSocketReceive, the <c>lpvStatusInformation</c> parameter contains a pointer to a WINHTTP_WEB_SOCKET_STATUS
|
||
/// structure, and the <c>dwStatusInformationLength</c> parameter indicates the size of <c>lpvStatusInformation</c>.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE</para>
|
||
/// <para>Waiting for the server to respond to a request. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_REDIRECT</para>
|
||
/// <para>
|
||
/// An HTTP request is about to automatically redirect the request. The <c>lpvStatusInformation</c> parameter contains a pointer to
|
||
/// an <c>LPWSTR</c> indicating the new URL. At this point, the application can read any data returned by the server with the
|
||
/// redirect response and can query the response headers. It can also cancel the operation by closing the handle.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_REQUEST_ERROR</para>
|
||
/// <para>
|
||
/// An error occurred while sending an HTTP request. The <c>lpvStatusInformation</c> parameter contains a pointer to a
|
||
/// WINHTTP_ASYNC_RESULT structure. Its <c>dwResult</c> member indicates the ID of the called function and <c>dwError</c> indicates
|
||
/// the return value.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_REQUEST_SENT</para>
|
||
/// <para>
|
||
/// Successfully sent the information request to the server. The <c>lpvStatusInformation</c> parameter contains a pointer to a
|
||
/// <c>DWORD</c> indicating the number of bytes sent.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_RESOLVING_NAME</para>
|
||
/// <para>
|
||
/// Looking up the IP address of a server name. The <c>lpvStatusInformation</c> parameter contains a pointer to the server name being resolved.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED</para>
|
||
/// <para>
|
||
/// Successfully received a response from the server. The <c>lpvStatusInformation</c> parameter contains a pointer to a <c>DWORD</c>
|
||
/// indicating the number of bytes received.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_SECURE_FAILURE</para>
|
||
/// <para>
|
||
/// One or more errors were encountered while retrieving a Secure Sockets Layer (SSL) certificate from the server. The
|
||
/// <c>lpvStatusInformation</c> parameter contains a flag. For more information, see the description for <c>lpvStatusInformation</c>.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_SENDING_REQUEST</para>
|
||
/// <para>Sending the information request to the server. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE</para>
|
||
/// <para>The request completed successfully. The <c>lpvStatusInformation</c> parameter is <c>NULL</c>.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE</para>
|
||
/// <para>
|
||
/// Data was successfully written to the server. The <c>lpvStatusInformation</c> parameter contains a pointer to a <c>DWORD</c> that
|
||
/// indicates the number of bytes written.
|
||
/// </para>
|
||
/// <para>
|
||
/// When used by WinHttpWebSocketSend, the <c>lpvStatusInformation</c> parameter contains a pointer to a WINHTTP_WEB_SOCKET_STATUS
|
||
/// structure, and the <c>dwStatusInformationLength</c> parameter indicates the size of <c>lpvStatusInformation</c>.
|
||
/// </para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE</para>
|
||
/// <para>The operation initiated by a call to WinHttpGetProxyForUrlEx is complete. Data is available to be retrieved with WinHttpReadData.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE</para>
|
||
/// <para>The connection was successfully closed via a call to WinHttpWebSocketClose.</para>
|
||
/// <para>WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE</para>
|
||
/// <para>The connection was successfully shut down via a call to WinHttpWebSocketShutdown.</para>
|
||
/// </param>
|
||
/// <param name="lpvStatusInformation">
|
||
/// <para>
|
||
/// A pointer to a buffer that specifies information pertinent to this call to the callback function. The format of these data
|
||
/// depends on the value of the <c>dwInternetStatus</c> argument. For more information, see <c>dwInternetStatus</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the <c>dwInternetStatus</c> argument is WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, then <c>lpvStatusInformation</c> points to a
|
||
/// DWORD which is a bitwise-OR combination of one or more of the following values.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED</c></term>
|
||
/// <term>
|
||
/// Certification revocation checking has been enabled, but the revocation check failed to verify whether a certificate has been
|
||
/// revoked. The server used to check for revocation might be unreachable.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT</c></term>
|
||
/// <term>SSL certificate is invalid.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED</c></term>
|
||
/// <term>SSL certificate was revoked.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA</c></term>
|
||
/// <term>The function is unfamiliar with the Certificate Authority that generated the server's certificate.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID</c></term>
|
||
/// <term>
|
||
/// SSL certificate common name (host name field) is incorrect, for example, if you entered www.microsoft.com and the common name on
|
||
/// the certificate says www.msn.com.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID</c></term>
|
||
/// <term>SSL certificate date that was received from the server is bad. The certificate is expired.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR</c></term>
|
||
/// <term>The application experienced an internal error loading the SSL libraries.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="dwStatusInformationLength">
|
||
/// <c>WINHTTP_CALLBACK_STATUS_REDIRECT</c> status callbacks provide a <c>dwStatusInformationLength</c> value that corresponds to the
|
||
/// character count of the <c>LPWSTR</c> pointed to by <c>lpvStatusInformation</c>.
|
||
/// </param>
|
||
/// <returns>None</returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// The callback function must be threadsafe and reentrant because it can be called on another thread for a separate request, and
|
||
/// reentered on the same thread for the current request. It must therefore be coded to handle reentrance safely while processing.
|
||
/// When the <c>dwInternetStatus</c> parameter is equal to <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c>, the callback does not need
|
||
/// to be able to handle reentrance for the same request, because this callback is guaranteed to be the last, and does not occur when
|
||
/// other messages for this request are handled.
|
||
/// </para>
|
||
/// <para>
|
||
/// The status callback function receives updates on the status of asynchronous operations through notification flags. Notifications
|
||
/// that indicate a particular operation is complete are called completion notifications, or just completions. The following table
|
||
/// lists the six completion flags and the corresponding function that is complete when this flag is received.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Completion flag</term>
|
||
/// <term>Function</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE</term>
|
||
/// <term>WinHttpQueryDataAvailable</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE</term>
|
||
/// <term>WinHttpReceiveResponse</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_READ_COMPLETE</term>
|
||
/// <term>WinHttpReadData</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE</term>
|
||
/// <term>WinHttpSendRequest</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE</term>
|
||
/// <term>WinHttpWriteData</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_REQUEST_ERROR</term>
|
||
/// <term>Any of the above functions when an error occurs.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// Because callbacks are made during the processing of the request, the application should spend as little time as possible in the
|
||
/// callback function to avoid degrading data throughput on the network. For example, displaying a dialog box in a callback function
|
||
/// can be such a lengthy operation that the server terminates the request.
|
||
/// </para>
|
||
/// <para>The callback function can be called in a thread context different from the thread that initiated the request.</para>
|
||
/// <para>
|
||
/// Similarly, there is no callback thread affinity when you call WinHttp asynchronously: a call might start from one thread, but any
|
||
/// other thread can receive the callback.
|
||
/// </para>
|
||
/// <para><c>Note</c> For more information about implementation in Windows XP and Windows 2000, see Run-Time Requirements.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nc-winhttp-winhttp_status_callback WINHTTP_STATUS_CALLBACK
|
||
// WinhttpStatusCallback; void WinhttpStatusCallback( [in] HINTERNET hInternet, [in] DWORD_PTR dwContext, [in] DWORD
|
||
// dwInternetStatus, [in] LPVOID lpvStatusInformation, [in] DWORD dwStatusInformationLength ) {...}
|
||
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NC:winhttp.WINHTTP_STATUS_CALLBACK")]
|
||
public delegate void WINHTTP_STATUS_CALLBACK([In] HINTERNET hInternet, [In] IntPtr dwContext, WINHTTP_CALLBACK_STATUS dwInternetStatus,
|
||
[In] IntPtr lpvStatusInformation, uint dwStatusInformationLength);
|
||
|
||
/// <summary>The <c>WinHttpAddRequestHeaders</c> function adds one or more HTTP request headers to the HTTP request handle.</summary>
|
||
/// <param name="hRequest">A HINTERNET handle returned by a call to the WinHttpOpenRequest function.</param>
|
||
/// <param name="lpszHeaders">
|
||
/// A pointer to a string variable that contains the headers to append to the request. Each header except the last must be terminated
|
||
/// by a carriage return/line feed (CR/LF).
|
||
/// </param>
|
||
/// <param name="dwHeadersLength">
|
||
/// An unsigned long integer value that contains the length, in characters, of <c>pwszHeaders</c>. If this parameter is -1L, the
|
||
/// function assumes that <c>pwszHeaders</c> is zero-terminated (ASCIIZ), and the length is computed.
|
||
/// </param>
|
||
/// <param name="dwModifiers">
|
||
/// <para>
|
||
/// An unsigned long integer value that contains the flags used to modify the semantics of this function. Can be one or more of the
|
||
/// following flags.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_ADD</c></term>
|
||
/// <term>Adds the header if it does not exist. Used with <c>WINHTTP_ADDREQ_FLAG_REPLACE</c>.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_ADD_IF_NEW</c></term>
|
||
/// <term>Adds the header only if it does not already exist; otherwise, an error is returned.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE</c></term>
|
||
/// <term>Merges headers of the same name.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA</c></term>
|
||
/// <term>
|
||
/// Merges headers of the same name using a comma. For example, adding "Accept: text/*" followed by "Accept: audio/*" with this flag
|
||
/// results in a single header "Accept: text/*, audio/*". This causes the first header found to be merged. The calling application
|
||
/// must to ensure a cohesive scheme with respect to merged and separate headers.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON</c></term>
|
||
/// <term>Merges headers of the same name using a semicolon.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_REPLACE</c></term>
|
||
/// <term>
|
||
/// Replaces or removes a header. If the header value is empty and the header is found, it is removed. If the value is not empty, it
|
||
/// is replaced.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise. For extended error information, call GetLastError. Among the error
|
||
/// codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be performed because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Headers are transferred across redirects. This can be a security issue. To avoid having headers transferred when a redirect
|
||
/// occurs, use the WINHTTP_STATUS_CALLBACK callback to correct the specific headers when a redirect occurs.
|
||
/// </para>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>WinHttpAddRequestHeaders</c> function appends additional free-format headers to the HTTP request handle and is intended
|
||
/// for use by sophisticated clients that require detailed control over the exact request sent to the HTTP server.
|
||
/// </para>
|
||
/// <para>
|
||
/// 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.
|
||
/// </para>
|
||
/// <para>
|
||
/// If you are sending a Date: request header, you can use the WinHttpTimeFromSystemTime function to create structure for the header.
|
||
/// </para>
|
||
/// <para>For basic <c>WinHttpAddRequestHeaders</c>, the application can pass in multiple headers in a single buffer.</para>
|
||
/// <para>An application can also use WinHttpSendRequest to add additional headers to the HTTP request handle before sending a request.</para>
|
||
/// <para><c>Note</c> For more information, see Run-Time Requirements.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following code example includes an If-Modified-Since header in a request. The response header is interpreted to determine
|
||
/// whether the target document has been updated.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code><![CDATA[DWORD dwSize = sizeof(DWORD);
|
||
/// DWORD dwStatusCode = 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.microsoft.com", INTERNET_DEFAULT_HTTP_PORT, 0 );
|
||
/// // Create an HTTP Request handle.
|
||
/// if( hConnect )
|
||
/// hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 );
|
||
/// // Add a request header.
|
||
/// if( hRequest )
|
||
/// bResults = WinHttpAddRequestHeaders( hRequest, L"If-Modified-Since: Mon, 20 Nov 2000 20:00:00 GMT", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD );
|
||
/// // Send a Request.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 );
|
||
/// // End the request.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpReceiveResponse( hRequest, NULL);
|
||
/// // Use WinHttpQueryHeaders to obtain the header buffer.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX );
|
||
/// // Based on the status code, determine whether
|
||
/// // the document was recently updated.
|
||
/// if( bResults ) {
|
||
/// if( dwStatusCode == 304 )
|
||
/// printf( "Document has not been updated.\n" );
|
||
/// else if( dwStatusCode == 200 )
|
||
/// printf( "Document has been updated.\n" );
|
||
/// else
|
||
/// printf( "Status code = %u.\n",dwStatusCode );
|
||
/// }
|
||
/// // Report any 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 );]]></code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpaddrequestheaders BOOL WinHttpAddRequestHeaders( [in]
|
||
// HINTERNET hRequest, [in] LPCWSTR lpszHeaders, [in] DWORD dwHeadersLength, [in] DWORD dwModifiers );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpAddRequestHeaders")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpAddRequestHeaders(HINTERNET hRequest, [MarshalAs(UnmanagedType.LPWStr)] string lpszHeaders, int dwHeadersLength, WINHTTP_ADDREQ_FLAG dwModifiers);
|
||
|
||
/// <summary>Adds one or more HTTP request headers to an HTTP request handle, allowing you to use separate name/value strings.</summary>
|
||
/// <param name="hRequest">
|
||
/// <para>Type: IN <c>HINTERNET</c></para>
|
||
/// <para>An <c>HINTERNET</c> handle returned by a call to WinHttpOpenRequest.</para>
|
||
/// </param>
|
||
/// <param name="dwModifiers">
|
||
/// <para>Type: IN <c>DWORD</c></para>
|
||
/// <para>
|
||
/// An unsigned long integer value that contains the flags used to modify the semantics of this function. Can be one or more of the
|
||
/// following flags.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_ADD</c></term>
|
||
/// <term>Adds the header if it does not exist. Used with <c>WINHTTP_ADDREQ_FLAG_REPLACE</c>.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_ADD_IF_NEW</c></term>
|
||
/// <term>Adds the header only if it does not already exist; otherwise, an error is returned.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE</c></term>
|
||
/// <term>Merges headers of the same name.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA</c></term>
|
||
/// <term>
|
||
/// Merges headers of the same name using a comma. For example, adding "Accept: text/*" followed by "Accept: audio/*" with this flag
|
||
/// results in a single header "Accept: text/*, audio/*". This causes the first header found to be merged. The calling application
|
||
/// must to ensure a cohesive scheme with respect to merged and separate headers.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON</c></term>
|
||
/// <term>Merges headers of the same name using a semicolon.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ADDREQ_FLAG_REPLACE</c></term>
|
||
/// <term>
|
||
/// Replaces or removes a header. If the header value is empty and the header is found, it is removed. If the value is not empty, it
|
||
/// is replaced.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="ullFlags">
|
||
/// <para>Type: IN <c>ULONGLONG</c></para>
|
||
/// <para>Pass <c>WINHTTP_EXTENDED_HEADER_FLAG_UNICODE</c> to indicate that the strings passed in are Unicode strings.</para>
|
||
/// </param>
|
||
/// <param name="ullExtra">
|
||
/// <para>Type: IN <c>ULONGLONG</c></para>
|
||
/// <para>Reserved.</para>
|
||
/// </param>
|
||
/// <param name="cHeaders">
|
||
/// <para>Type: IN <c>DWORD</c></para>
|
||
/// <para>The number of elements in pHeaders.</para>
|
||
/// </param>
|
||
/// <param name="pHeaders">
|
||
/// <para>Type: _In_reads_(cHeaders) <c>WINHTTP_EXTENDED_HEADER*</c></para>
|
||
/// <para>An array of <c>WINHTTP_EXTENDED_HEADER</c> structures.</para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation. Among the error codes returned are the following.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be performed because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpaddrequestheadersex WINHTTPAPI DWORD
|
||
// WinHttpAddRequestHeadersEx( HINTERNET hRequest, DWORD dwModifiers, ULONGLONG ullFlags, ULONGLONG ullExtra, DWORD cHeaders,
|
||
// WINHTTP_EXTENDED_HEADER *pHeaders );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpAddRequestHeadersEx")]
|
||
public static extern Win32Error WinHttpAddRequestHeadersEx(HINTERNET hRequest, WINHTTP_ADDREQ_FLAG dwModifiers, WINHTTP_EXTENDED_HEADER_FLAG ullFlags,
|
||
[Optional] ulong ullExtra, int cHeaders, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] WINHTTP_EXTENDED_HEADER[] pHeaders);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpCheckPlatform</c> function determines whether the current platform is supported by this version of Microsoft
|
||
/// Windows HTTP Services (WinHTTP).
|
||
/// </summary>
|
||
/// <returns>
|
||
/// The return value is <c>TRUE</c> if the platform is supported by Microsoft Windows HTTP Services (WinHTTP), or <c>FALSE</c> otherwise.
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// This function is useful if your application uses Microsoft Windows HTTP Services (WinHTTP), but also supports platforms that
|
||
/// WinHTTP does not.
|
||
/// </para>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// WinHTTP version 5.1 is an operating-system component of Windows 2000 with Service Pack 3 (SP3) and later (except Datacenter
|
||
/// Server), Windows XP with Service Pack 1 (SP1) and later, and Windows Server 2003. In Windows Server 2003, WinHTTP is a system
|
||
/// side-by-side assembly.
|
||
/// </para>
|
||
/// <para>For more information, see Run-Time Requirements.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>The following example shows how to determine whether the current platform is supported.</para>
|
||
/// <para>
|
||
/// <code language="c"> if (WinHttpCheckPlatform( )) printf("This platform is supported by WinHTTP.\n"); else printf("This platform is NOT supported by WinHTTP.\n");</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpcheckplatform BOOL WinHttpCheckPlatform();
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCheckPlatform")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpCheckPlatform();
|
||
|
||
/// <summary>The <c>WinHttpCloseHandle</c> function closes a single <c>HINTERNET</c> handle (see HINTERNET Handles in WinHTTP).</summary>
|
||
/// <param name="hInternet">A valid <c>HINTERNET</c> handle (see HINTERNET Handles in WinHTTP) to be closed.</param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// <c>TRUE</c> if the handle is successfully closed, otherwise <c>FALSE</c>. To get extended error information, call GetLastError.
|
||
/// Among the error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Codes</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_SHUTDOWN</c></term>
|
||
/// <term>The WinHTTP function support is being shut down or unloaded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// If there is a status callback registered for the handle being closed and the handle was created with a non- <c>NULL</c> context
|
||
/// value, a <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c> callback is made. This is the last callback made from the handle and
|
||
/// indicates that the handle is being destroyed.
|
||
/// </para>
|
||
/// <para>
|
||
/// An application can terminate an in-progress asynchronous request by closing the HINTERNET request handle using
|
||
/// <c>WinHttpCloseHandle</c>. Keep the following points in mind:
|
||
/// </para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>
|
||
/// After an application calls <c>WinHttpCloseHandle</c> on a WinHTTP handle, it cannot call any other WinHTTP API functions using
|
||
/// that handle from any thread.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// Even after a call to <c>WinHttpCloseHandle</c> returns, the application must still be prepared to receive callbacks for the
|
||
/// closed handle, because WinHTTP can tear down the handle asynchronously. If the asynchronous request was not able to complete
|
||
/// successfully, the callback receives a WINHTTP_CALLBACK_STATUS_REQUEST_ERROR notification.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// If an application associates a context data structure or object with the handle, it should maintain that binding until the
|
||
/// callback function receives a <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c> notification. This is the last callback notification
|
||
/// WinHTTP sends prior to deleting a handle object from memory. In order to receive the
|
||
/// <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c> callback notification, the application must enable the
|
||
/// <c>WINHTTP_CALLBACK_FLAG_HANDLES</c> flag in the WinHttpSetStatusCallback call.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// Before calling <c>WinHttpCloseHandle</c>, an application can call WinHttpSetStatusCallback to indicate that no more callbacks
|
||
/// should be made:
|
||
/// <para>
|
||
/// <code>WinHttpSetStatusCallback( hRequest, NULL, 0, 0 );</code>
|
||
/// </para>
|
||
/// <para>
|
||
/// It might seem that the context data structure could then be freed immediately rather than having to wait for a
|
||
/// <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c> notification, but this is not the case: WinHTTP does not synchronize
|
||
/// WinHttpSetStatusCallback with callbacks originating in worker threads. As a result, a callback could already be in progress from
|
||
/// another thread, and the application could receive a callback notification even after having <c>NULL</c> ed-out the callback
|
||
/// function pointer and deleted the handle's context data structure. Because of this potential race condition, be conservative in
|
||
/// freeing the context structure until after having received the <c>WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING</c> notification.
|
||
/// </para>
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para>
|
||
/// An application should never call <c>WinHttpCloseHandle</c> on a synchronous request. This can create a race condition. See
|
||
/// HINTERNET Handles in WinHTTP for more information.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpclosehandle BOOL WinHttpCloseHandle( [in] HINTERNET
|
||
// hInternet );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCloseHandle")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpCloseHandle(HINTERNET hInternet);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpConnect</c> function specifies the initial target server of an HTTP request and returns an HINTERNET connection
|
||
/// handle to an HTTP session for that initial target.
|
||
/// </summary>
|
||
/// <param name="hSession">Valid HINTERNET WinHTTP session handle returned by a previous call to WinHttpOpen.</param>
|
||
/// <param name="pswzServerName">
|
||
/// Pointer to a <c>null</c>-terminated string that contains the host name of an HTTP server. Alternately, the string can contain the
|
||
/// IP address of the site in ASCII, for example, 10.0.1.45. Note that WinHttp does not accept international host names without
|
||
/// converting them first to Punycode. For more information, see Handling Internationalized Domain Names (IDNs).
|
||
/// </param>
|
||
/// <param name="nServerPort">
|
||
/// <para>
|
||
/// Unsigned integer that specifies the TCP/IP port on the server to which a connection is made. This parameter can be any valid
|
||
/// TCP/IP port number, or one of the following values.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <description><c>INTERNET_DEFAULT_HTTP_PORT</c></description>
|
||
/// <description>Uses the default port for HTTP servers (port 80).</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>INTERNET_DEFAULT_HTTPS_PORT</c></description>
|
||
/// <description>
|
||
/// Uses the default port for HTTPS servers (port 443). Selecting this port does not automatically establish a secure connection. You
|
||
/// must still specify the use of secure transaction semantics by using the WINHTTP_FLAG_SECURE flag with WinHttpOpenRequest.
|
||
/// </description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>INTERNET_DEFAULT_PORT</c></description>
|
||
/// <description>Uses port 80 for HTTP and port 443 for Secure Hypertext Transfer Protocol (HTTPS).</description>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="dwReserved">This parameter is reserved and must be 0.</param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns a valid connection handle to the HTTP session if the connection is successful, or <c>NULL</c> otherwise. To retrieve
|
||
/// extended error information, call GetLastError. Among the error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Codes</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></description>
|
||
/// <description>The type of handle supplied is incorrect for this operation.</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_INTERNAL_ERROR</c></description>
|
||
/// <description>An internal error has occurred.</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_INVALID_URL</c></description>
|
||
/// <description>The URL is invalid.</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_OPERATION_CANCELLED</c></description>
|
||
/// <description>
|
||
/// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
|
||
/// </description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_UNRECOGNIZED_SCHEME</c></description>
|
||
/// <description>The URL scheme could not be recognized, or is not supported.</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_WINHTTP_SHUTDOWN</c></description>
|
||
/// <description>The WinHTTP function support is being shut down or unloaded.</description>
|
||
/// </item>
|
||
/// <item>
|
||
/// <description><c>ERROR_NOT_ENOUGH_MEMORY</c></description>
|
||
/// <description>Not enough memory was available to complete the requested operation. (Windows error code)</description>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// After the calling application has finished using the HINTERNET handle returned by <c>WinHttpConnect</c>, it must be closed using
|
||
/// the WinHttpCloseHandle function.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpConnect</c> specifies the target HTTP server, however a response can come from another server if the request was
|
||
/// redirected. You can determine the URL of the server sending the response by calling WinHttpQueryOption with the
|
||
/// WINHTTP_OPTION_URL flag.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following example shows how to use secure transaction semantics to download a resource from an HTTPS server. The sample code
|
||
/// initializes the Microsoft Windows HTTP Services (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.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code><![CDATA[DWORD dwSize = sizeof(DWORD);
|
||
/// DWORD dwStatusCode = 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.microsoft.com", INTERNET_DEFAULT_HTTP_PORT, 0 );
|
||
/// // Create an HTTP Request handle.
|
||
/// if( hConnect )
|
||
/// hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0 );
|
||
/// // Add a request header.
|
||
/// if( hRequest )
|
||
/// bResults = WinHttpAddRequestHeaders( hRequest, L"If-Modified-Since: Mon, 20 Nov 2000 20:00:00 GMT", (ULONG)-1L, WINHTTP_ADDREQ_FLAG_ADD );
|
||
/// // Send a Request.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 );
|
||
/// // End the request.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpReceiveResponse( hRequest, NULL);
|
||
/// // Use WinHttpQueryHeaders to obtain the header buffer.
|
||
/// if( bResults )
|
||
/// bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatusCode, &dwSize, WINHTTP_NO_HEADER_INDEX );
|
||
/// // Based on the status code, determine whether
|
||
/// // the document was recently updated.
|
||
/// if( bResults ) {
|
||
/// if( dwStatusCode == 304 )
|
||
/// printf( "Document has not been updated.\n" );
|
||
/// else if( dwStatusCode == 200 )
|
||
/// printf( "Document has been updated.\n" );
|
||
/// else
|
||
/// printf( "Status code = %u.\n",dwStatusCode );
|
||
/// }
|
||
/// // Report any 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 );]]></code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpconnect WINHTTPAPI HINTERNET WinHttpConnect( [in]
|
||
// HINTERNET hSession, [in] LPCWSTR pswzServerName, [in] INTERNET_PORT nServerPort, [in] DWORD dwReserved );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpConnect")]
|
||
public static extern SafeHINTERNET WinHttpConnect(HINTERNET hSession, [MarshalAs(UnmanagedType.LPWStr)] string pswzServerName, INTERNET_PORT nServerPort, uint dwReserved = 0);
|
||
|
||
/// <summary>The <c>WinHttpCrackUrl</c> function separates a URL into its component parts such as host name and path.</summary>
|
||
/// <param name="pwszUrl">
|
||
/// Pointer to a string that contains the canonical URL to separate. <c>WinHttpCrackUrl</c> does not check this URL for validity or
|
||
/// correct format before attempting to crack it.
|
||
/// </param>
|
||
/// <param name="dwUrlLength">
|
||
/// The length of the <c>pwszUrl</c> string, in characters. If <c>dwUrlLength</c> is set to zero, <c>WinHttpCrackUrl</c> assumes that
|
||
/// the <c>pwszUrl</c> string is <c>null</c> terminated and determines the length of the <c>pwszUrl</c> string based on that assumption.
|
||
/// </param>
|
||
/// <param name="dwFlags">
|
||
/// <para>
|
||
/// The flags that control the operation. This parameter can be a combination of one or more of the following flags (values can be
|
||
/// bitwise OR'd together). Or, the parameter can be 0, which performs no special operations.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ICU_DECODE</c></term>
|
||
/// <term>
|
||
/// Converts characters that are "escape encoded" (%xx) to their non-escaped form. This does not decode other encodings, such as
|
||
/// UTF-8. This feature can be used only if the user provides buffers in the URL_COMPONENTS structure to copy the components into.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ICU_ESCAPE</c></term>
|
||
/// <term>
|
||
/// Escapes certain characters to their escape sequences (%xx). Characters to be escaped are non-ASCII characters or those ASCII
|
||
/// characters that must be escaped to be represented in an HTTP request. This feature can be used only if the user provides buffers
|
||
/// in the URL_COMPONENTS structure to copy the components into.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ICU_REJECT_USERPWD</c></term>
|
||
/// <term>
|
||
/// Rejects URLs as input that contain embedded credentials (either a username, a password, or both). If the function fails because
|
||
/// of an invalid URL, then subsequent calls to GetLastError return <c>ERROR_WINHTTP_INVALID_URL</c>.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="lpUrlComponents">Pointer to a URL_COMPONENTS structure that receives the URL components.</param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if the function succeeds, or <c>FALSE</c> otherwise. To get extended error information, call GetLastError.
|
||
/// Among the error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Codes</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INVALID_URL</c></term>
|
||
/// <term>The URL is invalid.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNRECOGNIZED_SCHEME</c></term>
|
||
/// <term>The URL scheme could not be recognized, or is not supported.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// The required components are indicated by members of the URL_COMPONENTS structure. Each component has a pointer to the value and
|
||
/// has a member that stores the length of the stored value. If both the value and the length for a component are equal to zero, that
|
||
/// component is not returned. If the pointer to the value of the component is not <c>NULL</c> and the value of its corresponding
|
||
/// length member is nonzero, the address of the first character of the corresponding component in the <c>pwszUrl</c> string is
|
||
/// stored in the pointer, and the length of the component is stored in the length member.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the pointer contains the address of the user-supplied buffer, the length member must contain the size of the buffer. The
|
||
/// <c>WinHttpCrackUrl</c> function copies the component into the buffer, and the length member is set to the length of the copied
|
||
/// component, minus 1 for the trailing string terminator. If a user-supplied buffer is not large enough, <c>WinHttpCrackUrl</c>
|
||
/// returns <c>FALSE</c>, and GetLastError returns <c>ERROR_INSUFFICIENT_BUFFER</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// For <c>WinHttpCrackUrl</c> to work properly, the size of the URL_COMPONENTS structure must be stored in the dwStructSize member
|
||
/// of that structure.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the Internet protocol of the URL passed in for <c>pwszUrl</c> is not HTTP or HTTPS, then <c>WinHttpCrackUrl</c> returns
|
||
/// <c>FALSE</c> and GetLastError indicates ERROR_WINHTTP_UNRECOGNIZED_SCHEME.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpCrackUrl</c> does not check the validity or format of a URL before attempting to crack it. As a result, if a string
|
||
/// such as ""http://server?Bad=URL"" is passed in, the function returns incorrect results.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>This example shows how to break a URL into its components, update a component, then reconstruct the URL.</para>
|
||
/// <para>
|
||
/// <code> URL_COMPONENTS urlComp; LPCWSTR pwszUrl1 = L"http://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet"; DWORD dwUrlLen = 0; // Initialize the URL_COMPONENTS structure. ZeroMemory(&urlComp, sizeof(urlComp)); urlComp.dwStructSize = sizeof(urlComp); // Set required component lengths to non-zero // so that they are cracked. urlComp.dwSchemeLength = (DWORD)-1; urlComp.dwHostNameLength = (DWORD)-1; urlComp.dwUrlPathLength = (DWORD)-1; urlComp.dwExtraInfoLength = (DWORD)-1; // Crack the URL. if (!WinHttpCrackUrl( pwszUrl1, (DWORD)wcslen(pwszUrl1), 0, &urlComp)) { printf("Error %u in WinHttpCrackUrl.\n", GetLastError()); } else { // Change the search information. // New info is the same length. urlComp.lpszExtraInfo = L"?RS=CHECKED&FORM=MSNH&v=1&q=winhttp"; // Obtain the size of the new URL and allocate memory. WinHttpCreateUrl( &urlComp, 0, NULL, &dwUrlLen); LPWSTR pwszUrl2 = new WCHAR[dwUrlLen]; // Create a new URL. if(!WinHttpCreateUrl( &urlComp, 0, pwszUrl2, &dwUrlLen)) { printf("Error %u in WinHttpCreateUrl.\n", GetLastError()); } else { // Show both URLs. printf("Old URL: %S\nNew URL: %S\n", pwszUrl1, pwszUrl2); } // Free allocated memory. delete [] pwszUrl2; }</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpcrackurl BOOL WinHttpCrackUrl( [in] LPCWSTR pwszUrl,
|
||
// [in] DWORD dwUrlLength, [in] DWORD dwFlags, [in, out] LPURL_COMPONENTS lpUrlComponents );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCrackUrl")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpCrackUrl([MarshalAs(UnmanagedType.LPWStr)] string pwszUrl, uint dwUrlLength, ICU dwFlags, ref WINHTTP_URL_COMPONENTS lpUrlComponents);
|
||
|
||
/// <summary>The <c>WinHttpCreateProxyResolver</c> function creates a handle for use by WinHttpGetProxyForUrlEx.</summary>
|
||
/// <param name="hSession">
|
||
/// Valid HINTERNET WinHTTP session handle returned by a previous call to WinHttpOpen. The session handle must be opened using <c>WINHTTP_FLAG_ASYNC</c>.
|
||
/// </param>
|
||
/// <param name="phResolver">
|
||
/// A pointer to a new handle for use by WinHttpGetProxyForUrlEx. When finished or cancelling an outstanding operation, close this
|
||
/// handle with WinHttpCloseHandle.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>The following codes may be returned.</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_SUCCESS</c></term>
|
||
/// <term>The operation succeeded.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_INVALID_HANDLE</c></term>
|
||
/// <term><c>hSession</c> is NULL.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term><c>hSession</c> is not the result of a call to WinHttpOpen or <c>hSession</c> is not marked as asynchronous using <c>WINHTTP_FLAG_ASYNC</c>.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpcreateproxyresolver WINHTTPAPI DWORD
|
||
// WinHttpCreateProxyResolver( [in] HINTERNET hSession, [out] HINTERNET *phResolver );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCreateProxyResolver")]
|
||
public static extern Win32Error WinHttpCreateProxyResolver(HINTERNET hSession, out SafeHINTERNET phResolver);
|
||
|
||
/// <summary>The <c>WinHttpCreateUrl</c> function creates a URL from component parts such as the host name and path.</summary>
|
||
/// <param name="lpUrlComponents">Pointer to a URL_COMPONENTS structure that contains the components from which to create the URL.</param>
|
||
/// <param name="dwFlags">
|
||
/// <para>Flags that control the operation of this function. This parameter can be one of the following values.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ICU_ESCAPE</c></term>
|
||
/// <term>
|
||
/// Converts all unsafe characters to their corresponding escape sequences in the path string pointed to by the <c>lpszUrlPath</c>
|
||
/// member and in <c>lpszExtraInfo</c> the extra-information string pointed to by the member of the URL_COMPONENTS structure pointed
|
||
/// to by the <c>lpUrlComponents</c> parameter.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ICU_REJECT_USERPWD</c></term>
|
||
/// <term>
|
||
/// Rejects URLs as input that contains either a username, or a password, or both. If the function fails because of an invalid URL,
|
||
/// subsequent calls to GetLastError will return ERROR_WINHTTP_INVALID_URL.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="pwszUrl">Pointer to a character buffer that receives the URL as a wide character (Unicode) string.</param>
|
||
/// <param name="pdwUrlLength">
|
||
/// Pointer to a variable of type unsigned long integer that receives the length of the <c>pwszUrl</c> buffer in wide (Unicode)
|
||
/// characters. When the function returns, this parameter receives the length of the URL string wide in characters, minus 1 for the
|
||
/// terminating character. If GetLastError returns ERROR_INSUFFICIENT_BUFFER, this parameter receives the number of wide characters
|
||
/// required to hold the created URL.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if the function succeeds, or <c>FALSE</c> otherwise. To get extended error data, call GetLastError. Among the
|
||
/// error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Insufficient memory available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode, that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen, this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error data, call GetLastError.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following example shows how to decompile, or crack, a URL into its subcomponents, update a component, then reconstruct the URL.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code> URL_COMPONENTS urlComp; LPCWSTR pwszUrl1 = L"http://search.msn.com/results.asp?RS=CHECKED&FORM=MSNH&v=1&q=wininet"; DWORD dwUrlLen = 0; // Initialize the URL_COMPONENTS structure. ZeroMemory(&urlComp, sizeof(urlComp)); urlComp.dwStructSize = sizeof(urlComp); // Set required component lengths to non-zero, // so that they are cracked. urlComp.dwSchemeLength = (DWORD)-1; urlComp.dwHostNameLength = (DWORD)-1; urlComp.dwUrlPathLength = (DWORD)-1; urlComp.dwExtraInfoLength = (DWORD)-1; // Crack the URL. if (!WinHttpCrackUrl( pwszUrl1, (DWORD)wcslen(pwszUrl1), 0, &urlComp)) { printf("Error %u in WinHttpCrackUrl.\n", GetLastError()); } else { // Change the search data. New data is the same length. urlComp.lpszExtraInfo = L"?RS=CHECKED&FORM=MSNH&v=1&q=winhttp"; // Obtain the size of the new URL and allocate memory. WinHttpCreateUrl( &urlComp, 0, NULL, &dwUrlLen); LPWSTR pwszUrl2 = new WCHAR[dwUrlLen]; // Create a new URL. if(!WinHttpCreateUrl( &urlComp, 0, pwszUrl2, &dwUrlLen)) { printf( "Error %u in WinHttpCreateUrl.\n", GetLastError()); } else { // Show both URLs. printf( "Old URL: %S\nNew URL: %S\n", pwszUrl1, pwszUrl2); } // Free allocated memory. delete [] pwszUrl2; }</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpcreateurl BOOL WinHttpCreateUrl( [in]
|
||
// LPURL_COMPONENTS lpUrlComponents, [in] DWORD dwFlags, [out] LPWSTR pwszUrl, [in, out] LPDWORD pdwUrlLength );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCreateUrl")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpCreateUrl(in WINHTTP_URL_COMPONENTS_IN lpUrlComponents, ICU dwFlags,
|
||
[Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszUrl, ref uint pdwUrlLength);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpDetectAutoProxyConfigUrl</c> function finds the URL for the Proxy Auto-Configuration (PAC) file. This function
|
||
/// reports the URL of the PAC file, but it does not download the file.
|
||
/// </summary>
|
||
/// <param name="dwAutoDetectFlags">
|
||
/// <para>
|
||
/// A data type that specifies what protocols to use to locate the PAC file. If both the DHCP and DNS auto detect flags are set, DHCP
|
||
/// is used first; if no PAC URL is discovered using DHCP, then DNS is used.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTO_DETECT_TYPE_DHCP</c></term>
|
||
/// <term>Use DHCP to locate the proxy auto-configuration file.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTO_DETECT_TYPE_DNS_A</c></term>
|
||
/// <term>Use DNS to attempt to locate the proxy auto-configuration file at a well-known location on the domain of the local computer.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="ppwstrAutoConfigUrl">
|
||
/// A data type that returns a pointer to a null-terminated Unicode string that contains the configuration URL that receives the
|
||
/// proxy data. You must free the string pointed to by <c>ppwszAutoConfigUrl</c> using the GlobalFree function.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise. For extended error information, call GetLastError. Among the error
|
||
/// codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_AUTODETECTION_FAILED</c></term>
|
||
/// <term>Returned if WinHTTP was unable to discover the URL of the Proxy Auto-Configuration (PAC) file.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// WinHTTP implements the Web Proxy Auto-Discovery (WPAD) protocol, often referred to as <c>autoproxy</c>. For more information
|
||
/// about well-known locations, see the Discovery Process section of the WPAD protocol document.
|
||
/// </para>
|
||
/// <para>
|
||
/// Note that because the <c>WinHttpDetectAutoProxyConfigUrl</c> function takes time to complete its operation, it should not be
|
||
/// called from a UI thread.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpdetectautoproxyconfigurl BOOL
|
||
// WinHttpDetectAutoProxyConfigUrl( [in] DWORD dwAutoDetectFlags, [out] LPWSTR *ppwstrAutoConfigUrl );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpDetectAutoProxyConfigUrl")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpDetectAutoProxyConfigUrl(WINHTTP_AUTO_DETECT_TYPE dwAutoDetectFlags, out SafeHGlobalHandle ppwstrAutoConfigUrl);
|
||
|
||
/// <summary>The <c>WinHttpFreeProxyResult</c> function frees the data retrieved from a previous call to <see cref="WinHttpGetProxyResult"/>.</summary>
|
||
/// <param name="pProxyResult">A pointer to a WINHTTP_PROXY_RESULT structure retrieved from a previous call to WinHttpGetProxyResult.</param>
|
||
/// <returns>This function does not return a value.</returns>
|
||
/// <remarks>
|
||
/// Upon completion, all internal members of <c>pProxyResult</c> will be zeroed and the memory allocated to those members will be
|
||
/// freed. If <c>pProxyResult</c> is an allocated pointer, the caller must free the pointer.
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpfreeproxyresult WINHTTPAPI VOID
|
||
// WinHttpFreeProxyResult( [in, out] WINHTTP_PROXY_RESULT *pProxyResult );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpFreeProxyResult")]
|
||
public static extern void WinHttpFreeProxyResult(ref WINHTTP_PROXY_RESULT pProxyResult);
|
||
|
||
/// <summary>Frees the memory allocated by a previous call to WinHttpQueryConnectionGroup.</summary>
|
||
/// <param name="pResult">
|
||
/// <para>Type: _Inout_ <c>WINHTTP_QUERY_CONNECTION_GROUP_RESULT*</c></para>
|
||
/// <para>A pointer to the WINHTTP_QUERY_CONNECTION_GROUP_RESULT object to free.</para>
|
||
/// </param>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpfreequeryconnectiongroupresult WINHTTPAPI VOID
|
||
// WinHttpFreeQueryConnectionGroupResult( WINHTTP_QUERY_CONNECTION_GROUP_RESULT *pResult );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpFreeQueryConnectionGroupResult")]
|
||
public static extern void WinHttpFreeQueryConnectionGroupResult(IntPtr pResult);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpGetDefaultProxyConfiguration</c> function retrieves the default WinHTTP proxy configuration from the registry.
|
||
/// </summary>
|
||
/// <param name="pProxyInfo">A pointer to a variable of type WINHTTP_PROXY_INFO that receives the default proxy configuration.</param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful or <c>FALSE</c> otherwise. To retrieve a specific error message, call GetLastError. Error codes
|
||
/// returned include the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// <c>WinHttpGetDefaultProxyConfiguration</c> retrieves the proxy configuration set by WinHttpSetDefaultProxyConfiguration or ProxyCfg.exe.
|
||
/// </para>
|
||
/// <para>
|
||
/// The default proxy configuration can be overridden for a WinHTTP session by calling WinHttpSetOption and specifying the
|
||
/// WINHTTP_OPTION_PROXY flag. <c>WinHttpGetDefaultProxyConfiguration</c> does not retrieve the configuration for the current
|
||
/// session. It retrieves the configuration specified in the registry.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the registry contains a list of proxy servers, the <c>dwAccessType</c> member of <c>pProxyInfo</c> is set to
|
||
/// <c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c>. Otherwise, it is set to <c>WINHTTP_ACCESS_TYPE_NO_PROXY</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpGetDefaultProxyConfiguration</c> allocates memory for the string members of <c>pProxyInfo</c>. To free this memory,
|
||
/// call GlobalFree.
|
||
/// </para>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP Start Page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>The following code example shows how to retrieve the default proxy configuration from the registry.</para>
|
||
/// <para>
|
||
/// <code> WINHTTP_PROXY_INFO proxyInfo; // Retrieve the default proxy configuration. WinHttpGetDefaultProxyConfiguration( &proxyInfo ); // Display the proxy servers and free memory // allocated to this string. if (proxyInfo.lpszProxy != NULL) { printf("Proxy server list: %S\n", proxyInfo.lpszProxy); GlobalFree( proxyInfo.lpszProxy ); } // Display the bypass list and free memory // allocated to this string. if (proxyInfo.lpszProxyBypass != NULL) { printf("Proxy bypass list: %S\n", proxyInfo.lpszProxyBypass); GlobalFree( proxyInfo.lpszProxyBypass ); }</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetdefaultproxyconfiguration WINHTTPAPI BOOL
|
||
// WinHttpGetDefaultProxyConfiguration( [in, out] WINHTTP_PROXY_INFO *pProxyInfo );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetDefaultProxyConfiguration")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpGetDefaultProxyConfiguration(out WINHTTP_PROXY_INFO pProxyInfo);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpGetIEProxyConfigForCurrentUser</c> function retrieves the Internet Explorer proxy configuration for the current user.
|
||
/// </summary>
|
||
/// <param name="pProxyConfig">
|
||
/// A pointer, on input, to a WINHTTP_CURRENT_USER_IE_PROXY_CONFIG structure. On output, the structure contains the Internet Explorer
|
||
/// proxy settings for the current active network connection (for example, LAN, dial-up, or VPN connection).
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise. For extended error information, call GetLastError. Among the error
|
||
/// codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_FILE_NOT_FOUND</c></term>
|
||
/// <term>No Internet Explorer proxy settings can be found.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// In Internet Explorer, the proxy settings are found on the <c>Connections</c> tab of the <c>Tools</c> / <c>Internet Options</c>
|
||
/// menu option. Proxy settings are configured on a per-connection basis; that is, the proxy settings for a LAN connection are
|
||
/// separate from those for a dial-up or VPN connection. <c>WinHttpGetIEProxyConfigForCurrentUser</c> returns the proxy settings for
|
||
/// the current active connection.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function is useful in client applications running in network environments in which the Web Proxy Auto-Discovery (WPAD)
|
||
/// protocol is not implemented (meaning that no Proxy Auto-Configuration file is available). If a PAC file is not available, then
|
||
/// the WinHttpGetProxyForUrl function fails. The <c>WinHttpGetIEProxyConfigForCurrentUser</c> function can be used as a fall-back
|
||
/// mechanism to discover a workable proxy configuration by retrieving the user's proxy configuration in Internet Explorer.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function should not be used in a service process that does not impersonate a logged-on user.If the caller does not
|
||
/// impersonate a logged on user, WinHTTP attempts to retrieve the Internet Explorer settings for the current service process: for
|
||
/// example, the local service or the network service. If the Internet Explorer settings are not configured for these system
|
||
/// accounts, the call to <c>WinHttpGetIEProxyConfigForCurrentUser</c> will fail.
|
||
/// </para>
|
||
/// <para>
|
||
/// The caller must free the <c>lpszProxy</c>, <c>lpszProxyBypass</c> and <c>lpszAutoConfigUrl</c> strings in the
|
||
/// WINHTTP_CURRENT_USER_IE_PROXY_CONFIG structure if they are non- <c>NULL</c>. Use GlobalFree to free the strings.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetieproxyconfigforcurrentuser BOOL
|
||
// WinHttpGetIEProxyConfigForCurrentUser( [in, out] WINHTTP_CURRENT_USER_IE_PROXY_CONFIG *pProxyConfig );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetIEProxyConfigForCurrentUser")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpGetIEProxyConfigForCurrentUser(out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG pProxyConfig);
|
||
|
||
/// <summary>The <c>WinHttpGetProxyForUrl</c> function retrieves the proxy data for the specified URL.</summary>
|
||
/// <param name="hSession">The WinHTTP session handle returned by the WinHttpOpen function.</param>
|
||
/// <param name="lpcwszUrl">
|
||
/// A pointer to a null-terminated Unicode string that contains the URL of the HTTP request that the application is preparing to send.
|
||
/// </param>
|
||
/// <param name="pAutoProxyOptions">
|
||
/// A pointer to a WINHTTP_AUTOPROXY_OPTIONS structure that specifies the auto-proxy options to use.
|
||
/// </param>
|
||
/// <param name="pProxyInfo">
|
||
/// A pointer to a WINHTTP_PROXY_INFO structure that receives the proxy setting. This structure is then applied to the request handle
|
||
/// using the WINHTTP_OPTION_PROXY option. Free the <c>lpszProxy</c> and <c>lpszProxyBypass</c> strings contained in this structure
|
||
/// (if they are non-NULL) using the GlobalFree function.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
|
||
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error data, call GetLastError.</para>
|
||
/// <para>Possible error codes include the folllowing.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR</c></term>
|
||
/// <term>Returned by WinHttpGetProxyForUrl when a proxy for the specified URL cannot be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT</c></term>
|
||
/// <term>An error occurred executing the script code in the Proxy Auto-Configuration (PAC) file.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INVALID_URL</c></term>
|
||
/// <term>The URL is invalid.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_LOGIN_FAILURE</c></term>
|
||
/// <term>
|
||
/// The login attempt failed. When this error is encountered, close the request handle with WinHttpCloseHandle. A new request handle
|
||
/// must be created before retrying the function that originally produced this error.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_OPERATION_CANCELLED</c></term>
|
||
/// <term>
|
||
/// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT</c></term>
|
||
/// <term>
|
||
/// The PAC file could not be downloaded. For example, the server referenced by the PAC URL may not have been reachable, or the
|
||
/// server returned a 404 NOT FOUND response.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNRECOGNIZED_SCHEME</c></term>
|
||
/// <term>The URL of the PAC file specified a scheme other than "http:" or "https:".</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// This function implements the Web Proxy Auto-Discovery (WPAD) protocol for automatically configuring the proxy settings for an
|
||
/// HTTP request. The WPAD protocol downloads a Proxy Auto-Configuration (PAC) file, which is a script that identifies the proxy
|
||
/// server to use for a given target URL. PAC files are typically deployed by the IT department within a corporate network
|
||
/// environment. The URL of the PAC file can either be specified explicitly or <c>WinHttpGetProxyForUrl</c> can be instructed to
|
||
/// automatically discover the location of the PAC file on the local network.
|
||
/// </para>
|
||
/// <para><c>WinHttpGetProxyForUrl</c> supports only ECMAScript-based PAC files.</para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrl</c> must be called on a per-URL basis, because the PAC file can return a different proxy server for
|
||
/// different URLs. This is useful because the PAC file enables an IT department to implement proxy server load balancing by mapping
|
||
/// (hashing) the target URL (specified by the <c>lpcwszUrl</c> parameter) to a certain proxy in a proxy server array.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrl</c> caches the autoproxy URL and the autoproxy script when auto-discovery is specified in the
|
||
/// <c>dwFlags</c> member of the <c>pAutoProxyOptions</c> structure. For more information, see Autoproxy Cache.
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxyforurl BOOL WinHttpGetProxyForUrl( [in]
|
||
// HINTERNET hSession, [in] LPCWSTR lpcwszUrl, [in] WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, [out] WINHTTP_PROXY_INFO
|
||
// *pProxyInfo );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxyForUrl")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpGetProxyForUrl(HINTERNET hSession, [MarshalAs(UnmanagedType.LPWStr)] string lpcwszUrl,
|
||
in WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions, out WINHTTP_PROXY_INFO pProxyInfo);
|
||
|
||
/// <summary>The <c>WinHttpGetProxyForUrlEx</c> function retrieves the proxy data for the specified URL.</summary>
|
||
/// <param name="hResolver">The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function.</param>
|
||
/// <param name="pcwszUrl">
|
||
/// A pointer to a null-terminated Unicode string that contains a URL for which proxy information will be determined.
|
||
/// </param>
|
||
/// <param name="pAutoProxyOptions">
|
||
/// A pointer to a WINHTTP_AUTOPROXY_OPTIONS structure that specifies the auto-proxy options to use.
|
||
/// </param>
|
||
/// <param name="pContext">Context data that will be passed to the completion callback function.</param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>The following codes may be returned.</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_IO_PENDING</c></term>
|
||
/// <term>The operation is continuing asynchronously.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR</c></term>
|
||
/// <term>Returned by WinHttpGetProxyForUrlEx when a proxy for the specified URL cannot be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT</c></term>
|
||
/// <term>An error occurred executing the script code in the Proxy Auto-Configuration (PAC) file.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INVALID_URL</c></term>
|
||
/// <term>The URL is invalid.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_OPERATION_CANCELLED</c></term>
|
||
/// <term>
|
||
/// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT</c></term>
|
||
/// <term>
|
||
/// The PAC file could not be downloaded. For example, the server referenced by the PAC URL may not have been reachable, or the
|
||
/// server returned a 404 NOT FOUND response.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNRECOGNIZED_SCHEME</c></term>
|
||
/// <term>The URL of the PAC file specified a scheme other than "http:" or "https:".</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// This function implements the Web Proxy Auto-Discovery (WPAD) protocol for automatically configuring the proxy settings for an
|
||
/// HTTP request. The WPAD protocol downloads a Proxy Auto-Configuration (PAC) file, which is a script that identifies the proxy
|
||
/// server to use for a given target URL. PAC files are typically deployed by the IT department within a corporate network
|
||
/// environment. The URL of the PAC file can either be specified explicitly or <c>WinHttpGetProxyForUrlEx</c> can be instructed to
|
||
/// automatically discover the location of the PAC file on the local network.
|
||
/// </para>
|
||
/// <para><c>WinHttpGetProxyForUrlEx</c> supports only ECMAScript-based PAC files.</para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrlEx</c> must be called on a per-URL basis, because the PAC file can return a different proxy server for
|
||
/// different URLs. This is useful because the PAC file enables an IT department to implement proxy server load balancing by mapping
|
||
/// (hashing) the target URL (specified by the <c>lpcwszUrl</c> parameter) to a certain proxy in a proxy server array.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrlEx</c> caches the autoproxy URL and the autoproxy script when auto-discovery is specified in the
|
||
/// <c>dwFlags</c> member of the <c>pAutoProxyOptions</c> structure. For more information, see Autoproxy Cache.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrlEx</c> provides a fully Asynchronous and cancellable API that WinHttpGetProxyForUrl does not.
|
||
/// <c>WinHttpGetProxyForUrlEx</c> also provides the application with the full proxy list that was returned by the PAC script
|
||
/// allowing the application to better handle failover to "DIRECT" and to understand SOCKS if desired.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>WinHttpGetProxyForUrlEx</c> always executes asynchronously and returns immediately with <c>ERROR_IO_PENDING</c> on success.
|
||
/// The callback is set by calling WinHttpSetStatusCallback on the <c>hSession</c> provided by WinHttpOpen. Alternately call
|
||
/// <c>WinHttpSetStatusCallback</c> on the <c>hResolver</c> provided by WinHttpCreateProxyResolver to have a specific callback for
|
||
/// each call.
|
||
/// </para>
|
||
/// <para>
|
||
/// You must call WinHttpSetStatusCallback before WinHttpCreateProxyResolver. When calling <c>WinHttpSetStatusCallback</c>, use
|
||
/// <c>WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE</c>. See WINHTTP_STATUS_CALLBACK for
|
||
/// information on the use of the callback.
|
||
/// </para>
|
||
/// <para>
|
||
/// Once a callback of status <c>WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE</c> is returned, the application can call
|
||
/// WinHttpGetProxyResult on the resolver handle used to issue <c>WinHttpGetProxyForUrlEx</c> to receive the results of that call.
|
||
/// </para>
|
||
/// <para>
|
||
/// If the call fails after returning <c>ERROR_IO_PENDING</c> then a callback of <c>WINHTTP_CALLBACK_STATUS_REQUEST_ERROR</c> will be issued.
|
||
/// </para>
|
||
/// <para>This function always executes out-of-process.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxyforurlex WINHTTPAPI DWORD
|
||
// WinHttpGetProxyForUrlEx( [in] HINTERNET hResolver, [in] PCWSTR pcwszUrl, [in] WINHTTP_AUTOPROXY_OPTIONS *pAutoProxyOptions, [in]
|
||
// DWORD_PTR pContext );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxyForUrlEx")]
|
||
public static extern Win32Error WinHttpGetProxyForUrlEx(HINTERNET hResolver, [MarshalAs(UnmanagedType.LPWStr)] string pcwszUrl,
|
||
in WINHTTP_AUTOPROXY_OPTIONS pAutoProxyOptions, [In, Optional] IntPtr pContext);
|
||
|
||
/// <summary>The <c>WinHttpGetProxyResult</c> function retrieves the results of a call to WinHttpGetProxyForUrlEx.</summary>
|
||
/// <param name="hResolver">The resolver handle used to issue a previously completed call to WinHttpGetProxyForUrlEx.</param>
|
||
/// <param name="pProxyResult">
|
||
/// A pointer to a WINHTTP_PROXY_RESULT structure that contains the results of a previous call to WinHttpGetProxyForUrlEx. The
|
||
/// results must be freed by calling WinHttpFreeProxyResult.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>The following codes may be returned.</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The resolver handle has not successfully completed a call to WinHttpGetProxyForUrlEx.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxyresult WINHTTPAPI DWORD
|
||
// WinHttpGetProxyResult( [in] HINTERNET hResolver, [out] WINHTTP_PROXY_RESULT *pProxyResult );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxyResult")]
|
||
public static extern Win32Error WinHttpGetProxyResult(HINTERNET hResolver, out WINHTTP_PROXY_RESULT pProxyResult);
|
||
|
||
/// <summary>
|
||
/// The <c>WinHttpOpen</c> function initializes, for an application, the use of WinHTTP functions and returns a WinHTTP-session handle.
|
||
/// </summary>
|
||
/// <param name="pszAgentW">
|
||
/// A pointer to a string variable that contains the name of the application or entity calling the WinHTTP functions. This name is
|
||
/// used as the user agent in the HTTP protocol.
|
||
/// </param>
|
||
/// <param name="dwAccessType">
|
||
/// <para>Type of access required. This can be one of the following values.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ACCESS_TYPE_NO_PROXY</c></term>
|
||
/// <term>Resolves all host names directly without a proxy.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ACCESS_TYPE_DEFAULT_PROXY</c></term>
|
||
/// <term>
|
||
/// Retrieves the static proxy or direct configuration from the registry. <c>WINHTTP_ACCESS_TYPE_DEFAULT_PROXY</c> does not inherit
|
||
/// browser proxy settings. The WinHTTP proxy configuration is set by one of these mechanisms.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c></term>
|
||
/// <term>
|
||
/// Passes requests to the proxy unless a proxy bypass list is supplied and the name to be resolved bypasses the proxy. In this case,
|
||
/// this function uses the values passed for <c>pwszProxyName</c> and <c>pwszProxyBypass</c>.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY</c></term>
|
||
/// <term>
|
||
/// Uses system and per-user proxy settings (including the Internet Explorer proxy configuration) to determine which proxy/proxies to
|
||
/// use. Automatically attempts to handle failover between multiple proxies, different proxy configurations per interface, and
|
||
/// authentication. Supported in Windows 8.1 and newer.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="pszProxyW">
|
||
/// A pointer to a string variable that contains the name of the proxy server to use when proxy access is specified by setting
|
||
/// <c>dwAccessType</c> to <c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c>. The WinHTTP functions recognize only CERN type proxies for HTTP.
|
||
/// If <c>dwAccessType</c> is not set to <c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c>, this parameter must be set to <c>WINHTTP_NO_PROXY_NAME</c>.
|
||
/// </param>
|
||
/// <param name="pszProxyBypassW">
|
||
/// A pointer to a string variable that contains an optional semicolon delimited list of host names or IP addresses, or both, that
|
||
/// should not be routed through the proxy when <c>dwAccessType</c> is set to <c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c>. The list can
|
||
/// contain wildcard characters. Do not use an empty string, because the <c>WinHttpOpen</c> function uses it as the proxy bypass
|
||
/// list. If this parameter specifies the "<local>" macro in the list as the only entry, this function bypasses any host name
|
||
/// that does not contain a period. If <c>dwAccessType</c> is not set to <c>WINHTTP_ACCESS_TYPE_NAMED_PROXY</c>, this parameter must
|
||
/// be set to <c>WINHTTP_NO_PROXY_BYPASS</c>.
|
||
/// </param>
|
||
/// <param name="dwFlags">
|
||
/// <para>
|
||
/// Unsigned long integer value that contains the flags that indicate various options affecting the behavior of this function. This
|
||
/// parameter can have the following value.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_ASYNC</c></term>
|
||
/// <term>
|
||
/// Use the WinHTTP functions asynchronously. By default, all WinHTTP functions that use the returned HINTERNET handle are performed
|
||
/// synchronously. When this flag is set, the caller needs to specify a callback function through WinHttpSetStatusCallback.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_SECURE_DEFAULTS</c></term>
|
||
/// <term>
|
||
/// When this flag is set, WinHttp will require use of TLS 1.2 or newer. If the caller attempts to enable older TLS versions by
|
||
/// setting <c>WINHTTP_OPTION_SECURE_PROTOCOLS</c>, it will fail with <c>ERROR_ACCESS_DENIED</c>. Additionally, TLS fallback will be
|
||
/// disabled. Note that setting this flag also sets flag <c>WINHTTP_FLAG_ASYNC</c>.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns a valid session handle if successful, or <c>NULL</c> otherwise. To retrieve extended error information, call
|
||
/// GetLastError. Among the error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// We strongly recommend that you use WinHTTP in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in
|
||
/// <c>WinHttpOpen</c>, so that usage of the returned HINTERNET become asynchronous). The return value indicates success or failure.
|
||
/// To retrieve extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// The <c>WinHttpOpen</c> function is the first of the WinHTTP functions called by an application. It initializes internal WinHTTP
|
||
/// data structures and prepares for future calls from the application. When the application finishes using the WinHTTP functions, it
|
||
/// must call WinHttpCloseHandle to free the session handle and any associated resources.
|
||
/// </para>
|
||
/// <para>
|
||
/// The application can make any number of calls to <c>WinHttpOpen</c>, though a single call is normally sufficient. Each call to
|
||
/// <c>WinHttpOpen</c> opens a new session context. Because user data is not shared between multiple session contexts, an application
|
||
/// that makes requests on behalf of multiple users should create a separate session for each user, so as not to share user-specific
|
||
/// cookies and authentication state. The application should define separate behaviors for each <c>WinHttpOpen</c> instance, such as
|
||
/// different proxy servers configured for each.
|
||
/// </para>
|
||
/// <para>
|
||
/// After the calling application has finished using the HINTERNET handle returned by <c>WinHttpOpen</c>, it must be closed using the
|
||
/// WinHttpCloseHandle function.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see Run-Time Requirements.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>The following example code shows how to retrieve the default connection time-out value.</para>
|
||
/// <para>
|
||
/// <code> 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()); }</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpopen WINHTTPAPI HINTERNET WinHttpOpen( [in, optional]
|
||
// LPCWSTR pszAgentW, [in] DWORD dwAccessType, [in] LPCWSTR pszProxyW, [in] LPCWSTR pszProxyBypassW, [in] DWORD dwFlags );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpOpen")]
|
||
public static extern SafeHINTERNET WinHttpOpen([Optional, MarshalAs(UnmanagedType.LPWStr)] string pszAgentW, [Optional] WINHTTP_ACCESS_TYPE dwAccessType,
|
||
[Optional, MarshalAs(UnmanagedType.LPWStr)] string pszProxyW, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pszProxyBypassW, [Optional] WINHTTP_OPEN_FLAG dwFlags);
|
||
|
||
/// <summary>The <c>WinHttpOpenRequest</c> function creates an HTTP request handle.</summary>
|
||
/// <param name="hConnect">HINTERNET connection handle to an HTTP session returned by WinHttpConnect.</param>
|
||
/// <param name="pwszVerb">
|
||
/// Pointer to a string that contains the HTTP verb to use in the request. If this parameter is <c>NULL</c>, the function uses GET as
|
||
/// the <c>HTTP verb</c>. <c>Note</c> This string should be all uppercase. Many servers treat HTTP verbs as case-sensitive, and the
|
||
/// Internet Engineering Task Force (IETF) Requests for Comments (RFCs) spell these verbs using uppercase characters only.
|
||
/// </param>
|
||
/// <param name="pwszObjectName">
|
||
/// Pointer to a string that contains the name of the target resource of the specified HTTP verb. This is generally a file name, an
|
||
/// executable module, or a search specifier.
|
||
/// </param>
|
||
/// <param name="pwszVersion">
|
||
/// Pointer to a string that contains the HTTP version. If this parameter is <c>NULL</c>, the function uses HTTP/1.1.
|
||
/// </param>
|
||
/// <param name="pwszReferrer">
|
||
/// Pointer to a string that specifies the URL of the document from which the URL in the request <c>pwszObjectName</c> was obtained.
|
||
/// If this parameter is set to <c>WINHTTP_NO_REFERER</c>, no referring document is specified.
|
||
/// </param>
|
||
/// <param name="ppwszAcceptTypes">
|
||
/// Pointer to a <c>null</c>-terminated array of string pointers that specifies media types accepted by the client. If this parameter
|
||
/// is set to <c>WINHTTP_DEFAULT_ACCEPT_TYPES</c>, no types are accepted by the client. Typically, servers handle a lack of accepted
|
||
/// types as indication that the client accepts only documents of type "text/*"; that is, only text documents<74>no pictures or other
|
||
/// binary files. For a list of valid media types, see Media Types defined by IANA at http://www.iana.org/assignments/media-types/.
|
||
/// </param>
|
||
/// <param name="dwFlags">
|
||
/// <para>Unsigned long integer value that contains the Internet flag values. This can be one or more of the following values:</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_BYPASS_PROXY_CACHE</c></term>
|
||
/// <term>This flag provides the same behavior as <c>WINHTTP_FLAG_REFRESH</c>.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_ESCAPE_DISABLE</c></term>
|
||
/// <term>Unsafe characters in the URL passed in for <c>pwszObjectName</c> are not converted to escape sequences.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_ESCAPE_DISABLE_QUERY</c></term>
|
||
/// <term>Unsafe characters in the query component of the URL passed in for <c>pwszObjectName</c> are not converted to escape sequences.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_ESCAPE_PERCENT</c></term>
|
||
/// <term>
|
||
/// The string passed in for <c>pwszObjectName</c> is converted from an <c>LPCWSTR</c> to an <c>LPSTR</c>. All unsafe characters are
|
||
/// converted to an escape sequence including the percent symbol. By default, all unsafe characters except the percent symbol are
|
||
/// converted to an escape sequence.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_NULL_CODEPAGE</c></term>
|
||
/// <term>
|
||
/// The string passed in for <c>pwszObjectName</c> is assumed to consist of valid ANSI characters represented by <c>WCHAR</c>. No
|
||
/// check are done for unsafe characters. <c>Windows 7:</c> This option is obsolete.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_REFRESH</c></term>
|
||
/// <term>
|
||
/// Indicates that the request should be forwarded to the originating server rather than sending a cached version of a resource from
|
||
/// a proxy server. When this flag is used, a "Pragma: no-cache" header is added to the request handle. When creating an HTTP/1.1
|
||
/// request header, a "Cache-Control: no-cache" is also added.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_FLAG_SECURE</c></term>
|
||
/// <term>Uses secure transaction semantics. This translates to using Secure Sockets Layer (SSL)/Transport Layer Security (TLS).</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns a valid HTTP request handle if successful, or <c>NULL</c> if not. For extended error information, call GetLastError.
|
||
/// Among the error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INVALID_URL</c></term>
|
||
/// <term>The URL is invalid.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_OPERATION_CANCELLED</c></term>
|
||
/// <term>
|
||
/// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_UNRECOGNIZED_SCHEME</c></term>
|
||
/// <term>The URL specified a scheme other than "http:" or "https:".</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>The return value indicates success or failure. To get extended error information, call GetLastError.</para>
|
||
/// <para>
|
||
/// The <c>WinHttpOpenRequest</c> function creates a new HTTP request handle and stores the specified parameters in that handle. An
|
||
/// HTTP request handle holds a request to send to an HTTP server and contains all RFC822/MIME/HTTP headers to be sent as part of the request.
|
||
/// </para>
|
||
/// <para>If <c>pwszVerb</c> is set to "HEAD", the Content-Length header is ignored.</para>
|
||
/// <para>
|
||
/// If a status callback function has been installed with WinHttpSetStatusCallback, then a
|
||
/// <c>WINHTTP_CALLBACK_STATUS_HANDLE_CREATED</c> notification indicates that <c>WinHttpOpenRequest</c> has created a request handle.
|
||
/// </para>
|
||
/// <para>
|
||
/// After the calling application finishes using the HINTERNET handle returned by <c>WinHttpOpenRequest</c>, it must be closed using
|
||
/// the WinHttpCloseHandle function.
|
||
/// </para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// This example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that header to the server.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code> 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 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);</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpopenrequest WINHTTPAPI HINTERNET WinHttpOpenRequest(
|
||
// [in] HINTERNET hConnect, [in] LPCWSTR pwszVerb, [in] LPCWSTR pwszObjectName, [in] LPCWSTR pwszVersion, [in] LPCWSTR pwszReferrer,
|
||
// [in] LPCWSTR *ppwszAcceptTypes, [in] DWORD dwFlags );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpOpenRequest")]
|
||
public static extern SafeHINTERNET WinHttpOpenRequest(HINTERNET hConnect, [MarshalAs(UnmanagedType.LPWStr)] string pwszVerb,
|
||
[Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszObjectName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszVersion,
|
||
[Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszReferrer,
|
||
[In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] ppwszAcceptTypes, [Optional] WINHTTP_OPENREQ_FLAG dwFlags);
|
||
|
||
/// <summary>The <c>WinHttpQueryAuthSchemes</c> function returns the authorization schemes that are supported by the server.</summary>
|
||
/// <param name="hRequest">Valid HINTERNET handle returned by WinHttpOpenRequest</param>
|
||
/// <param name="lpdwSupportedSchemes">
|
||
/// <para>
|
||
/// An unsigned integer that specifies a flag that contains the supported authentication schemes. This parameter can return one or
|
||
/// more flags that are identified in the following table.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_BASIC</c></term>
|
||
/// <term>Indicates basic authentication is available.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_NTLM</c></term>
|
||
/// <term>Indicates NTLM authentication is available.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_PASSPORT</c></term>
|
||
/// <term>Indicates passport authentication is available.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_DIGEST</c></term>
|
||
/// <term>Indicates digest authentication is available.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_NEGOTIATE</c></term>
|
||
/// <term>Selects between NTLM and Kerberos authentication.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="lpdwFirstScheme">
|
||
/// <para>
|
||
/// An unsigned integer that specifies a flag that contains the first authentication scheme listed by the server. This parameter can
|
||
/// return one or more flags that are identified in the following table.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_BASIC</c></term>
|
||
/// <term>Indicates basic authentication is first.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_NTLM</c></term>
|
||
/// <term>Indicates NTLM authentication is first.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_PASSPORT</c></term>
|
||
/// <term>Indicates passport authentication is first.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_DIGEST</c></term>
|
||
/// <term>Indicates digest authentication is first.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_SCHEME_NEGOTIATE</c></term>
|
||
/// <term>Selects between NTLM and Kerberos authentication.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="pdwAuthTarget">
|
||
/// <para>
|
||
/// An unsigned integer that specifies a flag that contains the authentication target. This parameter can return one or more flags
|
||
/// that are identified in the following table.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Value</term>
|
||
/// <term>Meaning</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_TARGET_SERVER</c></term>
|
||
/// <term>Authentication target is a server. Indicates that a 401 status code has been received.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>WINHTTP_AUTH_TARGET_PROXY</c></term>
|
||
/// <term>Authentication target is a proxy. Indicates that a 407 status code has been received.</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> if unsuccessful. To get extended error information, call GetLastError. The
|
||
/// following table identifies the error codes that are returned.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> is set in WinHttpOpen), this function
|
||
/// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para><c>WinHttpQueryAuthSchemes</c> cannot be used before calling WinHttpQueryHeaders.</para>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000 see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following example shows how to retrieve a specified document from an HTTP server when authentication is required. The status
|
||
/// code is retrieved from the response to determine if the server or proxy is requesting authentication. If a 200 status code is
|
||
/// found, the document is available. If a status code of 401 or 407 is found, authentication is required before the document can be
|
||
/// retrieved. For any other status code an error message is displayed.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code>#include <windows.h> #include <winhttp.h> #include <stdio.h> #pragma comment(lib, "winhttp.lib") DWORD ChooseAuthScheme( DWORD dwSupportedSchemes ) { // It is the server's responsibility only to accept // authentication schemes that provide a sufficient level // of security to protect the server's resources. // // The client is also obligated only to use an authentication // scheme that adequately protects its username and password. // // Thus, this sample code does not use Basic authentication // because Basic authentication exposes the client's username // and password to anyone monitoring the connection. if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NEGOTIATE ) return WINHTTP_AUTH_SCHEME_NEGOTIATE; else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_NTLM ) return WINHTTP_AUTH_SCHEME_NTLM; else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_PASSPORT ) return WINHTTP_AUTH_SCHEME_PASSPORT; else if( dwSupportedSchemes & WINHTTP_AUTH_SCHEME_DIGEST ) return WINHTTP_AUTH_SCHEME_DIGEST; else return 0; } struct SWinHttpSampleGet { LPCWSTR szServer; LPCWSTR szPath; BOOL fUseSSL; LPCWSTR szServerUsername; LPCWSTR szServerPassword; LPCWSTR szProxyUsername; LPCWSTR szProxyPassword; }; void WinHttpAuthSample( IN SWinHttpSampleGet *pGetRequest ) { DWORD dwStatusCode = 0; DWORD dwSupportedSchemes; DWORD dwFirstScheme; DWORD dwSelectedScheme; DWORD dwTarget; DWORD dwLastStatus = 0; DWORD dwSize = sizeof(DWORD); BOOL bResults = FALSE; BOOL bDone = FALSE; DWORD dwProxyAuthScheme = 0; 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 ); INTERNET_PORT nPort = ( pGetRequest->fUseSSL ) ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT; // Specify an HTTP server. if( hSession ) hConnect = WinHttpConnect( hSession, pGetRequest->szServer, nPort, 0 ); // Create an HTTP request handle. if( hConnect ) hRequest = WinHttpOpenRequest( hConnect, L"GET", pGetRequest->szPath, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, ( pGetRequest->fUseSSL ) ? WINHTTP_FLAG_SECURE : 0 ); // Continue to send a request until status code is not 401 or 407. if( hRequest == NULL ) bDone = TRUE; while( !bDone ) { // If a proxy authentication challenge was responded to, reset // those credentials before each SendRequest, because the proxy // may require re-authentication after responding to a 401 or to // a redirect. If you don't, you can get into a 407-401-407-401 // loop. if( dwProxyAuthScheme != 0 ) bResults = WinHttpSetCredentials( hRequest, WINHTTP_AUTH_TARGET_PROXY, dwProxyAuthScheme, pGetRequest->szProxyUsername, pGetRequest->szProxyPassword, NULL ); // Send a request. bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0 ); // End the request. if( bResults ) bResults = WinHttpReceiveResponse( hRequest, NULL ); // Resend the request in case of // ERROR_WINHTTP_RESEND_REQUEST error. if( !bResults && GetLastError( ) == ERROR_WINHTTP_RESEND_REQUEST) continue; // Check the status code. if( bResults ) bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &dwStatusCode, &dwSize, NULL ); if( bResults ) { switch( dwStatusCode ) { case 200: // The resource was successfully retrieved. // You can use WinHttpReadData to read the contents // of the server's response. printf( "The resource was successfully retrieved.\n" ); bDone = TRUE; break; case 401: // The server requires authentication. printf( "The server requires authentication. Sending credentials\n"); // Obtain the supported and preferred schemes. bResults = WinHttpQueryAuthSchemes( hRequest, &dwSupportedSchemes, &dwFirstScheme, &dwTarget ); // Set the credentials before re-sending the request. if( bResults ) { dwSelectedScheme = ChooseAuthScheme( dwSupportedSchemes ); if( dwSelectedScheme == 0 ) bDone = TRUE; else bResults = WinHttpSetCredentials( hRequest, dwTarget, dwSelectedScheme, pGetRequest->szServerUsername, pGetRequest->szServerPassword, NULL ); } // If the same credentials are requested twice, abort the // request. For simplicity, this sample does not check for // a repeated sequence of status codes. if( dwLastStatus == 401 ) bDone = TRUE; break; case 407: // The proxy requires authentication. printf( "The proxy requires authentication. Sending credentials\n"); // Obtain the supported and preferred schemes. bResults = WinHttpQueryAuthSchemes( hRequest, &dwSupportedSchemes, &dwFirstScheme, &dwTarget ); // Set the credentials before re-sending the request. if( bResults ) dwProxyAuthScheme = ChooseAuthScheme(dwSupportedSchemes); // If the same credentials are requested twice, abort the // request. For simplicity, this sample does not check for // a repeated sequence of status codes. if( dwLastStatus == 407 ) bDone = TRUE; break; default: // The status code does not indicate success. printf( "Error. Status code %d returned.\n", dwStatusCode ); bDone = TRUE; } } // Keep track of the last status code. dwLastStatus = dwStatusCode; // If there are any errors, break out of the loop. if( !bResults ) bDone = TRUE; } // Report any errors. if( !bResults ) { DWORD dwLastError = GetLastError( ); printf( "Error %d has occurred.\n", dwLastError ); } // Close any open handles. if( hRequest ) WinHttpCloseHandle( hRequest ); if( hConnect ) WinHttpCloseHandle( hConnect ); if( hSession ) WinHttpCloseHandle( hSession ); }</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryauthschemes BOOL WinHttpQueryAuthSchemes( [in]
|
||
// HINTERNET hRequest, [out] LPDWORD lpdwSupportedSchemes, [out] LPDWORD lpdwFirstScheme, [out] LPDWORD pdwAuthTarget );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryAuthSchemes")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpQueryAuthSchemes(HINTERNET hRequest, out WINHTTP_AUTH_SCHEME lpdwSupportedSchemes,
|
||
out WINHTTP_AUTH_SCHEME lpdwFirstScheme, out WINHTTP_AUTH_TARGET pdwAuthTarget);
|
||
|
||
/// <summary>Retrieves a description of the current state of WinHttp's connections.</summary>
|
||
/// <param name="hInternet">
|
||
/// <para>Type: _In_ <c>HINTERNET</c></para>
|
||
/// <para>A request handle or a connect handle.</para>
|
||
/// <para>
|
||
/// If a connect handle, then WinHttp assumes that the host uses HTTPS by default. But you can pass
|
||
/// <c>WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE</c> (0x0000000000000001ull) in ullFlags to indicate that you want non-HTTPS connections.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pGuidConnection">
|
||
/// <para>Type: _In_ <c>GUID*</c></para>
|
||
/// <para>
|
||
/// An optional GUID. If provided, then only connections matching the GUID are returned. Otherwise, the function returns all
|
||
/// connections to the host (specified in hInternet either by a request handle or a connect handle).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ullFlags">
|
||
/// <para>Type: _In_ <c>ULONGLONG</c></para>
|
||
/// <para>Flags. Pass <c>WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE</c> to indicate that you want non-HTTPS connections (see hInternet).</para>
|
||
/// </param>
|
||
/// <param name="ppResult">
|
||
/// <para>Type: _Inout_ <c>PWINHTTP_QUERY_CONNECTION_GROUP_RESULT*</c></para>
|
||
/// <para>The address of a pointer to a WINHTTP_QUERY_CONNECTION_GROUP_RESULT, through which the results are returned.</para>
|
||
/// <para>WinHttp performs an allocation internally, so once you're done with it you must free this pointer by calling WinHttpFreeQueryConnectionGroupResult.</para>
|
||
/// </param>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryconnectiongroup WINHTTPAPI DWORD
|
||
// WinHttpQueryConnectionGroup( HINTERNET hInternet, const GUID *pGuidConnection, ULONGLONG ullFlags,
|
||
// PWINHTTP_QUERY_CONNECTION_GROUP_RESULT *ppResult );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryConnectionGroup")]
|
||
public static extern Win32Error WinHttpQueryConnectionGroup(HINTERNET hInternet, in Guid pGuidConnection,
|
||
[Optional] WINHTTP_QUERY_CONNECTION_GROUP_FLAG ullFlags, ref IntPtr ppResult);
|
||
|
||
/// <summary>Retrieves a description of the current state of WinHttp's connections.</summary>
|
||
/// <param name="hInternet">
|
||
/// <para>Type: _In_ <c>HINTERNET</c></para>
|
||
/// <para>A request handle or a connect handle.</para>
|
||
/// <para>
|
||
/// If a connect handle, then WinHttp assumes that the host uses HTTPS by default. But you can pass
|
||
/// <c>WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE</c> (0x0000000000000001ull) in ullFlags to indicate that you want non-HTTPS connections.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pGuidConnection">
|
||
/// <para>Type: _In_ <c>GUID*</c></para>
|
||
/// <para>
|
||
/// An optional GUID. If provided, then only connections matching the GUID are returned. Otherwise, the function returns all
|
||
/// connections to the host (specified in hInternet either by a request handle or a connect handle).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ullFlags">
|
||
/// <para>Type: _In_ <c>ULONGLONG</c></para>
|
||
/// <para>Flags. Pass <c>WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE</c> to indicate that you want non-HTTPS connections (see hInternet).</para>
|
||
/// </param>
|
||
/// <param name="ppResult">
|
||
/// <para>Type: _Inout_ <c>PWINHTTP_QUERY_CONNECTION_GROUP_RESULT*</c></para>
|
||
/// <para>The address of a pointer to a <see cref="WINHTTP_QUERY_CONNECTION_GROUP_RESULT"/>, through which the results are returned.</para>
|
||
/// <para>WinHttp performs an allocation internally, so once you're done with it you must free this pointer by calling <see cref="WinHttpFreeQueryConnectionGroupResult"/>.</para>
|
||
/// </param>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryconnectiongroup WINHTTPAPI DWORD
|
||
// WinHttpQueryConnectionGroup( HINTERNET hInternet, const GUID *pGuidConnection, ULONGLONG ullFlags,
|
||
// PWINHTTP_QUERY_CONNECTION_GROUP_RESULT *ppResult );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryConnectionGroup")]
|
||
public static extern Win32Error WinHttpQueryConnectionGroup(HINTERNET hInternet, [In, Optional] IntPtr pGuidConnection,
|
||
[Optional] WINHTTP_QUERY_CONNECTION_GROUP_FLAG ullFlags, ref IntPtr ppResult);
|
||
|
||
/// <summary>The <c>WinHttpQueryDataAvailable</c> function returns the amount of data, in bytes, available to be read with WinHttpReadData.</summary>
|
||
/// <param name="hRequest">
|
||
/// A valid HINTERNET handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have
|
||
/// completed before <c>WinHttpQueryDataAvailable</c> is called.
|
||
/// </param>
|
||
/// <param name="lpdwNumberOfBytesAvailable">
|
||
/// A pointer to an unsigned long integer variable that receives the number of available bytes. When WinHTTP is used in asynchronous
|
||
/// mode, always set this parameter to <c>NULL</c> and retrieve data in the callback function; not doing so can cause a memory fault.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if the function succeeds, or <c>FALSE</c> otherwise. To get extended error data, call GetLastError. Among the
|
||
/// error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_CONNECTION_ERROR</c></term>
|
||
/// <term>
|
||
/// 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.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot complete because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_OPERATION_CANCELLED</c></term>
|
||
/// <term>
|
||
/// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_TIMEOUT</c></term>
|
||
/// <term>The request has timed out.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function can operate either synchronously or asynchronously. If it returns <c>FALSE</c>, it failed and you can call GetLastError
|
||
/// to get extended error information. If it returns <c>TRUE</c>, use the WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE 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.
|
||
/// </para>
|
||
/// <para>
|
||
/// <c>Warning</c> When WinHTTP is used in asynchronous mode, always set the <c>lpdwNumberOfBytesAvailable</c> parameter to
|
||
/// <c>NULL</c> and retrieve the bytes available in the callback function; otherwise, a memory fault can occur.
|
||
/// </para>
|
||
/// <para>
|
||
/// This function returns the number of bytes of data that are available to read immediately by a subsequent call to WinHttpReadData.
|
||
/// If no data is available and the end of the file has not been reached, one of two things happens. If the session is synchronous,
|
||
/// the request waits until data becomes available. If the session is asynchronous, the function returns <c>TRUE</c>, and when data
|
||
/// becomes available, calls the callback function with WINHTTP_STATUS_CALLBACK_DATA_AVAILABLE and indicates the number of bytes
|
||
/// immediately available to read by calling <c>WinHttpReadData</c>.
|
||
/// </para>
|
||
/// <para>
|
||
/// The amount of data that remains is not recalculated until all available data indicated by the call to
|
||
/// <c>WinHttpQueryDataAvailable</c> is read.
|
||
/// </para>
|
||
/// <para>Use the return value of WinHttpReadData to determine when a response has been completely read.</para>
|
||
/// <para>
|
||
/// <c>Important</c> Do not use the return value of <c>WinHttpQueryDataAvailable</c> to determine whether the end of a response has
|
||
/// been reached, because not all servers terminate responses properly, and an improperly terminated response causes
|
||
/// <c>WinHttpQueryDataAvailable</c> to anticipate more data.
|
||
/// </para>
|
||
/// <para>
|
||
/// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse
|
||
/// must be made on the handle before <c>WinHttpQueryDataAvailable</c> can be used.
|
||
/// </para>
|
||
/// <para>
|
||
/// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that
|
||
/// have been set in the <c>dwNotificationFlags</c> parameter of <c>WinHttpSetStatusCallback</c> indicate progress in checking for
|
||
/// available data:
|
||
/// </para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para><c>Note</c> For more information about Windows XP and Windows 2000, see Run-Time Requirements.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpquerydataavailable BOOL WinHttpQueryDataAvailable(
|
||
// [in] HINTERNET hRequest, [out] LPDWORD lpdwNumberOfBytesAvailable );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryDataAvailable")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpQueryDataAvailable(HINTERNET hRequest, out uint lpdwNumberOfBytesAvailable);
|
||
|
||
/// <summary>Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings.</summary>
|
||
/// <param name="hRequest">
|
||
/// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have
|
||
/// completed before <c>WinHttpQueryHeaders</c> is called.
|
||
/// </param>
|
||
/// <param name="dwInfoLevel">
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed on the Query Info Flags page.
|
||
/// These attribute and modifier flags indicate that the information is being requested and how it is to be formatted.
|
||
/// </param>
|
||
/// <param name="pwszName">
|
||
/// Pointer to a string that contains the header name. If the flag in <c>dwInfoLevel</c> is not <c>WINHTTP_QUERY_CUSTOM</c>, set this
|
||
/// parameter to WINHTTP_HEADER_NAME_BY_INDEX.
|
||
/// </param>
|
||
/// <param name="lpBuffer">
|
||
/// Pointer to the buffer that receives the information. Setting this parameter to WINHTTP_NO_OUTPUT_BUFFER causes this function to
|
||
/// return <c>FALSE</c>. Calling GetLastError then returns <c>ERROR_INSUFFICIENT_BUFFER</c> and <c>lpdwBufferLength</c> contains the
|
||
/// number of bytes required to hold the requested information.
|
||
/// </param>
|
||
/// <param name="lpdwBufferLength">
|
||
/// <para>
|
||
/// Pointer to a value of type <c>DWORD</c> that specifies the length of the data buffer, in bytes. When the function returns, this
|
||
/// parameter contains the pointer to a value that specifies the length of the information written to the buffer. When the function
|
||
/// returns strings, the following rules apply.
|
||
/// </para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>
|
||
/// If the function succeeds, <c>lpdwBufferLength</c> specifies the length of the string, in bytes, minus 2 for the terminating null.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// If the function fails and <c>ERROR_INSUFFICIENT_BUFFER</c> is returned, <c>lpdwBufferLength</c> specifies the number of bytes
|
||
/// that the application must allocate to receive the string.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="lpdwIndex">
|
||
/// Pointer to a zero-based header index used to enumerate multiple headers with the same name. When calling the function, this
|
||
/// parameter is the index of the specified header to return. When the function returns, this parameter is the index of the next
|
||
/// header. If the next index cannot be found, <c>ERROR_WINHTTP_HEADER_NOT_FOUND</c> is returned. Set this parameter to
|
||
/// WINHTTP_NO_HEADER_INDEX to specify that only the first occurrence of a header should be returned.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise. To get extended error information, call GetLastError. Among the
|
||
/// error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_HEADER_NOT_FOUND</c></term>
|
||
/// <term>The requested header could not be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be carried out because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// By default <c>WinHttpQueryHeaders</c> returns a string. However, you can request data in the form of a SYSTEMTIME structure or
|
||
/// <c>DWORD</c> by including the appropriate modifier flag in <c>dwInfoLevel</c>. The following table shows the possible data types
|
||
/// that <c>WinHttpQueryHeaders</c> can return along with the modifier flag that you use to select that data type.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Data type</term>
|
||
/// <term>Modifier flag</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>LPCWSTR</c></term>
|
||
/// <term>Default. No modifier flag required.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>SYSTEMTIME</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c></term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>DWORD</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_NUMBER</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following example shows how to obtain an HINTERNET handle, open an HTTP session, create and send a request header, and
|
||
/// examine the returned response header.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code> DWORD dwSize = 0; LPVOID lpOutBuffer = NULL; 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.microsoft.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, 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); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // First, use WinHttpQueryHeaders to obtain the size of the buffer. if (bResults) { WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); // Allocate memory for the buffer. if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER ) { lpOutBuffer = new WCHAR[dwSize/sizeof(WCHAR)]; // Now, use WinHttpQueryHeaders to retrieve the header. bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, lpOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX); } } // Print the header contents. if (bResults) printf("Header contents: \n%S",lpOutBuffer); // Free the allocated memory. delete [] lpOutBuffer; // 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);</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryheaders BOOL WinHttpQueryHeaders( [in] HINTERNET
|
||
// hRequest, [in] DWORD dwInfoLevel, [in, optional] LPCWSTR pwszName, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength, [in,
|
||
// out] LPDWORD lpdwIndex );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpQueryHeaders(HINTERNET hRequest, WINHTTP_QUERY dwInfoLevel, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszName,
|
||
[Out, Optional] IntPtr lpBuffer, ref uint lpdwBufferLength, ref uint lpdwIndex);
|
||
|
||
/// <summary>Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings.</summary>
|
||
/// <param name="hRequest">
|
||
/// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have
|
||
/// completed before <c>WinHttpQueryHeaders</c> is called.
|
||
/// </param>
|
||
/// <param name="dwInfoLevel">
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed on the Query Info Flags page.
|
||
/// These attribute and modifier flags indicate that the information is being requested and how it is to be formatted.
|
||
/// </param>
|
||
/// <param name="pwszName">
|
||
/// Pointer to a string that contains the header name. If the flag in <c>dwInfoLevel</c> is not <c>WINHTTP_QUERY_CUSTOM</c>, set this
|
||
/// parameter to WINHTTP_HEADER_NAME_BY_INDEX.
|
||
/// </param>
|
||
/// <param name="lpBuffer">
|
||
/// Pointer to the buffer that receives the information. Setting this parameter to WINHTTP_NO_OUTPUT_BUFFER causes this function to
|
||
/// return <c>FALSE</c>. Calling GetLastError then returns <c>ERROR_INSUFFICIENT_BUFFER</c> and <c>lpdwBufferLength</c> contains the
|
||
/// number of bytes required to hold the requested information.
|
||
/// </param>
|
||
/// <param name="lpdwBufferLength">
|
||
/// <para>
|
||
/// Pointer to a value of type <c>DWORD</c> that specifies the length of the data buffer, in bytes. When the function returns, this
|
||
/// parameter contains the pointer to a value that specifies the length of the information written to the buffer. When the function
|
||
/// returns strings, the following rules apply.
|
||
/// </para>
|
||
/// <list type="bullet">
|
||
/// <item>
|
||
/// <term>
|
||
/// If the function succeeds, <c>lpdwBufferLength</c> specifies the length of the string, in bytes, minus 2 for the terminating null.
|
||
/// </term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term>
|
||
/// If the function fails and <c>ERROR_INSUFFICIENT_BUFFER</c> is returned, <c>lpdwBufferLength</c> specifies the number of bytes
|
||
/// that the application must allocate to receive the string.
|
||
/// </term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </param>
|
||
/// <param name="lpdwIndex">
|
||
/// Pointer to a zero-based header index used to enumerate multiple headers with the same name. When calling the function, this
|
||
/// parameter is the index of the specified header to return. When the function returns, this parameter is the index of the next
|
||
/// header. If the next index cannot be found, <c>ERROR_WINHTTP_HEADER_NOT_FOUND</c> is returned. Set this parameter to
|
||
/// WINHTTP_NO_HEADER_INDEX to specify that only the first occurrence of a header should be returned.
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>
|
||
/// Returns <c>TRUE</c> if successful, or <c>FALSE</c> otherwise. To get extended error information, call GetLastError. Among the
|
||
/// error codes returned are the following.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_HEADER_NOT_FOUND</c></term>
|
||
/// <term>The requested header could not be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be carried out because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError.
|
||
/// </para>
|
||
/// <para>
|
||
/// By default <c>WinHttpQueryHeaders</c> returns a string. However, you can request data in the form of a SYSTEMTIME structure or
|
||
/// <c>DWORD</c> by including the appropriate modifier flag in <c>dwInfoLevel</c>. The following table shows the possible data types
|
||
/// that <c>WinHttpQueryHeaders</c> can return along with the modifier flag that you use to select that data type.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Data type</term>
|
||
/// <term>Modifier flag</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>LPCWSTR</c></term>
|
||
/// <term>Default. No modifier flag required.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>SYSTEMTIME</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c></term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>DWORD</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_NUMBER</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// <para><c>Note</c> For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page.</para>
|
||
/// <para>Examples</para>
|
||
/// <para>
|
||
/// The following example shows how to obtain an HINTERNET handle, open an HTTP session, create and send a request header, and
|
||
/// examine the returned response header.
|
||
/// </para>
|
||
/// <para>
|
||
/// <code> DWORD dwSize = 0; LPVOID lpOutBuffer = NULL; 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.microsoft.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, 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); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // First, use WinHttpQueryHeaders to obtain the size of the buffer. if (bResults) { WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &dwSize, WINHTTP_NO_HEADER_INDEX); // Allocate memory for the buffer. if( GetLastError( ) == ERROR_INSUFFICIENT_BUFFER ) { lpOutBuffer = new WCHAR[dwSize/sizeof(WCHAR)]; // Now, use WinHttpQueryHeaders to retrieve the header. bResults = WinHttpQueryHeaders( hRequest, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, lpOutBuffer, &dwSize, WINHTTP_NO_HEADER_INDEX); } } // Print the header contents. if (bResults) printf("Header contents: \n%S",lpOutBuffer); // Free the allocated memory. delete [] lpOutBuffer; // 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);</code>
|
||
/// </para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryheaders BOOL WinHttpQueryHeaders( [in] HINTERNET
|
||
// hRequest, [in] DWORD dwInfoLevel, [in, optional] LPCWSTR pwszName, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength, [in,
|
||
// out] LPDWORD lpdwIndex );
|
||
[DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")]
|
||
[return: MarshalAs(UnmanagedType.Bool)]
|
||
public static extern bool WinHttpQueryHeaders(HINTERNET hRequest, WINHTTP_QUERY dwInfoLevel, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszName,
|
||
[Out, Optional] IntPtr lpBuffer, ref uint lpdwBufferLength, [In, Optional] IntPtr lpdwIndex);
|
||
|
||
/// <summary>Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings.</summary>
|
||
/// <typeparam name="T">The type of the value to return.</typeparam>
|
||
/// <param name="hRequest">
|
||
/// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have
|
||
/// completed before <c>WinHttpQueryHeaders</c> is called.
|
||
/// </param>
|
||
/// <param name="infoLevel">
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed on the Query Info Flags page.
|
||
/// These attribute and modifier flags indicate that the information is being requested and how it is to be formatted.
|
||
/// </param>
|
||
/// <param name="name">
|
||
/// Pointer to a string that contains the header name. If the flag in <paramref name="infoLevel"/> is not
|
||
/// <c>WINHTTP_QUERY_CUSTOM</c>, set this parameter to WINHTTP_HEADER_NAME_BY_INDEX.
|
||
/// </param>
|
||
/// <param name="index">
|
||
/// A zero-based header index used to enumerate multiple headers with the same name. When calling the function, this parameter is the
|
||
/// index of the specified header to return. When the function returns, this parameter is the index of the next header. If the next
|
||
/// index cannot be found, <c>ERROR_WINHTTP_HEADER_NOT_FOUND</c> is returned.
|
||
/// </param>
|
||
/// <returns>The requested value.</returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously.
|
||
/// </para>
|
||
/// <para>
|
||
/// By default <c>WinHttpQueryHeaders</c> returns a string. However, you can request data in the form of a SYSTEMTIME structure or
|
||
/// <c>uint</c> by including the appropriate modifier flag in <paramref name="infoLevel"/>. The following table shows the possible
|
||
/// data types that <c>WinHttpQueryHeaders</c> can return along with the modifier flag that you use to select that data type.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Data type</term>
|
||
/// <term>Modifier flag</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>string</c></term>
|
||
/// <term>Default. No modifier flag required.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>SYSTEMTIME</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c></term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>uint</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_NUMBER</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </remarks>
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")]
|
||
public static T WinHttpQueryHeaders<T>(HINTERNET hRequest, WINHTTP_QUERY infoLevel, [Optional] string name, ref uint index)
|
||
{
|
||
uint sz = 0;
|
||
WinHttpQueryHeaders(hRequest, infoLevel, name, default, ref sz, ref index);
|
||
Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER);
|
||
if (typeof(T).IsValueType)
|
||
sz = Math.Max(InteropExtensions.SizeOf<T>(), sz);
|
||
using var buffer = new SafeHGlobalHandle(sz);
|
||
Win32Error.ThrowLastErrorIfFalse(WinHttpQueryHeaders(hRequest, infoLevel, name, buffer, ref sz, ref index));
|
||
return buffer.ToType<T>();
|
||
}
|
||
|
||
/// <summary>Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings.</summary>
|
||
/// <typeparam name="T">The type of the value to return.</typeparam>
|
||
/// <param name="hRequest">
|
||
/// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have
|
||
/// completed before <c>WinHttpQueryHeaders</c> is called.
|
||
/// </param>
|
||
/// <param name="infoLevel">
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed on the Query Info Flags page.
|
||
/// These attribute and modifier flags indicate that the information is being requested and how it is to be formatted.
|
||
/// </param>
|
||
/// <param name="name">
|
||
/// Pointer to a string that contains the header name. If the flag in <paramref name="infoLevel"/> is not
|
||
/// <c>WINHTTP_QUERY_CUSTOM</c>, set this parameter to WINHTTP_HEADER_NAME_BY_INDEX.
|
||
/// </param>
|
||
/// <returns>The requested value.</returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// Even when WinHTTP is used in asynchronous mode (that is, when <c>WINHTTP_FLAG_ASYNC</c> has been set in WinHttpOpen), this
|
||
/// function operates synchronously.
|
||
/// </para>
|
||
/// <para>
|
||
/// By default <c>WinHttpQueryHeaders</c> returns a string. However, you can request data in the form of a SYSTEMTIME structure or
|
||
/// <c>uint</c> by including the appropriate modifier flag in <paramref name="infoLevel"/>. The following table shows the possible
|
||
/// data types that <c>WinHttpQueryHeaders</c> can return along with the modifier flag that you use to select that data type.
|
||
/// </para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Data type</term>
|
||
/// <term>Modifier flag</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>string</c></term>
|
||
/// <term>Default. No modifier flag required.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>SYSTEMTIME</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c></term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>uint</c></term>
|
||
/// <term><c>WINHTTP_QUERY_FLAG_NUMBER</c></term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </remarks>
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")]
|
||
public static T WinHttpQueryHeaders<T>(HINTERNET hRequest, WINHTTP_QUERY infoLevel, [Optional] string name)
|
||
{
|
||
uint sz = 0;
|
||
WinHttpQueryHeaders(hRequest, infoLevel, name, default, ref sz);
|
||
Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER);
|
||
if (typeof(T).IsValueType)
|
||
sz = Math.Max(InteropExtensions.SizeOf<T>(), sz);
|
||
using var buffer = new SafeHGlobalHandle(sz);
|
||
Win32Error.ThrowLastErrorIfFalse(WinHttpQueryHeaders(hRequest, infoLevel, name, buffer, ref sz));
|
||
return buffer.ToType<T>();
|
||
}
|
||
|
||
private const WINHTTP_QUERY queryMods = WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER64 | WINHTTP_QUERY.WINHTTP_QUERY_FLAG_SYSTEMTIME;
|
||
|
||
/// <summary>
|
||
/// Retrieves header information associated with an HTTP request; offers a way to retrieve parsed header name and value strings.
|
||
/// </summary>
|
||
/// <param name="hRequest">
|
||
/// <para>Type: _In_ <c>HINTERNET</c></para>
|
||
/// <para>
|
||
/// Request handle returned by WinHttpOpenRequest. The WinHttpReceiveResponse call for this handle must have completed before calling
|
||
/// <c>WinHttpQueryHeadersEx</c>. If you're querying trailers, then the WinHttpReadData call for this handle must return 0 bytes read
|
||
/// before calling <c>WinHttpQueryHeadersEx</c>.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwInfoLevel">
|
||
/// <para>Type: _In_ <c>DWORD</c></para>
|
||
/// <para>
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed in the Query info flags topic.
|
||
/// These attribute and modifier flags indicate the information that is being requested, and how it is to be formatted.
|
||
/// </para>
|
||
/// <para>
|
||
/// <para>Note</para>
|
||
/// <para>
|
||
/// The following flags return <c>ERROR_INVALID_PARAMETER</c> if used: <c>WINHTTP_QUERY_VERSION</c>,
|
||
/// <c>WINHTTP_QUERY_STATUS_CODE</c>, <c>WINHTTP_QUERY_STATUS_TEXT</c>, <c>WINHTTP_QUERY_FLAG_NUMBER</c>,
|
||
/// <c>WINHTTP_QUERY_FLAG_NUMBER64</c>, <c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c>, and <c>WINHTTP_QUERY_RAW_HEADERS_CRLF</c>.
|
||
/// </para>
|
||
/// </para>
|
||
/// <para>The flag <c>WINHTTP_QUERY_EX_ALL_HEADERS</c> returns all the headers.</para>
|
||
/// <para>
|
||
/// If you're not querying for all of the headers, then you can pass the flag corresponding to a specific known header, or you can
|
||
/// pass <c>WINHTTP_QUERY_CUSTOM</c> along with a string for the header name in the pHeaderName parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// Passing <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c> returns the headers in the format in which they're sent over the wire (you should
|
||
/// access/set the psz* members of WINHTTP_EXTENDED_HEADER and WINHTTP_HEADER_NAME). If you don't set the wire encoding flag, then
|
||
/// the default behavior is to return headers in Unicode format (you should access/set the pwsz* members of WINHTTP_EXTENDED_HEADER
|
||
/// and WINHTTP_HEADER_NAME).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ullFlags">
|
||
/// <para>Type: _In_ <c>ULONGLONG</c></para>
|
||
/// <para>Reserved. Set to 0.</para>
|
||
/// </param>
|
||
/// <param name="uiCodePage">
|
||
/// <para>Type: _In_ <c>UINT</c></para>
|
||
/// <para>
|
||
/// The code page to use for Unicode conversion. You should pass in 0 for default behavior (CP_ACP), or when using
|
||
/// <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c>. No validation is done for this parameter.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwIndex">
|
||
/// <para>Type: _Inout_opt_ <c>PDWORD</c></para>
|
||
/// <para>
|
||
/// The address of a zero-based index used to enumerate multiple headers with the same name. When calling the function, this
|
||
/// parameter is the index of the specified header to return. When the function returns, this parameter is the index of the next
|
||
/// header. Pass <c>NULL</c> to access the first instance of a given header.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pHeaderName">
|
||
/// <para>Type: _Inout_opt_ <c>PWINHTTP_HEADER_NAME</c></para>
|
||
/// <para>The address of a WINHTTP_HEADER_NAME structure.</para>
|
||
/// <para>
|
||
/// Set pHeaderName to <c>NULL</c> when retrieving all headers. If this parameter is not <c>NULL</c>, and you pass
|
||
/// <c>WINHTTP_QUERY_CUSTOM</c> with dwInfoLevel, then <c>WinHttpQueryHeadersEx</c> will retrieve only the header specified by this
|
||
/// parameter. If you pass <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c> with dwInfoLevel, then you should use the pszName member (if the
|
||
/// flag is not set, then use pwszName member).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pBuffer">
|
||
/// <para>Type: _Out_writes_bytes_to_opt_(*pdwBufferLength, *pdwBufferLength) <c>LPVOID</c></para>
|
||
/// <para>
|
||
/// A caller-provided buffer to store the parsed header pointers and the headers. If this parameter is <c>NULL</c> or too small, then
|
||
/// <c>WinHttpQueryHeadersEx</c> returns <c>ERROR_INSUFFICIENT_BUFFER</c>, and the pdwBufferLength parameter contains the required
|
||
/// buffer size in bytes.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwBufferLength">
|
||
/// <para>Type: _Inout_ <c>PDWORD</c></para>
|
||
/// <para>
|
||
/// Length of the caller-provided buffer. If pBuffer is <c>NULL</c> or too small, then <c>WinHttpQueryHeadersEx</c> writes the
|
||
/// required buffer size in bytes to this parameter.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ppHeaders">
|
||
/// <para>Type: _Out_writes_opt_(*pdwHeadersCount) <c>PWINHTTP_EXTENDED_HEADER*</c></para>
|
||
/// <para>
|
||
/// A handle to an array of WINHTTP_EXTENDED_HEADER for accessing parsed header names/values. You should pass in the address of a
|
||
/// <c>WINHTTP_EXTENDED_HEADER</c> pointer that's initialized to <c>NULL</c>. Upon completion, you should access the pszName/pszValue
|
||
/// parameters if using <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c>, and pwszName/pwszValue otherwise.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwHeadersCount">
|
||
/// <para>Type: _Out_ <c>PDWORD</c></para>
|
||
/// <para>The number of headers returned. You shouldn't try to access beyond
|
||
/// <code>ppHeaders[cHeaders - 1]</code>
|
||
/// , because that is out of bounds of the array.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation. Among the error codes returned are the following.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_HEADER_NOT_FOUND</c></term>
|
||
/// <term>The requested header could not be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be carried out because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// <c>WinHttpQueryHeadersEx</c> builds on the functionality of WinHttpQueryHeaders. <c>WinHttpQueryHeaders</c> allows you to query
|
||
/// request or response headers (or response trailers) in the form of a string, a number (DWORD), or a timestamp (SYSTEMTIME).
|
||
/// Querying for all headers returns a single serialized string with CRLF or NULL characters delimiting different headers. For
|
||
/// example, "Name1: value1\r\nName2: value2\r\n\r\n". Or "Name1: value1\0Name2: value2\0\0". A double delimiter is used to indicate
|
||
/// the end of the string.
|
||
/// </para>
|
||
/// <para><c>WinHttpQueryHeadersEx</c> gives you a way to retrieve parsed header name and value strings.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryheadersex WINHTTPAPI DWORD
|
||
// WinHttpQueryHeadersEx( HINTERNET hRequest, DWORD dwInfoLevel, ULONGLONG ullFlags, UINT uiCodePage, PDWORD pdwIndex,
|
||
// PWINHTTP_HEADER_NAME pHeaderName, PVOID pBuffer, PDWORD pdwBufferLength, PWINHTTP_EXTENDED_HEADER *ppHeaders, PDWORD
|
||
// pdwHeadersCount );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeadersEx")]
|
||
public static extern Win32Error WinHttpQueryHeadersEx(HINTERNET hRequest, WINHTTP_QUERY dwInfoLevel, [Optional] ulong ullFlags,
|
||
[Optional] uint uiCodePage, ref uint pdwIndex, ref WINHTTP_HEADER_NAME pHeaderName, [Out, Optional] IntPtr pBuffer,
|
||
ref uint pdwBufferLength, out IntPtr ppHeaders, out uint pdwHeadersCount);
|
||
|
||
/// <summary>
|
||
/// Retrieves header information associated with an HTTP request; offers a way to retrieve parsed header name and value strings.
|
||
/// </summary>
|
||
/// <param name="hRequest">
|
||
/// <para>Type: _In_ <c>HINTERNET</c></para>
|
||
/// <para>
|
||
/// Request handle returned by WinHttpOpenRequest. The WinHttpReceiveResponse call for this handle must have completed before calling
|
||
/// <c>WinHttpQueryHeadersEx</c>. If you're querying trailers, then the WinHttpReadData call for this handle must return 0 bytes read
|
||
/// before calling <c>WinHttpQueryHeadersEx</c>.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="dwInfoLevel">
|
||
/// <para>Type: _In_ <c>DWORD</c></para>
|
||
/// <para>
|
||
/// Value of type <c>DWORD</c> that specifies a combination of attribute and modifier flags listed in the Query info flags topic.
|
||
/// These attribute and modifier flags indicate the information that is being requested, and how it is to be formatted.
|
||
/// </para>
|
||
/// <para>
|
||
/// <para>Note</para>
|
||
/// <para>
|
||
/// The following flags return <c>ERROR_INVALID_PARAMETER</c> if used: <c>WINHTTP_QUERY_VERSION</c>,
|
||
/// <c>WINHTTP_QUERY_STATUS_CODE</c>, <c>WINHTTP_QUERY_STATUS_TEXT</c>, <c>WINHTTP_QUERY_FLAG_NUMBER</c>,
|
||
/// <c>WINHTTP_QUERY_FLAG_NUMBER64</c>, <c>WINHTTP_QUERY_FLAG_SYSTEMTIME</c>, and <c>WINHTTP_QUERY_RAW_HEADERS_CRLF</c>.
|
||
/// </para>
|
||
/// </para>
|
||
/// <para>The flag <c>WINHTTP_QUERY_EX_ALL_HEADERS</c> returns all the headers.</para>
|
||
/// <para>
|
||
/// If you're not querying for all of the headers, then you can pass the flag corresponding to a specific known header, or you can
|
||
/// pass <c>WINHTTP_QUERY_CUSTOM</c> along with a string for the header name in the pHeaderName parameter.
|
||
/// </para>
|
||
/// <para>
|
||
/// Passing <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c> returns the headers in the format in which they're sent over the wire (you should
|
||
/// access/set the psz* members of WINHTTP_EXTENDED_HEADER and WINHTTP_HEADER_NAME). If you don't set the wire encoding flag, then
|
||
/// the default behavior is to return headers in Unicode format (you should access/set the pwsz* members of WINHTTP_EXTENDED_HEADER
|
||
/// and WINHTTP_HEADER_NAME).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ullFlags">
|
||
/// <para>Type: _In_ <c>ULONGLONG</c></para>
|
||
/// <para>Reserved. Set to 0.</para>
|
||
/// </param>
|
||
/// <param name="uiCodePage">
|
||
/// <para>Type: _In_ <c>UINT</c></para>
|
||
/// <para>
|
||
/// The code page to use for Unicode conversion. You should pass in 0 for default behavior (CP_ACP), or when using
|
||
/// <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c>. No validation is done for this parameter.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwIndex">
|
||
/// <para>Type: _Inout_opt_ <c>PDWORD</c></para>
|
||
/// <para>
|
||
/// The address of a zero-based index used to enumerate multiple headers with the same name. When calling the function, this
|
||
/// parameter is the index of the specified header to return. When the function returns, this parameter is the index of the next
|
||
/// header. Pass <c>NULL</c> to access the first instance of a given header.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pHeaderName">
|
||
/// <para>Type: _Inout_opt_ <c>PWINHTTP_HEADER_NAME</c></para>
|
||
/// <para>The address of a WINHTTP_HEADER_NAME structure.</para>
|
||
/// <para>
|
||
/// Set pHeaderName to <c>NULL</c> when retrieving all headers. If this parameter is not <c>NULL</c>, and you pass
|
||
/// <c>WINHTTP_QUERY_CUSTOM</c> with dwInfoLevel, then <c>WinHttpQueryHeadersEx</c> will retrieve only the header specified by this
|
||
/// parameter. If you pass <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c> with dwInfoLevel, then you should use the pszName member (if the
|
||
/// flag is not set, then use pwszName member).
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pBuffer">
|
||
/// <para>Type: _Out_writes_bytes_to_opt_(*pdwBufferLength, *pdwBufferLength) <c>LPVOID</c></para>
|
||
/// <para>
|
||
/// A caller-provided buffer to store the parsed header pointers and the headers. If this parameter is <c>NULL</c> or too small, then
|
||
/// <c>WinHttpQueryHeadersEx</c> returns <c>ERROR_INSUFFICIENT_BUFFER</c>, and the pdwBufferLength parameter contains the required
|
||
/// buffer size in bytes.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwBufferLength">
|
||
/// <para>Type: _Inout_ <c>PDWORD</c></para>
|
||
/// <para>
|
||
/// Length of the caller-provided buffer. If pBuffer is <c>NULL</c> or too small, then <c>WinHttpQueryHeadersEx</c> writes the
|
||
/// required buffer size in bytes to this parameter.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="ppHeaders">
|
||
/// <para>Type: _Out_writes_opt_(*pdwHeadersCount) <c>PWINHTTP_EXTENDED_HEADER*</c></para>
|
||
/// <para>
|
||
/// A handle to an array of WINHTTP_EXTENDED_HEADER for accessing parsed header names/values. You should pass in the address of a
|
||
/// <c>WINHTTP_EXTENDED_HEADER</c> pointer that's initialized to <c>NULL</c>. Upon completion, you should access the pszName/pszValue
|
||
/// parameters if using <c>WINHTTP_QUERY_FLAG_WIRE_ENCODING</c>, and pwszName/pwszValue otherwise.
|
||
/// </para>
|
||
/// </param>
|
||
/// <param name="pdwHeadersCount">
|
||
/// <para>Type: _Out_ <c>PDWORD</c></para>
|
||
/// <para>The number of headers returned. You shouldn't try to access beyond
|
||
/// <code>ppHeaders[cHeaders - 1]</code>
|
||
/// , because that is out of bounds of the array.
|
||
/// </para>
|
||
/// </param>
|
||
/// <returns>
|
||
/// <para>A status code indicating the result of the operation. Among the error codes returned are the following.</para>
|
||
/// <list type="table">
|
||
/// <listheader>
|
||
/// <term>Error Code</term>
|
||
/// <term>Description</term>
|
||
/// </listheader>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_HEADER_NOT_FOUND</c></term>
|
||
/// <term>The requested header could not be located.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_STATE</c></term>
|
||
/// <term>The requested operation cannot be carried out because the handle supplied is not in the correct state.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INCORRECT_HANDLE_TYPE</c></term>
|
||
/// <term>The type of handle supplied is incorrect for this operation.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_WINHTTP_INTERNAL_ERROR</c></term>
|
||
/// <term>An internal error has occurred.</term>
|
||
/// </item>
|
||
/// <item>
|
||
/// <term><c>ERROR_NOT_ENOUGH_MEMORY</c></term>
|
||
/// <term>Not enough memory was available to complete the requested operation. (Windows error code)</term>
|
||
/// </item>
|
||
/// </list>
|
||
/// </returns>
|
||
/// <remarks>
|
||
/// <para>
|
||
/// <c>WinHttpQueryHeadersEx</c> builds on the functionality of WinHttpQueryHeaders. <c>WinHttpQueryHeaders</c> allows you to query
|
||
/// request or response headers (or response trailers) in the form of a string, a number (DWORD), or a timestamp (SYSTEMTIME).
|
||
/// Querying for all headers returns a single serialized string with CRLF or NULL characters delimiting different headers. For
|
||
/// example, "Name1: value1\r\nName2: value2\r\n\r\n". Or "Name1: value1\0Name2: value2\0\0". A double delimiter is used to indicate
|
||
/// the end of the string.
|
||
/// </para>
|
||
/// <para><c>WinHttpQueryHeadersEx</c> gives you a way to retrieve parsed header name and value strings.</para>
|
||
/// </remarks>
|
||
// https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryheadersex WINHTTPAPI DWORD
|
||
// WinHttpQueryHeadersEx( HINTERNET hRequest, DWORD dwInfoLevel, ULONGLONG ullFlags, UINT uiCodePage, PDWORD pdwIndex,
|
||
// PWINHTTP_HEADER_NAME pHeaderName, PVOID pBuffer, PDWORD pdwBufferLength, PWINHTTP_EXTENDED_HEADER *ppHeaders, PDWORD
|
||
// pdwHeadersCount );
|
||
[DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)]
|
||
[PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeadersEx")]
|
||
public static extern Win32Error WinHttpQueryHeadersEx(HINTERNET hRequest, WINHTTP_QUERY dwInfoLevel, [Optional] ulong ullFlags,
|
||
[Optional] uint uiCodePage, [Optional] IntPtr pdwIndex, [Optional] IntPtr pHeaderName, [Out, Optional] IntPtr pBuffer,
|
||
ref uint pdwBufferLength, out IntPtr ppHeaders, out uint pdwHeadersCount);
|
||
}
|
||
} |