diff --git a/PInvoke/WinHTTP/Vanara.PInvoke.WinHTTP.csproj b/PInvoke/WinHTTP/Vanara.PInvoke.WinHTTP.csproj new file mode 100644 index 00000000..e39892ff --- /dev/null +++ b/PInvoke/WinHTTP/Vanara.PInvoke.WinHTTP.csproj @@ -0,0 +1,22 @@ + + + + winhttp.dll + + + PInvoke API (methods, structures and constants) imported from Windows WinHTTP.dll. + $(AssemblyName) + net462;net48;net5.0;net6.0;netstandard2.0;netcoreapp3.1 + Vanara.PInvoke.WinHTTP + $(AssemblyName) + pinvoke;vanara;net-extensions;interop;WinHTTP + + true + + + + + + + + \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.Funcs.cs b/PInvoke/WinHTTP/WinHTTP.Funcs.cs new file mode 100644 index 00000000..e671a5b1 --- /dev/null +++ b/PInvoke/WinHTTP/WinHTTP.Funcs.cs @@ -0,0 +1,2734 @@ +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 +{ + /// Items from the WinHTTP.dll. + public static partial class WinHTTP + { + private const string Lib_Winhttp = "WinHTTP.dll"; + + /// The WINHTTP_STATUS_CALLBACK type represents an application-defined status callback function. + /// The handle for which the callback function is called. + /// + /// + /// A pointer to a DWORD that specifies the application-defined context value associated with the handle in the + /// hInternet parameter. + /// + /// + /// 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. + /// + /// + /// + /// + /// Points to a DWORD that specifies the status code that indicates why the callback function is called. This can be one of + /// the following values: + /// + /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION + /// Closing the connection to the server. The lpvStatusInformation parameter is NULL. + /// WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER + /// + /// Successfully connected to the server. The lpvStatusInformation parameter contains a pointer to an LPWSTR that + /// indicates the IP address of the server in dotted notation. + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER + /// + /// Connecting to the server. The lpvStatusInformation parameter contains a pointer to an LPWSTR that indicates the IP + /// address of the server in dotted notation. + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// Successfully closed the connection to the server. The lpvStatusInformation parameter is NULL. + /// WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + /// + /// Data is available to be retrieved with WinHttpReadData. The lpvStatusInformation parameter points to a DWORD that + /// contains the number of bytes of data available. The dwStatusInformationLength parameter itself is 4 (the size of a DWORD). + /// + /// WINHTTP_CALLBACK_STATUS_HANDLE_CREATED + /// An HINTERNET handle has been created. The lpvStatusInformation parameter contains a pointer to the HINTERNET handle. + /// WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING + /// + /// This handle value has been terminated. The lpvStatusInformation parameter contains a pointer to the HINTERNET handle. + /// There will be no more callbacks for this handle. + /// + /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + /// + /// The response header has been received and is available with WinHttpQueryHeaders. The lpvStatusInformation parameter is NULL. + /// + /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + /// + /// Received an intermediate (100 level) status code message from the server. The lpvStatusInformation parameter contains a + /// pointer to a DWORD that indicates the status code. + /// + /// WINHTTP_CALLBACK_STATUS_NAME_RESOLVED + /// + /// Successfully found the IP address of the server. The lpvStatusInformation parameter contains a pointer to a LPWSTR + /// that indicates the name that was resolved. + /// + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// + /// Data was successfully read from the server. The lpvStatusInformation parameter contains a pointer to the buffer specified + /// in the call to WinHttpReadData. The dwStatusInformationLength parameter contains the number of bytes read. + /// + /// + /// When used by WinHttpWebSocketReceive, the lpvStatusInformation parameter contains a pointer to a WINHTTP_WEB_SOCKET_STATUS + /// structure, and the dwStatusInformationLength parameter indicates the size of lpvStatusInformation. + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// Waiting for the server to respond to a request. The lpvStatusInformation parameter is NULL. + /// WINHTTP_CALLBACK_STATUS_REDIRECT + /// + /// An HTTP request is about to automatically redirect the request. The lpvStatusInformation parameter contains a pointer to + /// an LPWSTR 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. + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + /// + /// An error occurred while sending an HTTP request. The lpvStatusInformation parameter contains a pointer to a + /// WINHTTP_ASYNC_RESULT structure. Its dwResult member indicates the ID of the called function and dwError indicates + /// the return value. + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// Successfully sent the information request to the server. The lpvStatusInformation parameter contains a pointer to a + /// DWORD indicating the number of bytes sent. + /// + /// WINHTTP_CALLBACK_STATUS_RESOLVING_NAME + /// + /// Looking up the IP address of a server name. The lpvStatusInformation parameter contains a pointer to the server name being resolved. + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// Successfully received a response from the server. The lpvStatusInformation parameter contains a pointer to a DWORD + /// indicating the number of bytes received. + /// + /// WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + /// + /// One or more errors were encountered while retrieving a Secure Sockets Layer (SSL) certificate from the server. The + /// lpvStatusInformation parameter contains a flag. For more information, see the description for lpvStatusInformation. + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// Sending the information request to the server. The lpvStatusInformation parameter is NULL. + /// WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + /// The request completed successfully. The lpvStatusInformation parameter is NULL. + /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + /// + /// Data was successfully written to the server. The lpvStatusInformation parameter contains a pointer to a DWORD that + /// indicates the number of bytes written. + /// + /// + /// When used by WinHttpWebSocketSend, the lpvStatusInformation parameter contains a pointer to a WINHTTP_WEB_SOCKET_STATUS + /// structure, and the dwStatusInformationLength parameter indicates the size of lpvStatusInformation. + /// + /// WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE + /// The operation initiated by a call to WinHttpGetProxyForUrlEx is complete. Data is available to be retrieved with WinHttpReadData. + /// WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE + /// The connection was successfully closed via a call to WinHttpWebSocketClose. + /// WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE + /// The connection was successfully shut down via a call to WinHttpWebSocketShutdown. + /// + /// + /// + /// 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 dwInternetStatus argument. For more information, see dwInternetStatus. + /// + /// + /// If the dwInternetStatus argument is WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, then lpvStatusInformation points to a + /// DWORD which is a bitwise-OR combination of one or more of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED + /// + /// 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. + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT + /// SSL certificate is invalid. + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED + /// SSL certificate was revoked. + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA + /// The function is unfamiliar with the Certificate Authority that generated the server's certificate. + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID + /// + /// 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. + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID + /// SSL certificate date that was received from the server is bad. The certificate is expired. + /// + /// + /// WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR + /// The application experienced an internal error loading the SSL libraries. + /// + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_REDIRECT status callbacks provide a dwStatusInformationLength value that corresponds to the + /// character count of the LPWSTR pointed to by lpvStatusInformation. + /// + /// None + /// + /// + /// 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 dwInternetStatus parameter is equal to WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 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. + /// + /// + /// 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. + /// + /// + /// + /// Completion flag + /// Function + /// + /// + /// WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + /// WinHttpQueryDataAvailable + /// + /// + /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + /// WinHttpReceiveResponse + /// + /// + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// WinHttpReadData + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE + /// WinHttpSendRequest + /// + /// + /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + /// WinHttpWriteData + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + /// Any of the above functions when an error occurs. + /// + /// + /// + /// 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. + /// + /// The callback function can be called in a thread context different from the thread that initiated the request. + /// + /// 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. + /// + /// Note For more information about implementation in Windows XP and Windows 2000, see Run-Time Requirements. + /// + // 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); + + /// The WinHttpAddRequestHeaders function adds one or more HTTP request headers to the HTTP request handle. + /// A HINTERNET handle returned by a call to the WinHttpOpenRequest function. + /// + /// 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). + /// + /// + /// An unsigned long integer value that contains the length, in characters, of pwszHeaders. If this parameter is -1L, the + /// function assumes that pwszHeaders is zero-terminated (ASCIIZ), and the length is computed. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_ADDREQ_FLAG_ADD + /// Adds the header if it does not exist. Used with WINHTTP_ADDREQ_FLAG_REPLACE. + /// + /// + /// WINHTTP_ADDREQ_FLAG_ADD_IF_NEW + /// Adds the header only if it does not already exist; otherwise, an error is returned. + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE + /// Merges headers of the same name. + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA + /// + /// 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. + /// + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON + /// Merges headers of the same name using a semicolon. + /// + /// + /// WINHTTP_ADDREQ_FLAG_REPLACE + /// + /// 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. + /// + /// + /// + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be performed because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// The WinHttpAddRequestHeaders 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. + /// + /// + /// 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. + /// + /// + /// If you are sending a Date: request header, you can use the WinHttpTimeFromSystemTime function to create structure for the header. + /// + /// For basic WinHttpAddRequestHeaders, the application can pass in multiple headers in a single buffer. + /// An application can also use WinHttpSendRequest to add additional headers to the HTTP request handle before sending a request. + /// Note For more information, see Run-Time Requirements. + /// Examples + /// + /// 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. + /// + /// + /// + /// + /// + // 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); + + /// Adds one or more HTTP request headers to an HTTP request handle, allowing you to use separate name/value strings. + /// + /// Type: IN HINTERNET + /// An HINTERNET handle returned by a call to WinHttpOpenRequest. + /// + /// + /// Type: IN DWORD + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_ADDREQ_FLAG_ADD + /// Adds the header if it does not exist. Used with WINHTTP_ADDREQ_FLAG_REPLACE. + /// + /// + /// WINHTTP_ADDREQ_FLAG_ADD_IF_NEW + /// Adds the header only if it does not already exist; otherwise, an error is returned. + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE + /// Merges headers of the same name. + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA + /// + /// 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. + /// + /// + /// + /// WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON + /// Merges headers of the same name using a semicolon. + /// + /// + /// WINHTTP_ADDREQ_FLAG_REPLACE + /// + /// 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. + /// + /// + /// + /// + /// + /// Type: IN ULONGLONG + /// Pass WINHTTP_EXTENDED_HEADER_FLAG_UNICODE to indicate that the strings passed in are Unicode strings. + /// + /// + /// Type: IN ULONGLONG + /// Reserved. + /// + /// + /// Type: IN DWORD + /// The number of elements in pHeaders. + /// + /// + /// Type: _In_reads_(cHeaders) WINHTTP_EXTENDED_HEADER* + /// An array of WINHTTP_EXTENDED_HEADER structures. + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be performed because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. + /// + /// + /// + // 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); + + /// + /// The WinHttpCheckPlatform function determines whether the current platform is supported by this version of Microsoft + /// Windows HTTP Services (WinHTTP). + /// + /// + /// The return value is TRUE if the platform is supported by Microsoft Windows HTTP Services (WinHTTP), or FALSE otherwise. + /// + /// + /// + /// This function is useful if your application uses Microsoft Windows HTTP Services (WinHTTP), but also supports platforms that + /// WinHTTP does not. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// 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. + /// + /// For more information, see Run-Time Requirements. + /// Examples + /// The following example shows how to determine whether the current platform is supported. + /// + /// if (WinHttpCheckPlatform( )) printf("This platform is supported by WinHTTP.\n"); else printf("This platform is NOT supported by WinHTTP.\n"); + /// + /// + // 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(); + + /// The WinHttpCloseHandle function closes a single HINTERNET handle (see HINTERNET Handles in WinHTTP). + /// A valid HINTERNET handle (see HINTERNET Handles in WinHTTP) to be closed. + /// + /// + /// TRUE if the handle is successfully closed, otherwise FALSE. To get extended error information, call GetLastError. + /// Among the error codes returned are the following. + /// + /// + /// + /// Error Codes + /// Description + /// + /// + /// ERROR_WINHTTP_SHUTDOWN + /// The WinHTTP function support is being shut down or unloaded. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// If there is a status callback registered for the handle being closed and the handle was created with a non- NULL context + /// value, a WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING callback is made. This is the last callback made from the handle and + /// indicates that the handle is being destroyed. + /// + /// + /// An application can terminate an in-progress asynchronous request by closing the HINTERNET request handle using + /// WinHttpCloseHandle. Keep the following points in mind: + /// + /// + /// + /// + /// After an application calls WinHttpCloseHandle on a WinHTTP handle, it cannot call any other WinHTTP API functions using + /// that handle from any thread. + /// + /// + /// + /// + /// Even after a call to WinHttpCloseHandle 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. + /// + /// + /// + /// + /// If an application associates a context data structure or object with the handle, it should maintain that binding until the + /// callback function receives a WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING notification. This is the last callback notification + /// WinHTTP sends prior to deleting a handle object from memory. In order to receive the + /// WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING callback notification, the application must enable the + /// WINHTTP_CALLBACK_FLAG_HANDLES flag in the WinHttpSetStatusCallback call. + /// + /// + /// + /// + /// Before calling WinHttpCloseHandle, an application can call WinHttpSetStatusCallback to indicate that no more callbacks + /// should be made: + /// + /// WinHttpSetStatusCallback( hRequest, NULL, 0, 0 ); + /// + /// + /// It might seem that the context data structure could then be freed immediately rather than having to wait for a + /// WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING 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 NULL 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 WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING notification. + /// + /// + /// + /// + /// + /// An application should never call WinHttpCloseHandle on a synchronous request. This can create a race condition. See + /// HINTERNET Handles in WinHTTP for more information. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-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); + + /// + /// The WinHttpConnect function specifies the initial target server of an HTTP request and returns an HINTERNET connection + /// handle to an HTTP session for that initial target. + /// + /// Valid HINTERNET WinHTTP session handle returned by a previous call to WinHttpOpen. + /// + /// Pointer to a null-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). + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// INTERNET_DEFAULT_HTTP_PORT + /// Uses the default port for HTTP servers (port 80). + /// + /// + /// INTERNET_DEFAULT_HTTPS_PORT + /// + /// 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. + /// + /// + /// + /// INTERNET_DEFAULT_PORT + /// Uses port 80 for HTTP and port 443 for Secure Hypertext Transfer Protocol (HTTPS). + /// + /// + /// + /// This parameter is reserved and must be 0. + /// + /// + /// Returns a valid connection handle to the HTTP session if the connection is successful, or NULL otherwise. To retrieve + /// extended error information, call GetLastError. Among the error codes returned are the following. + /// + /// + /// + /// Error Codes + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL scheme could not be recognized, or is not supported. + /// + /// + /// ERROR_WINHTTP_SHUTDOWN + /// The WinHTTP function support is being shut down or unloaded. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// After the calling application has finished using the HINTERNET handle returned by WinHttpConnect, it must be closed using + /// the WinHttpCloseHandle function. + /// + /// + /// WinHttpConnect 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. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to use secure transaction semantics to download a resource from an 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. + /// + /// + /// + /// + /// + // 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); + + /// The WinHttpCrackUrl function separates a URL into its component parts such as host name and path. + /// + /// Pointer to a string that contains the canonical URL to separate. WinHttpCrackUrl does not check this URL for validity or + /// correct format before attempting to crack it. + /// + /// + /// The length of the pwszUrl string, in characters. If dwUrlLength is set to zero, WinHttpCrackUrl assumes that + /// the pwszUrl string is null terminated and determines the length of the pwszUrl string based on that assumption. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// ICU_DECODE + /// + /// 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. + /// + /// + /// + /// ICU_ESCAPE + /// + /// 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. + /// + /// + /// + /// ICU_REJECT_USERPWD + /// + /// 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 ERROR_WINHTTP_INVALID_URL. + /// + /// + /// + /// + /// Pointer to a URL_COMPONENTS structure that receives the URL components. + /// + /// + /// Returns TRUE if the function succeeds, or FALSE otherwise. To get extended error information, call GetLastError. + /// Among the error codes returned are the following. + /// + /// + /// + /// Error Codes + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL scheme could not be recognized, or is not supported. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// The 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 NULL and the value of its corresponding + /// length member is nonzero, the address of the first character of the corresponding component in the pwszUrl string is + /// stored in the pointer, and the length of the component is stored in the length member. + /// + /// + /// If the pointer contains the address of the user-supplied buffer, the length member must contain the size of the buffer. The + /// WinHttpCrackUrl 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, WinHttpCrackUrl + /// returns FALSE, and GetLastError returns ERROR_INSUFFICIENT_BUFFER. + /// + /// + /// For WinHttpCrackUrl to work properly, the size of the URL_COMPONENTS structure must be stored in the dwStructSize member + /// of that structure. + /// + /// + /// If the Internet protocol of the URL passed in for pwszUrl is not HTTP or HTTPS, then WinHttpCrackUrl returns + /// FALSE and GetLastError indicates ERROR_WINHTTP_UNRECOGNIZED_SCHEME. + /// + /// + /// WinHttpCrackUrl 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. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// This example shows how to break a URL into its components, update a component, then reconstruct the URL. + /// + /// 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; } + /// + /// + // 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); + + /// The WinHttpCreateProxyResolver function creates a handle for use by WinHttpGetProxyForUrlEx. + /// + /// Valid HINTERNET WinHTTP session handle returned by a previous call to WinHttpOpen. The session handle must be opened using WINHTTP_FLAG_ASYNC. + /// + /// + /// A pointer to a new handle for use by WinHttpGetProxyForUrlEx. When finished or cancelling an outstanding operation, close this + /// handle with WinHttpCloseHandle. + /// + /// + /// A status code indicating the result of the operation. + /// + /// + /// The following codes may be returned. + /// Description + /// + /// + /// ERROR_SUCCESS + /// The operation succeeded. + /// + /// + /// ERROR_INVALID_HANDLE + /// hSession is NULL. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// hSession is not the result of a call to WinHttpOpen or hSession is not marked as asynchronous using WINHTTP_FLAG_ASYNC. + /// + /// + /// + // 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); + + /// The WinHttpCreateUrl function creates a URL from component parts such as the host name and path. + /// Pointer to a URL_COMPONENTS structure that contains the components from which to create the URL. + /// + /// Flags that control the operation of this function. This parameter can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// ICU_ESCAPE + /// + /// Converts all unsafe characters to their corresponding escape sequences in the path string pointed to by the lpszUrlPath + /// member and in lpszExtraInfo the extra-information string pointed to by the member of the URL_COMPONENTS structure pointed + /// to by the lpUrlComponents parameter. + /// + /// + /// + /// ICU_REJECT_USERPWD + /// + /// 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. + /// + /// + /// + /// + /// Pointer to a character buffer that receives the URL as a wide character (Unicode) string. + /// + /// Pointer to a variable of type unsigned long integer that receives the length of the pwszUrl 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. + /// + /// + /// + /// Returns TRUE if the function succeeds, or FALSE otherwise. To get extended error data, call GetLastError. Among the + /// error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Insufficient memory available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode, that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen, this + /// function operates synchronously. The return value indicates success or failure. To get extended error data, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to decompile, or crack, a URL into its subcomponents, update a component, then reconstruct the URL. + /// + /// + /// 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; } + /// + /// + // 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); + + /// + /// The WinHttpDetectAutoProxyConfigUrl 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. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTO_DETECT_TYPE_DHCP + /// Use DHCP to locate the proxy auto-configuration file. + /// + /// + /// WINHTTP_AUTO_DETECT_TYPE_DNS_A + /// Use DNS to attempt to locate the proxy auto-configuration file at a well-known location on the domain of the local computer. + /// + /// + /// + /// + /// 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 ppwszAutoConfigUrl using the GlobalFree function. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_AUTODETECTION_FAILED + /// Returned if WinHTTP was unable to discover the URL of the Proxy Auto-Configuration (PAC) file. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// WinHTTP implements the Web Proxy Auto-Discovery (WPAD) protocol, often referred to as autoproxy. For more information + /// about well-known locations, see the Discovery Process section of the WPAD protocol document. + /// + /// + /// Note that because the WinHttpDetectAutoProxyConfigUrl function takes time to complete its operation, it should not be + /// called from a UI thread. + /// + /// + // 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); + + /// The WinHttpFreeProxyResult function frees the data retrieved from a previous call to . + /// A pointer to a WINHTTP_PROXY_RESULT structure retrieved from a previous call to WinHttpGetProxyResult. + /// This function does not return a value. + /// + /// Upon completion, all internal members of pProxyResult will be zeroed and the memory allocated to those members will be + /// freed. If pProxyResult is an allocated pointer, the caller must free the pointer. + /// + // 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); + + /// Frees the memory allocated by a previous call to WinHttpQueryConnectionGroup. + /// + /// Type: _Inout_ WINHTTP_QUERY_CONNECTION_GROUP_RESULT* + /// A pointer to the WINHTTP_QUERY_CONNECTION_GROUP_RESULT object to free. + /// + // 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); + + /// + /// The WinHttpGetDefaultProxyConfiguration function retrieves the default WinHTTP proxy configuration from the registry. + /// + /// A pointer to a variable of type WINHTTP_PROXY_INFO that receives the default proxy configuration. + /// + /// + /// Returns TRUE if successful or FALSE otherwise. To retrieve a specific error message, call GetLastError. Error codes + /// returned include the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// WinHttpGetDefaultProxyConfiguration retrieves the proxy configuration set by WinHttpSetDefaultProxyConfiguration or ProxyCfg.exe. + /// + /// + /// The default proxy configuration can be overridden for a WinHTTP session by calling WinHttpSetOption and specifying the + /// WINHTTP_OPTION_PROXY flag. WinHttpGetDefaultProxyConfiguration does not retrieve the configuration for the current + /// session. It retrieves the configuration specified in the registry. + /// + /// + /// If the registry contains a list of proxy servers, the dwAccessType member of pProxyInfo is set to + /// WINHTTP_ACCESS_TYPE_NAMED_PROXY. Otherwise, it is set to WINHTTP_ACCESS_TYPE_NO_PROXY. + /// + /// + /// WinHttpGetDefaultProxyConfiguration allocates memory for the string members of pProxyInfo. To free this memory, + /// call GlobalFree. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP Start Page. + /// Examples + /// The following code example shows how to retrieve the default proxy configuration from the registry. + /// + /// 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 ); } + /// + /// + // 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); + + /// + /// The WinHttpGetIEProxyConfigForCurrentUser function retrieves the Internet Explorer proxy configuration for the current user. + /// + /// + /// 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). + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_FILE_NOT_FOUND + /// No Internet Explorer proxy settings can be found. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// In Internet Explorer, the proxy settings are found on the Connections tab of the Tools / Internet Options + /// 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. WinHttpGetIEProxyConfigForCurrentUser returns the proxy settings for + /// the current active connection. + /// + /// + /// 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 WinHttpGetIEProxyConfigForCurrentUser 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. + /// + /// + /// 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 WinHttpGetIEProxyConfigForCurrentUser will fail. + /// + /// + /// The caller must free the lpszProxy, lpszProxyBypass and lpszAutoConfigUrl strings in the + /// WINHTTP_CURRENT_USER_IE_PROXY_CONFIG structure if they are non- NULL. Use GlobalFree to free the strings. + /// + /// + // 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); + + /// The WinHttpGetProxyForUrl function retrieves the proxy data for the specified URL. + /// The WinHTTP session handle returned by the WinHttpOpen function. + /// + /// A pointer to a null-terminated Unicode string that contains the URL of the HTTP request that the application is preparing to send. + /// + /// + /// A pointer to a WINHTTP_AUTOPROXY_OPTIONS structure that specifies the auto-proxy options to use. + /// + /// + /// 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 lpszProxy and lpszProxyBypass strings contained in this structure + /// (if they are non-NULL) using the GlobalFree function. + /// + /// + /// If the function succeeds, the function returns TRUE. + /// If the function fails, it returns FALSE. For extended error data, call GetLastError. + /// Possible error codes include the folllowing. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR + /// Returned by WinHttpGetProxyForUrl when a proxy for the specified URL cannot be located. + /// + /// + /// ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT + /// An error occurred executing the script code in the Proxy Auto-Configuration (PAC) file. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_LOGIN_FAILURE + /// + /// The login attempt failed. When this error is encountered, close the request handle with WinHttpCloseHandle. A new request handle + /// must be created before retrying the function that originally produced this error. + /// + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT + /// + /// 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. + /// + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL of the PAC file specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// 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 WinHttpGetProxyForUrl can be instructed to + /// automatically discover the location of the PAC file on the local network. + /// + /// WinHttpGetProxyForUrl supports only ECMAScript-based PAC files. + /// + /// WinHttpGetProxyForUrl 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 lpcwszUrl parameter) to a certain proxy in a proxy server array. + /// + /// + /// WinHttpGetProxyForUrl caches the autoproxy URL and the autoproxy script when auto-discovery is specified in the + /// dwFlags member of the pAutoProxyOptions structure. For more information, see Autoproxy Cache. + /// + /// + // 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); + + /// The WinHttpGetProxyForUrlEx function retrieves the proxy data for the specified URL. + /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. + /// + /// A pointer to a null-terminated Unicode string that contains a URL for which proxy information will be determined. + /// + /// + /// A pointer to a WINHTTP_AUTOPROXY_OPTIONS structure that specifies the auto-proxy options to use. + /// + /// Context data that will be passed to the completion callback function. + /// + /// A status code indicating the result of the operation. + /// + /// + /// The following codes may be returned. + /// Description + /// + /// + /// ERROR_IO_PENDING + /// The operation is continuing asynchronously. + /// + /// + /// ERROR_WINHTTP_AUTO_PROXY_SERVICE_ERROR + /// Returned by WinHttpGetProxyForUrlEx when a proxy for the specified URL cannot be located. + /// + /// + /// ERROR_WINHTTP_BAD_AUTO_PROXY_SCRIPT + /// An error occurred executing the script code in the Proxy Auto-Configuration (PAC) file. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT + /// + /// 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. + /// + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL of the PAC file specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// 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 WinHttpGetProxyForUrlEx can be instructed to + /// automatically discover the location of the PAC file on the local network. + /// + /// WinHttpGetProxyForUrlEx supports only ECMAScript-based PAC files. + /// + /// WinHttpGetProxyForUrlEx 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 lpcwszUrl parameter) to a certain proxy in a proxy server array. + /// + /// + /// WinHttpGetProxyForUrlEx caches the autoproxy URL and the autoproxy script when auto-discovery is specified in the + /// dwFlags member of the pAutoProxyOptions structure. For more information, see Autoproxy Cache. + /// + /// + /// WinHttpGetProxyForUrlEx provides a fully Asynchronous and cancellable API that WinHttpGetProxyForUrl does not. + /// WinHttpGetProxyForUrlEx 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. + /// + /// + /// WinHttpGetProxyForUrlEx always executes asynchronously and returns immediately with ERROR_IO_PENDING on success. + /// The callback is set by calling WinHttpSetStatusCallback on the hSession provided by WinHttpOpen. Alternately call + /// WinHttpSetStatusCallback on the hResolver provided by WinHttpCreateProxyResolver to have a specific callback for + /// each call. + /// + /// + /// You must call WinHttpSetStatusCallback before WinHttpCreateProxyResolver. When calling WinHttpSetStatusCallback, use + /// WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE. See WINHTTP_STATUS_CALLBACK for + /// information on the use of the callback. + /// + /// + /// Once a callback of status WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE is returned, the application can call + /// WinHttpGetProxyResult on the resolver handle used to issue WinHttpGetProxyForUrlEx to receive the results of that call. + /// + /// + /// If the call fails after returning ERROR_IO_PENDING then a callback of WINHTTP_CALLBACK_STATUS_REQUEST_ERROR will be issued. + /// + /// This function always executes out-of-process. + /// + // 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); + + /// The WinHttpGetProxyResult function retrieves the results of a call to WinHttpGetProxyForUrlEx. + /// The resolver handle used to issue a previously completed call to WinHttpGetProxyForUrlEx. + /// + /// 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. + /// + /// + /// A status code indicating the result of the operation. + /// + /// + /// The following codes may be returned. + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The resolver handle has not successfully completed a call to WinHttpGetProxyForUrlEx. + /// + /// + /// + // 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); + + /// + /// The WinHttpOpen function initializes, for an application, the use of WinHTTP functions and returns a WinHTTP-session handle. + /// + /// + /// 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. + /// + /// + /// Type of access required. This can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_ACCESS_TYPE_NO_PROXY + /// Resolves all host names directly without a proxy. + /// + /// + /// WINHTTP_ACCESS_TYPE_DEFAULT_PROXY + /// + /// Retrieves the static proxy or direct configuration from the registry. WINHTTP_ACCESS_TYPE_DEFAULT_PROXY does not inherit + /// browser proxy settings. The WinHTTP proxy configuration is set by one of these mechanisms. + /// + /// + /// + /// WINHTTP_ACCESS_TYPE_NAMED_PROXY + /// + /// 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 pwszProxyName and pwszProxyBypass. + /// + /// + /// + /// WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY + /// + /// 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. + /// + /// + /// + /// + /// + /// A pointer to a string variable that contains the name of the proxy server to use when proxy access is specified by setting + /// dwAccessType to WINHTTP_ACCESS_TYPE_NAMED_PROXY. The WinHTTP functions recognize only CERN type proxies for HTTP. + /// If dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY, this parameter must be set to WINHTTP_NO_PROXY_NAME. + /// + /// + /// 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 dwAccessType is set to WINHTTP_ACCESS_TYPE_NAMED_PROXY. The list can + /// contain wildcard characters. Do not use an empty string, because the WinHttpOpen 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 dwAccessType is not set to WINHTTP_ACCESS_TYPE_NAMED_PROXY, this parameter must + /// be set to WINHTTP_NO_PROXY_BYPASS. + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_FLAG_ASYNC + /// + /// 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. + /// + /// + /// + /// WINHTTP_FLAG_SECURE_DEFAULTS + /// + /// 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 WINHTTP_OPTION_SECURE_PROTOCOLS, it will fail with ERROR_ACCESS_DENIED. Additionally, TLS fallback will be + /// disabled. Note that setting this flag also sets flag WINHTTP_FLAG_ASYNC. + /// + /// + /// + /// + /// + /// + /// Returns a valid session handle if successful, or NULL otherwise. To retrieve extended error information, call + /// GetLastError. Among the error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// We strongly recommend that you use WinHTTP in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in + /// WinHttpOpen, so that usage of the returned HINTERNET become asynchronous). The return value indicates success or failure. + /// To retrieve extended error information, call GetLastError. + /// + /// + /// The WinHttpOpen 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. + /// + /// + /// The application can make any number of calls to WinHttpOpen, though a single call is normally sufficient. Each call to + /// WinHttpOpen 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 WinHttpOpen instance, such as + /// different proxy servers configured for each. + /// + /// + /// After the calling application has finished using the HINTERNET handle returned by WinHttpOpen, it must be closed using the + /// WinHttpCloseHandle function. + /// + /// Note For Windows XP and Windows 2000, see Run-Time Requirements. + /// Examples + /// The following example code shows how to retrieve the default connection time-out value. + /// + /// DWORD data; DWORD dwSize = sizeof(DWORD); // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpQueryOption to retrieve internet options. if (WinHttpQueryOption( hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &data, &dwSize)) { printf("Connection timeout: %u ms\n\n",data); } else { printf( "Error %u in WinHttpQueryOption.\n", GetLastError()); } // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-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); + + /// The WinHttpOpenRequest function creates an HTTP request handle. + /// HINTERNET connection handle to an HTTP session returned by WinHttpConnect. + /// + /// Pointer to a string that contains the HTTP verb to use in the request. If this parameter is NULL, the function uses GET as + /// the HTTP verb. Note 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. + /// + /// + /// 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. + /// + /// + /// Pointer to a string that contains the HTTP version. If this parameter is NULL, the function uses HTTP/1.1. + /// + /// + /// Pointer to a string that specifies the URL of the document from which the URL in the request pwszObjectName was obtained. + /// If this parameter is set to WINHTTP_NO_REFERER, no referring document is specified. + /// + /// + /// Pointer to a null-terminated array of string pointers that specifies media types accepted by the client. If this parameter + /// is set to WINHTTP_DEFAULT_ACCEPT_TYPES, 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—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/. + /// + /// + /// Unsigned long integer value that contains the Internet flag values. This can be one or more of the following values: + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_FLAG_BYPASS_PROXY_CACHE + /// This flag provides the same behavior as WINHTTP_FLAG_REFRESH. + /// + /// + /// WINHTTP_FLAG_ESCAPE_DISABLE + /// Unsafe characters in the URL passed in for pwszObjectName are not converted to escape sequences. + /// + /// + /// WINHTTP_FLAG_ESCAPE_DISABLE_QUERY + /// Unsafe characters in the query component of the URL passed in for pwszObjectName are not converted to escape sequences. + /// + /// + /// WINHTTP_FLAG_ESCAPE_PERCENT + /// + /// The string passed in for pwszObjectName is converted from an LPCWSTR to an LPSTR. 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. + /// + /// + /// + /// WINHTTP_FLAG_NULL_CODEPAGE + /// + /// The string passed in for pwszObjectName is assumed to consist of valid ANSI characters represented by WCHAR. No + /// check are done for unsafe characters. Windows 7: This option is obsolete. + /// + /// + /// + /// WINHTTP_FLAG_REFRESH + /// + /// 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. + /// + /// + /// + /// WINHTTP_FLAG_SECURE + /// Uses secure transaction semantics. This translates to using Secure Sockets Layer (SSL)/Transport Layer Security (TLS). + /// + /// + /// + /// + /// + /// Returns a valid HTTP request handle if successful, or NULL if not. For extended error information, call GetLastError. + /// Among the error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// The WinHttpOpenRequest 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. + /// + /// If pwszVerb is set to "HEAD", the Content-Length header is ignored. + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then a + /// WINHTTP_CALLBACK_STATUS_HANDLE_CREATED notification indicates that WinHttpOpenRequest has created a request handle. + /// + /// + /// After the calling application finishes using the HINTERNET handle returned by WinHttpOpenRequest, it must be closed using + /// the WinHttpCloseHandle function. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// This example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that header to the server. + /// + /// + /// BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // PLACE ADDITIONAL CODE HERE. // Report any errors. if (!bResults) printf( "Error %d has occurred.\n", GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-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); + + /// The WinHttpQueryAuthSchemes function returns the authorization schemes that are supported by the server. + /// Valid HINTERNET handle returned by WinHttpOpenRequest + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Indicates basic authentication is available. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Indicates NTLM authentication is available. + /// + /// + /// WINHTTP_AUTH_SCHEME_PASSPORT + /// Indicates passport authentication is available. + /// + /// + /// WINHTTP_AUTH_SCHEME_DIGEST + /// Indicates digest authentication is available. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Selects between NTLM and Kerberos authentication. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Indicates basic authentication is first. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Indicates NTLM authentication is first. + /// + /// + /// WINHTTP_AUTH_SCHEME_PASSPORT + /// Indicates passport authentication is first. + /// + /// + /// WINHTTP_AUTH_SCHEME_DIGEST + /// Indicates digest authentication is first. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Selects between NTLM and Kerberos authentication. + /// + /// + /// + /// + /// + /// 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. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_TARGET_SERVER + /// Authentication target is a server. Indicates that a 401 status code has been received. + /// + /// + /// WINHTTP_AUTH_TARGET_PROXY + /// Authentication target is a proxy. Indicates that a 407 status code has been received. + /// + /// + /// + /// + /// + /// Returns TRUE if successful, or FALSE if unsuccessful. To get extended error information, call GetLastError. The + /// following table identifies the error codes that are returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC is set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// WinHttpQueryAuthSchemes cannot be used before calling WinHttpQueryHeaders. + /// Note For Windows XP and Windows 2000 see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to 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. + /// + /// + /// #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 ); } + /// + /// + // 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); + + /// Retrieves a description of the current state of WinHttp's connections. + /// + /// Type: _In_ HINTERNET + /// A request handle or a connect handle. + /// + /// If a connect handle, then WinHttp assumes that the host uses HTTPS by default. But you can pass + /// WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE (0x0000000000000001ull) in ullFlags to indicate that you want non-HTTPS connections. + /// + /// + /// + /// Type: _In_ GUID* + /// + /// 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). + /// + /// + /// + /// Type: _In_ ULONGLONG + /// Flags. Pass WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE to indicate that you want non-HTTPS connections (see hInternet). + /// + /// + /// Type: _Inout_ PWINHTTP_QUERY_CONNECTION_GROUP_RESULT* + /// The address of a pointer to a WINHTTP_QUERY_CONNECTION_GROUP_RESULT, through which the results are returned. + /// WinHttp performs an allocation internally, so once you're done with it you must free this pointer by calling WinHttpFreeQueryConnectionGroupResult. + /// + // 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); + + /// Retrieves a description of the current state of WinHttp's connections. + /// + /// Type: _In_ HINTERNET + /// A request handle or a connect handle. + /// + /// If a connect handle, then WinHttp assumes that the host uses HTTPS by default. But you can pass + /// WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE (0x0000000000000001ull) in ullFlags to indicate that you want non-HTTPS connections. + /// + /// + /// + /// Type: _In_ GUID* + /// + /// 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). + /// + /// + /// + /// Type: _In_ ULONGLONG + /// Flags. Pass WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE to indicate that you want non-HTTPS connections (see hInternet). + /// + /// + /// Type: _Inout_ PWINHTTP_QUERY_CONNECTION_GROUP_RESULT* + /// The address of a pointer to a , through which the results are returned. + /// WinHttp performs an allocation internally, so once you're done with it you must free this pointer by calling . + /// + // 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); + + /// The WinHttpQueryDataAvailable function returns the amount of data, in bytes, available to be read with WinHttpReadData. + /// + /// A valid HINTERNET handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have + /// completed before WinHttpQueryDataAvailable is called. + /// + /// + /// 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 NULL and retrieve data in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if the function succeeds, or FALSE otherwise. To get extended error data, call GetLastError. Among the + /// error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot complete because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function can operate either synchronously or asynchronously. If it returns FALSE, it failed and you can call GetLastError + /// to get extended error information. If it returns TRUE, 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. + /// + /// + /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesAvailable parameter to + /// NULL and retrieve the bytes available in the callback function; otherwise, a memory fault can occur. + /// + /// + /// 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 TRUE, 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 WinHttpReadData. + /// + /// + /// The amount of data that remains is not recalculated until all available data indicated by the call to + /// WinHttpQueryDataAvailable is read. + /// + /// Use the return value of WinHttpReadData to determine when a response has been completely read. + /// + /// Important Do not use the return value of WinHttpQueryDataAvailable to determine whether the end of a response has + /// been reached, because not all servers terminate responses properly, and an improperly terminated response causes + /// WinHttpQueryDataAvailable to anticipate more data. + /// + /// + /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse + /// must be made on the handle before WinHttpQueryDataAvailable can be used. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for + /// available data: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE + /// + /// + /// Note For more information about Windows XP and Windows 2000, see Run-Time Requirements. + /// + // 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); + + /// Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings. + /// + /// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have + /// completed before WinHttpQueryHeaders is called. + /// + /// + /// Value of type DWORD 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. + /// + /// + /// Pointer to a string that contains the header name. If the flag in dwInfoLevel is not WINHTTP_QUERY_CUSTOM, set this + /// parameter to WINHTTP_HEADER_NAME_BY_INDEX. + /// + /// + /// Pointer to the buffer that receives the information. Setting this parameter to WINHTTP_NO_OUTPUT_BUFFER causes this function to + /// return FALSE. Calling GetLastError then returns ERROR_INSUFFICIENT_BUFFER and lpdwBufferLength contains the + /// number of bytes required to hold the requested information. + /// + /// + /// + /// Pointer to a value of type DWORD 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. + /// + /// + /// + /// + /// If the function succeeds, lpdwBufferLength specifies the length of the string, in bytes, minus 2 for the terminating null. + /// + /// + /// + /// + /// If the function fails and ERROR_INSUFFICIENT_BUFFER is returned, lpdwBufferLength specifies the number of bytes + /// that the application must allocate to receive the string. + /// + /// + /// + /// + /// + /// 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, ERROR_WINHTTP_HEADER_NOT_FOUND is returned. Set this parameter to + /// WINHTTP_NO_HEADER_INDEX to specify that only the first occurrence of a header should be returned. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError. Among the + /// error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_HEADER_NOT_FOUND + /// The requested header could not be located. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// By default WinHttpQueryHeaders returns a string. However, you can request data in the form of a SYSTEMTIME structure or + /// DWORD by including the appropriate modifier flag in dwInfoLevel. The following table shows the possible data types + /// that WinHttpQueryHeaders can return along with the modifier flag that you use to select that data type. + /// + /// + /// + /// Data type + /// Modifier flag + /// + /// + /// LPCWSTR + /// Default. No modifier flag required. + /// + /// + /// SYSTEMTIME + /// WINHTTP_QUERY_FLAG_SYSTEMTIME + /// + /// + /// DWORD + /// WINHTTP_QUERY_FLAG_NUMBER + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to obtain an HINTERNET handle, open an HTTP session, create and send a request header, and + /// examine the returned response header. + /// + /// + /// 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); + /// + /// + // 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); + + /// Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings. + /// + /// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have + /// completed before WinHttpQueryHeaders is called. + /// + /// + /// Value of type DWORD 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. + /// + /// + /// Pointer to a string that contains the header name. If the flag in dwInfoLevel is not WINHTTP_QUERY_CUSTOM, set this + /// parameter to WINHTTP_HEADER_NAME_BY_INDEX. + /// + /// + /// Pointer to the buffer that receives the information. Setting this parameter to WINHTTP_NO_OUTPUT_BUFFER causes this function to + /// return FALSE. Calling GetLastError then returns ERROR_INSUFFICIENT_BUFFER and lpdwBufferLength contains the + /// number of bytes required to hold the requested information. + /// + /// + /// + /// Pointer to a value of type DWORD 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. + /// + /// + /// + /// + /// If the function succeeds, lpdwBufferLength specifies the length of the string, in bytes, minus 2 for the terminating null. + /// + /// + /// + /// + /// If the function fails and ERROR_INSUFFICIENT_BUFFER is returned, lpdwBufferLength specifies the number of bytes + /// that the application must allocate to receive the string. + /// + /// + /// + /// + /// + /// 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, ERROR_WINHTTP_HEADER_NOT_FOUND is returned. Set this parameter to + /// WINHTTP_NO_HEADER_INDEX to specify that only the first occurrence of a header should be returned. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError. Among the + /// error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_HEADER_NOT_FOUND + /// The requested header could not be located. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// By default WinHttpQueryHeaders returns a string. However, you can request data in the form of a SYSTEMTIME structure or + /// DWORD by including the appropriate modifier flag in dwInfoLevel. The following table shows the possible data types + /// that WinHttpQueryHeaders can return along with the modifier flag that you use to select that data type. + /// + /// + /// + /// Data type + /// Modifier flag + /// + /// + /// LPCWSTR + /// Default. No modifier flag required. + /// + /// + /// SYSTEMTIME + /// WINHTTP_QUERY_FLAG_SYSTEMTIME + /// + /// + /// DWORD + /// WINHTTP_QUERY_FLAG_NUMBER + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to obtain an HINTERNET handle, open an HTTP session, create and send a request header, and + /// examine the returned response header. + /// + /// + /// 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); + /// + /// + // 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); + + /// Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings. + /// The type of the value to return. + /// + /// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have + /// completed before WinHttpQueryHeaders is called. + /// + /// + /// Value of type DWORD 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. + /// + /// + /// Pointer to a string that contains the header name. If the flag in is not + /// WINHTTP_QUERY_CUSTOM, set this parameter to WINHTTP_HEADER_NAME_BY_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, ERROR_WINHTTP_HEADER_NOT_FOUND is returned. + /// + /// The requested value. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. + /// + /// + /// By default WinHttpQueryHeaders returns a string. However, you can request data in the form of a SYSTEMTIME structure or + /// uint by including the appropriate modifier flag in . The following table shows the possible + /// data types that WinHttpQueryHeaders can return along with the modifier flag that you use to select that data type. + /// + /// + /// + /// Data type + /// Modifier flag + /// + /// + /// string + /// Default. No modifier flag required. + /// + /// + /// SYSTEMTIME + /// WINHTTP_QUERY_FLAG_SYSTEMTIME + /// + /// + /// uint + /// WINHTTP_QUERY_FLAG_NUMBER + /// + /// + /// + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")] + public static T WinHttpQueryHeaders(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(), sz); + using var buffer = new SafeHGlobalHandle(sz); + Win32Error.ThrowLastErrorIfFalse(WinHttpQueryHeaders(hRequest, infoLevel, name, buffer, ref sz, ref index)); + return buffer.ToType(); + } + + /// Also see WinHttpQueryHeadersEx, which offers a way to retrieve parsed header name and value strings. + /// The type of the value to return. + /// + /// HINTERNET request handle returned by WinHttpOpenRequest. WinHttpReceiveResponse must have been called for this handle and have + /// completed before WinHttpQueryHeaders is called. + /// + /// + /// Value of type DWORD 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. + /// + /// + /// Pointer to a string that contains the header name. If the flag in is not + /// WINHTTP_QUERY_CUSTOM, set this parameter to WINHTTP_HEADER_NAME_BY_INDEX. + /// + /// The requested value. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. + /// + /// + /// By default WinHttpQueryHeaders returns a string. However, you can request data in the form of a SYSTEMTIME structure or + /// uint by including the appropriate modifier flag in . The following table shows the possible + /// data types that WinHttpQueryHeaders can return along with the modifier flag that you use to select that data type. + /// + /// + /// + /// Data type + /// Modifier flag + /// + /// + /// string + /// Default. No modifier flag required. + /// + /// + /// SYSTEMTIME + /// WINHTTP_QUERY_FLAG_SYSTEMTIME + /// + /// + /// uint + /// WINHTTP_QUERY_FLAG_NUMBER + /// + /// + /// + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryHeaders")] + public static T WinHttpQueryHeaders(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(), sz); + using var buffer = new SafeHGlobalHandle(sz); + Win32Error.ThrowLastErrorIfFalse(WinHttpQueryHeaders(hRequest, infoLevel, name, buffer, ref sz)); + return buffer.ToType(); + } + + private const WINHTTP_QUERY queryMods = WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER64 | WINHTTP_QUERY.WINHTTP_QUERY_FLAG_SYSTEMTIME; + + /// + /// Retrieves header information associated with an HTTP request; offers a way to retrieve parsed header name and value strings. + /// + /// + /// Type: _In_ HINTERNET + /// + /// Request handle returned by WinHttpOpenRequest. The WinHttpReceiveResponse call for this handle must have completed before calling + /// WinHttpQueryHeadersEx. If you're querying trailers, then the WinHttpReadData call for this handle must return 0 bytes read + /// before calling WinHttpQueryHeadersEx. + /// + /// + /// + /// Type: _In_ DWORD + /// + /// Value of type DWORD 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. + /// + /// + /// Note + /// + /// The following flags return ERROR_INVALID_PARAMETER if used: WINHTTP_QUERY_VERSION, + /// WINHTTP_QUERY_STATUS_CODE, WINHTTP_QUERY_STATUS_TEXT, WINHTTP_QUERY_FLAG_NUMBER, + /// WINHTTP_QUERY_FLAG_NUMBER64, WINHTTP_QUERY_FLAG_SYSTEMTIME, and WINHTTP_QUERY_RAW_HEADERS_CRLF. + /// + /// + /// The flag WINHTTP_QUERY_EX_ALL_HEADERS returns all the headers. + /// + /// 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 WINHTTP_QUERY_CUSTOM along with a string for the header name in the pHeaderName parameter. + /// + /// + /// Passing WINHTTP_QUERY_FLAG_WIRE_ENCODING 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). + /// + /// + /// + /// Type: _In_ ULONGLONG + /// Reserved. Set to 0. + /// + /// + /// Type: _In_ UINT + /// + /// The code page to use for Unicode conversion. You should pass in 0 for default behavior (CP_ACP), or when using + /// WINHTTP_QUERY_FLAG_WIRE_ENCODING. No validation is done for this parameter. + /// + /// + /// + /// Type: _Inout_opt_ PDWORD + /// + /// 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 NULL to access the first instance of a given header. + /// + /// + /// + /// Type: _Inout_opt_ PWINHTTP_HEADER_NAME + /// The address of a WINHTTP_HEADER_NAME structure. + /// + /// Set pHeaderName to NULL when retrieving all headers. If this parameter is not NULL, and you pass + /// WINHTTP_QUERY_CUSTOM with dwInfoLevel, then WinHttpQueryHeadersEx will retrieve only the header specified by this + /// parameter. If you pass WINHTTP_QUERY_FLAG_WIRE_ENCODING with dwInfoLevel, then you should use the pszName member (if the + /// flag is not set, then use pwszName member). + /// + /// + /// + /// Type: _Out_writes_bytes_to_opt_(*pdwBufferLength, *pdwBufferLength) LPVOID + /// + /// A caller-provided buffer to store the parsed header pointers and the headers. If this parameter is NULL or too small, then + /// WinHttpQueryHeadersEx returns ERROR_INSUFFICIENT_BUFFER, and the pdwBufferLength parameter contains the required + /// buffer size in bytes. + /// + /// + /// + /// Type: _Inout_ PDWORD + /// + /// Length of the caller-provided buffer. If pBuffer is NULL or too small, then WinHttpQueryHeadersEx writes the + /// required buffer size in bytes to this parameter. + /// + /// + /// + /// Type: _Out_writes_opt_(*pdwHeadersCount) PWINHTTP_EXTENDED_HEADER* + /// + /// A handle to an array of WINHTTP_EXTENDED_HEADER for accessing parsed header names/values. You should pass in the address of a + /// WINHTTP_EXTENDED_HEADER pointer that's initialized to NULL. Upon completion, you should access the pszName/pszValue + /// parameters if using WINHTTP_QUERY_FLAG_WIRE_ENCODING, and pwszName/pwszValue otherwise. + /// + /// + /// + /// Type: _Out_ PDWORD + /// The number of headers returned. You shouldn't try to access beyond + /// ppHeaders[cHeaders - 1] + /// , because that is out of bounds of the array. + /// + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_HEADER_NOT_FOUND + /// The requested header could not be located. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// WinHttpQueryHeadersEx builds on the functionality of WinHttpQueryHeaders. WinHttpQueryHeaders 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. + /// + /// WinHttpQueryHeadersEx gives you a way to retrieve parsed header name and value strings. + /// + // 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); + + /// + /// Retrieves header information associated with an HTTP request; offers a way to retrieve parsed header name and value strings. + /// + /// + /// Type: _In_ HINTERNET + /// + /// Request handle returned by WinHttpOpenRequest. The WinHttpReceiveResponse call for this handle must have completed before calling + /// WinHttpQueryHeadersEx. If you're querying trailers, then the WinHttpReadData call for this handle must return 0 bytes read + /// before calling WinHttpQueryHeadersEx. + /// + /// + /// + /// Type: _In_ DWORD + /// + /// Value of type DWORD 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. + /// + /// + /// Note + /// + /// The following flags return ERROR_INVALID_PARAMETER if used: WINHTTP_QUERY_VERSION, + /// WINHTTP_QUERY_STATUS_CODE, WINHTTP_QUERY_STATUS_TEXT, WINHTTP_QUERY_FLAG_NUMBER, + /// WINHTTP_QUERY_FLAG_NUMBER64, WINHTTP_QUERY_FLAG_SYSTEMTIME, and WINHTTP_QUERY_RAW_HEADERS_CRLF. + /// + /// + /// The flag WINHTTP_QUERY_EX_ALL_HEADERS returns all the headers. + /// + /// 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 WINHTTP_QUERY_CUSTOM along with a string for the header name in the pHeaderName parameter. + /// + /// + /// Passing WINHTTP_QUERY_FLAG_WIRE_ENCODING 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). + /// + /// + /// + /// Type: _In_ ULONGLONG + /// Reserved. Set to 0. + /// + /// + /// Type: _In_ UINT + /// + /// The code page to use for Unicode conversion. You should pass in 0 for default behavior (CP_ACP), or when using + /// WINHTTP_QUERY_FLAG_WIRE_ENCODING. No validation is done for this parameter. + /// + /// + /// + /// Type: _Inout_opt_ PDWORD + /// + /// 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 NULL to access the first instance of a given header. + /// + /// + /// + /// Type: _Inout_opt_ PWINHTTP_HEADER_NAME + /// The address of a WINHTTP_HEADER_NAME structure. + /// + /// Set pHeaderName to NULL when retrieving all headers. If this parameter is not NULL, and you pass + /// WINHTTP_QUERY_CUSTOM with dwInfoLevel, then WinHttpQueryHeadersEx will retrieve only the header specified by this + /// parameter. If you pass WINHTTP_QUERY_FLAG_WIRE_ENCODING with dwInfoLevel, then you should use the pszName member (if the + /// flag is not set, then use pwszName member). + /// + /// + /// + /// Type: _Out_writes_bytes_to_opt_(*pdwBufferLength, *pdwBufferLength) LPVOID + /// + /// A caller-provided buffer to store the parsed header pointers and the headers. If this parameter is NULL or too small, then + /// WinHttpQueryHeadersEx returns ERROR_INSUFFICIENT_BUFFER, and the pdwBufferLength parameter contains the required + /// buffer size in bytes. + /// + /// + /// + /// Type: _Inout_ PDWORD + /// + /// Length of the caller-provided buffer. If pBuffer is NULL or too small, then WinHttpQueryHeadersEx writes the + /// required buffer size in bytes to this parameter. + /// + /// + /// + /// Type: _Out_writes_opt_(*pdwHeadersCount) PWINHTTP_EXTENDED_HEADER* + /// + /// A handle to an array of WINHTTP_EXTENDED_HEADER for accessing parsed header names/values. You should pass in the address of a + /// WINHTTP_EXTENDED_HEADER pointer that's initialized to NULL. Upon completion, you should access the pszName/pszValue + /// parameters if using WINHTTP_QUERY_FLAG_WIRE_ENCODING, and pwszName/pwszValue otherwise. + /// + /// + /// + /// Type: _Out_ PDWORD + /// The number of headers returned. You shouldn't try to access beyond + /// ppHeaders[cHeaders - 1] + /// , because that is out of bounds of the array. + /// + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_HEADER_NOT_FOUND + /// The requested header could not be located. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// WinHttpQueryHeadersEx builds on the functionality of WinHttpQueryHeaders. WinHttpQueryHeaders 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. + /// + /// WinHttpQueryHeadersEx gives you a way to retrieve parsed header name and value strings. + /// + // 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); + } +} \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.Funcs2.cs b/PInvoke/WinHTTP/WinHTTP.Funcs2.cs new file mode 100644 index 00000000..f702345d --- /dev/null +++ b/PInvoke/WinHTTP/WinHTTP.Funcs2.cs @@ -0,0 +1,2069 @@ +using System; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +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 +{ + /// Items from the WinHTTP.dll. + public static partial class WinHTTP + { + /// The WinHttpQueryOption function queries an Internet option on the specified handle. + /// + /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, + /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying + /// a particular option. + /// + /// + /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. + /// + /// + /// A pointer to a buffer that receives the option setting. Strings returned by the WinHttpQueryOption function are globally + /// allocated, so the calling application must globally free the string when it finishes using it. Setting this parameter to + /// NULL causes this function to return FALSE. Calling GetLastError then returns ERROR_INSUFFICIENT_BUFFER and + /// lpdwBufferLength contains the number of bytes required to hold the requested information. + /// + /// + /// A pointer to an unsigned long integer variable that contains the length of lpBuffer, in bytes. When the function returns, + /// the variable receives the length of the data placed into lpBuffer. If GetLastError returns ERROR_INSUFFICIENT_BUFFER, this + /// parameter receives the number of bytes required to hold the requested information. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get a specific error message, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// An invalid option value was specified. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// GetLastError returns the ERROR_INVALID_PARAMETER if an option flag that is invalid for the specified handle type is passed to the + /// dwOption parameter. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// This example demonstrates retrieving the connection time-out value: + /// + /// DWORD data; DWORD dwSize = sizeof(DWORD); // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpQueryOption to retrieve internet options. if (WinHttpQueryOption( hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &data, &dwSize)) { printf("Connection timeout: %u ms\n\n",data); } else { printf( "Error %u in WinHttpQueryOption.\n", GetLastError()); } // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [Out, Optional] IntPtr lpBuffer, ref uint lpdwBufferLength); + + /// The WinHttpQueryOption function queries an Internet option on the specified handle. + /// The type of the option. + /// + /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, + /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying + /// a particular option. + /// + /// + /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. + /// + /// The option setting. + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] + public static T WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption) + { + var rType = CorrespondingTypeAttribute.GetCorrespondingTypes(dwOption, CorrespondingAction.Get).FirstOrDefault() ?? typeof(T); + if (typeof(T) != typeof(object)) + rType = typeof(T); + uint sz = 0; + WinHttpQueryOption(hInternet, dwOption, default, ref sz); + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + using var buffer = new SafeHGlobalHandle(sz); + Win32Error.ThrowLastErrorIfFalse(WinHttpQueryOption(hInternet, dwOption, buffer, ref sz)); + return (T)buffer.DangerousGetHandle().Convert(sz, rType, CharSet.Unicode); + } + + /// Also see WinHttpReadDataEx. + /// + /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable + /// must have been called for this handle and must have completed before WinHttpReadData is called. Although calling + /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing + /// so requires that the application use a fixed-length buffer for reading. + /// + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. + /// + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to + /// zero before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and + /// retrieve the information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following + /// table identifies the error codes that are returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent + /// to the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking + /// information before giving the data to the application. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you + /// can call GetLastError to get extended error information. If this function returns TRUE, use the + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion to determine whether this function was successful and the value of the + /// parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. + /// + /// + /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL + /// and retrieve the bytes read in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion triggers another call to WinHttpReadData, the situation can result in a + /// stack overflow. In general, it is best to use a read buffer that is comparable in size, or larger than the internal read buffer + /// used by WinHTTP, which is 8 KB. + /// + /// + /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, + /// the transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a + /// local file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the + /// dwStatusInformationLength parameter set to zero when the end of a response is found. + /// + /// + /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the + /// response. If sufficient data has not arrived from the server, the buffer is not filled. + /// + /// + /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse + /// must be made on the handle before WinHttpReadData can be used. + /// + /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. + /// + /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow + /// can result. It is best to use a read buffer that is 8 Kilobytes or larger in size. + /// + /// + /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by + /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML + /// encoded directory entries, it must be large enough to hold at least one complete entry. + /// + /// + /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications + /// that have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking + /// for available data: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer + /// Protocol (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS + /// server, then opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to + /// determine how much data is available for download, then WinHttpReadData is used to read that data. This process repeats + /// until the entire document has been retrieved and displayed. + /// + /// + /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET + // hRequest, [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, out uint lpdwNumberOfBytesRead); + + /// Reads data from a handle opened by the WinHttpOpenRequest function. + /// + /// Type: IN HINTERNET + /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. + /// + /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before + /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of + /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length + /// buffer for reading. + /// + /// + /// + /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. + /// + /// + /// + /// Type: IN DWORD + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// + /// Type: OUT LPDWORD + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to + /// zero before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and + /// retrieve the information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Type: IN ULONGLONG + /// + /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until + /// the provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API + /// equivalent to that of WinHttpReadData. + /// + /// + /// + /// Type: IN DWORD + /// Reserved. Pass 0. + /// + /// + /// Type: _In_reads_bytes_opt_(cbProperty) PVOID + /// Reserved. Pass NULL. + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the + /// function won't always completely fill the buffer that you provide). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( + // HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD + // cbProperty, PVOID pvProperty ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] + public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, + out uint lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); + + /// + /// The WinHttpReceiveResponse function waits to receive the response to an HTTP request initiated by WinHttpSendRequest. When + /// WinHttpReceiveResponse completes successfully, the status code and response headers have been received and are available + /// for the application to inspect using WinHttpQueryHeaders. An application must call WinHttpReceiveResponse before it can + /// use WinHttpQueryDataAvailable and WinHttpReadData to access the response entity body (if any). + /// + /// + /// HINTERNET handle returned by WinHttpOpenRequest and sent by WinHttpSendRequest. Wait until WinHttpSendRequest has + /// completed for this handle before calling WinHttpReceiveResponse. + /// + /// This parameter is reserved and must be NULL. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CANNOT_CONNECT + /// Returned if connection to the server failed. + /// + /// + /// ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW + /// Returned when an overflow condition is encountered in the course of parsing chunked encoding. + /// + /// + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED + /// Returned when the server requests client authentication. + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_HEADER_COUNT_EXCEEDED + /// Returned when a larger number of headers were present in a response than WinHTTP could receive. + /// + /// + /// ERROR_WINHTTP_HEADER_SIZE_OVERFLOW + /// Returned by WinHttpReceiveResponse when the size of headers received exceeds the limit for the request handle. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_SERVER_RESPONSE + /// The server response could not be parsed. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_LOGIN_FAILURE + /// + /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new + /// request handle must be created before retrying the function that originally produced this error. + /// + /// + /// + /// ERROR_WINHTTP_NAME_NOT_RESOLVED + /// The server name could not be resolved. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_REDIRECT_FAILED + /// The redirection failed because either the scheme changed or all attempts made to redirect failed (default is five attempts). + /// + /// + /// ERROR_WINHTTP_RESEND_REQUEST + /// The WinHTTP function failed. The desired function can be retried on the same request handle. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_SECURE_FAILURE + /// + /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error + /// was encountered, check for a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more + /// information, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you + /// can call GetLastError to get extended error information. If this function returns TRUE, the application should expect + /// either the WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE completion callback, indicating success, or the + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion callback, indicating that the operation completed asynchronously, but failed. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in receiving the response: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + /// + /// + /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_REDIRECT + /// + /// + /// + /// If the server closes the connection, the following notifications will also be reported, provided that they have been set in the + /// dwNotificationFlags parameter of WinHttpSetStatusCallback: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is + /// fictitious and must be replaced with the name of a server for which you have write access. + /// + /// + /// LPSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreceiveresponse WINHTTPAPI BOOL + // WinHttpReceiveResponse( [in] HINTERNET hRequest, [in] LPVOID lpReserved ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReceiveResponse")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpReceiveResponse(HINTERNET hRequest, [In, Optional] IntPtr lpReserved); + + /// The WinHttpResetAutoProxy function resets the auto-proxy. + /// A valid HINTERNET WinHTTP session handle returned by a previous call to the WinHttpOpen function. + /// + /// A set of flags that affects the reset operation. + /// The following flags are supported as defined in the Winhttp.h header file. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_RESET_STATE 0x00000001 + /// Forces a flush and retry of non-persistent proxy information on the current network. + /// + /// + /// WINHTTP_RESET_SWPAD_CURRENT_NETWORK 0x00000002 + /// Flush the PAD information for the current network. + /// + /// + /// WINHTTP_RESET_SWPAD_ALL 0x00000004 + /// Flush the PAD information for all networks. + /// + /// + /// WINHTTP_RESET_SCRIPT_CACHE 0x00000008 + /// Flush the persistent HTTP cache of proxy scripts. + /// + /// + /// WINHTTP_RESET_ALL 0x0000FFFF + /// Forces a flush and retry of all proxy information on the current network. + /// + /// + /// WINHTTP_RESET_NOTIFY_NETWORK_CHANGED 0x00010000 + /// Flush the current proxy information and notify that the network changed. + /// + /// + /// WINHTTP_RESET_OUT_OF_PROC 0x00020000 + /// + /// Act on the autoproxy service instead of the current process. Applications that use the WinHttpGetProxyForUrl function to purge + /// in-process caching should close the hInternet handle and open a new handle for future calls. + /// + /// + /// + /// + /// + /// A code indicating the success or failure of the operation. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The operation was successful. + /// + /// + /// ERROR_INVALID_HANDLE + /// The hSession parameter is not a valid handle. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE TYPE + /// The hSession parameter is not the product of a call to WinHttpOpen. + /// + /// + /// + /// + /// To reset everything, set the dwFlags parameter to include WINHTTP_RESET_ALL and WINHTTP_RESET_OUT_OF_PROC. + /// + /// Note If you make subsequent calls to the WinHttpResetAutoProxy function, there must be at least 30 seconds delay + /// between calls to reset the state of the auto-proxy. If there is less than 30 seconds, the WinHttpResetAutoProxy function + /// call may return ERROR_SUCCESS but the reset won't happen. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpresetautoproxy WINHTTPAPI DWORD + // WinHttpResetAutoProxy( [in] HINTERNET hSession, [in] DWORD dwFlags ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpResetAutoProxy")] + public static extern uint WinHttpResetAutoProxy(HINTERNET hSession, WINHTTP_RESET dwFlags); + + /// The WinHttpSendRequest function sends the specified request to the HTTP server. + /// An HINTERNET handle returned by WinHttpOpenRequest. + /// + /// A pointer to a string that contains the additional headers to append to the request. This parameter can be + /// WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to append. + /// + /// + /// An unsigned long integer value that contains the length, in characters, of the additional headers. If this parameter is + /// -1L and pwszHeaders is not NULL, this function assumes that pwszHeaders is null-terminated, + /// and the length is calculated. + /// + /// + /// + /// A pointer to a buffer that contains any optional data to send immediately after the request headers. This parameter is generally + /// used for POST and PUT operations. The optional data can be the resource or data posted to the server. This parameter can be + /// WINHTTP_NO_REQUEST_DATA if there is no optional data to send. + /// + /// If the dwOptionalLength parameter is 0, this parameter is ignored and set to NULL. + /// This buffer must remain available until the request handle is closed or the call to WinHttpReceiveResponse has completed. + /// + /// + /// + /// An unsigned long integer value that contains the length, in bytes, of the optional data. This parameter can be zero if there is + /// no optional data to send. + /// + /// + /// This parameter must contain a valid length when the lpOptional parameter is not NULL. Otherwise, lpOptional + /// is ignored and set to NULL. + /// + /// + /// + /// + /// An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the + /// Content-Length header of the request. If the value of this parameter is greater than the length specified by + /// dwOptionalLength, then WinHttpWriteData can be used to send additional data. + /// + /// + /// dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength + /// needs to be changed, the caller should create a new request. + /// + /// + /// + /// A pointer to a pointer-sized variable that contains an application-defined value that is passed, with the request handle, to any + /// callback functions. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Error codes are + /// listed in the following table. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CANNOT_CONNECT + /// Returned if connection to the server failed. + /// + /// + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED + /// + /// The secure HTTP server requires a client certificate. The application retrieves the list of certificate issuers by calling + /// WinHttpQueryOption with the WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST option. If the server requests the client certificate, + /// but does not require it, the application can alternately call WinHttpSetOption with the WINHTTP_OPTION_CLIENT_CERT_CONTEXT + /// option. In this case, the application specifies the WINHTTP_NO_CLIENT_CERT_CONTEXT macro in the lpBuffer parameter of + /// WinHttpSetOption. For more information, see the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. Windows Server 2003 + /// with SP1, Windows XP with SP2 and Windows 2000: This error is not supported. + /// + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_LOGIN_FAILURE + /// + /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new + /// request handle must be created before retrying the function that originally produced this error. + /// + /// + /// + /// ERROR_WINHTTP_NAME_NOT_RESOLVED + /// The server name cannot be resolved. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_SECURE_FAILURE + /// + /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error + /// was encountered, verify through a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more + /// information, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// + /// ERROR_WINHTTP_SHUTDOWN + /// The WinHTTP function support is shut down or unloaded. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request timed out. + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// Not enough memory was available to complete the requested operation. (Windows error code) Windows Server 2003, Windows XP and + /// Windows 2000: The TCP reservation range set with the WINHTTP_OPTION_PORT_RESERVATION option is not large enough to + /// send this request. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// The content length specified in the dwTotalLength parameter does not match the length specified in the Content-Length + /// header. The lpOptional parameter must be NULL and the dwOptionalLength parameter must be zero when the + /// Transfer-Encoding header is present. The Content-Length header cannot be present when the Transfer-Encoding header is present. + /// + /// + /// + /// ERROR_WINHTTP_RESEND_REQUEST + /// + /// The application must call WinHttpSendRequest again due to a redirect or authentication challenge. Windows Server 2003 with + /// SP1, Windows XP with SP2 and Windows 2000: This error is not supported. + /// + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode, that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen, this + /// function can operate either synchronously or asynchronously. In either case, if the request is sent successfully, the application + /// is called back with the completion status set to WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. The + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. Upon + /// receiving the WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE status callback, the application can start to receive a + /// response from the server with WinHttpReceiveResponse. Before then, no other asynchronous functions can be called, otherwise, + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE is returned. + /// + /// + /// An application must not delete or alter the buffer pointed to by lpOptional until the request handle is closed or the call + /// to WinHttpReceiveResponse has completed, because an authentication challenge or redirect that required the optional data could be + /// encountered in the course of receiving the response. If the operation must be aborted with WinHttpCloseHandle, the application + /// must keep the buffer valid until it receives the callback WINHTTP_CALLBACK_STATUS_REQUEST_ERROR with an + /// ERROR_WINHTTP_OPERATION_CANCELLED error code. + /// + /// + /// If WinHTTP is used synchronously, that is, when WINHTP_FLAG_ASYNC was not set in WinHttpOpen, an application is not called + /// with a completion status even if a callback function is registered. While in this mode, the application can call + /// WinHttpReceiveResponse when WinHttpSendRequest returns. + /// + /// + /// The WinHttpSendRequest function sends the specified request to the HTTP server and allows the client to specify additional + /// headers to send along with the request. + /// + /// + /// This function also lets the client specify optional data to send to the HTTP server immediately following the request headers. + /// This feature is generally used for write operations such as PUT and POST. + /// + /// + /// An application can use the same HTTP request handle in multiple calls to WinHttpSendRequest to re-send the same request, + /// but the application must read all data returned from the previous call before calling this function again. + /// + /// + /// The name and value of request headers added with this function are validated. Headers must be well formed. For more information + /// about valid HTTP headers, see RFC 2616. If an invalid header is used, this function fails and GetLastError returns + /// ERROR_INVALID_PARAMETER. The invalid header is not added. + /// + /// + /// Windows 2000: When sending requests from multiple threads, there may be a significant decrease in network and CPU performance. + /// + /// Windows XP and Windows 2000: See Run-Time Requirements. + /// WinHttpSetStatusCallback + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate the progress in sending the request: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_DETECTING_PROXY (not implemented) + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE (only in asynchronous mode) + /// + /// + /// WINHTTP_CALLBACK_STATUS_REDIRECT + /// + /// + /// WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + /// + /// + /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + /// + /// + /// Note On Windows 7 and Windows Server 2008 R2, all of the following notifications are deprecated. + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESOLVING_NAME + /// + /// + /// WINHTTP_CALLBACK_STATUS_NAME_RESOLVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// + /// If the server closes the connection, the following notifications are also sent, provided that they have been set in the + /// dwNotificationFlags parameter of WinHttpSetStatusCallback: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// Support for Greater Than 4-GB Upload + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp supports uploading files up to the size of a LARGE_INTEGER (2^64 + /// bytes) using the Content-Length header. Payload lengths specified in the call to WinHttpSendRequest are limited to the + /// size of a DWORD (2^32 bytes). To upload data to a URL larger than a DWORD, the application must provide the length + /// in the Content-Length header of the request. In this case, the WinHttp client application calls WinHttpSendRequest with + /// the dwTotalLength parameter set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH. + /// + /// + /// If the Content-Length header specifies a length less than a 2^32, the application must also specify the content length in the + /// call to WinHttpSendRequest. If the dwTotalLength parameter does not match the length specified in the + /// Content-Length header, the call fails and returns ERROR_INVALID_PARAMETER. + /// + /// + /// The Content-Length header can be added in the call to WinHttpAddRequestHeaders, or it can be specified in the lpszHeader + /// parameter of WinHttpSendRequest as shown in the following code example. + /// + /// + /// BOOL fRet = WinHttpSendRequest( hReq, L"Content-Length: 68719476735\r\n", -1L, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, pMyContent); + /// + /// Transfer-Encoding Header + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent + /// to the server. When the Transfer-Encoding header is present on the WinHttp request, the dwTotalLength parameter in the + /// call to WinHttpSendRequest is set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH and the application sends the entity body + /// in one or more calls to WinHttpWriteData. The lpOptional parameter of WinHttpSendRequest must be NULL and + /// the dwOptionLength parameter must be zero, otherwise an ERROR_WINHTTP_INVALID_PARAMETER error is returned. To + /// terminate the chunked data transfer, the application generates a zero length chunk and sends it in the last call to WinHttpWriteData. + /// + /// Examples + /// + /// The following code example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that + /// header to the server. + /// + /// + /// BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // Place additional code here. // Report errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsendrequest BOOL WinHttpSendRequest( [in] HINTERNET + // hRequest, [in, optional] LPCWSTR lpszHeaders, [in] DWORD dwHeadersLength, [in, optional] LPVOID lpOptional, [in] DWORD + // dwOptionalLength, [in] DWORD dwTotalLength, [in] DWORD_PTR dwContext ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSendRequest")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSendRequest(HINTERNET hRequest, [Optional, MarshalAs(UnmanagedType.LPWStr)] string lpszHeaders, + [Optional] int dwHeadersLength, [In, Optional] IntPtr lpOptional, [Optional] uint dwOptionalLength, [Optional] uint dwTotalLength, + [In, Optional] IntPtr dwContext); + + /// The WinHttpSetCredentials function passes the required authorization credentials to the server. + /// Valid HINTERNET handle returned by WinHttpOpenRequest. + /// + /// + /// An unsigned integer that specifies a flag that contains the authentication target. Can be one of the values in the following table. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_TARGET_SERVER + /// Credentials are passed to a server. + /// + /// + /// WINHTTP_AUTH_TARGET_PROXY + /// Credentials are passed to a proxy. + /// + /// + /// + /// + /// + /// An unsigned integer that specifies a flag that contains the authentication scheme. Must be one of the supported authentication + /// schemes returned from WinHttpQueryAuthSchemes. The following table identifies the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Use basic authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Use NTLM authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_PASSPORT + /// Use passport authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_DIGEST + /// Use digest authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Selects between NTLM and Kerberos authentication. + /// + /// + /// + /// Pointer to a string that contains a valid user name. + /// Pointer to a string that contains a valid password. The password can be blank. + /// This parameter is reserved and must be NULL. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following + /// table identifies the error codes returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation (Windows error code). + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// The credentials set by WinHttpSetCredentials are only used for a single request; WinHTTP does not cache these credentials + /// for use in subsequent requests. As a result, applications must be written so that they can respond to multiple challenges. If an + /// authenticated connection is re-used, subsequent requests cannot be challenged, but your code should be able to respond to a + /// challenge at any point. + /// + /// For sample code that illustrates the use of WinHttpSetCredentials, see Authentication in WinHTTP. + /// + /// When using Passport authentication and responding to a 407 status code, a WinHTTP application must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials, because WinHttpSetOption is less secure. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetcredentials BOOL WinHttpSetCredentials( [in] + // HINTERNET hRequest, [in] DWORD AuthTargets, [in] DWORD AuthScheme, [in] LPCWSTR pwszUserName, [in] LPCWSTR pwszPassword, [in] + // LPVOID pAuthParams ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetCredentials")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetCredentials(HINTERNET hRequest, WINHTTP_AUTH_TARGET AuthTargets, WINHTTP_AUTH_SCHEME AuthScheme, + [MarshalAs(UnmanagedType.LPWStr)] string pwszUserName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszPassword, IntPtr pAuthParams = default); + + /// The WinHttpSetDefaultProxyConfiguration function sets the default WinHTTP proxy configuration in the registry. + /// A pointer to a variable of type WINHTTP_PROXY_INFO that specifies the default proxy configuration. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// The default proxy configuration set by WinHttpSetDefaultProxyConfiguration can be overridden for an existing WinHTTP + /// session by calling WinHttpSetOption and specifying the WINHTTP_OPTION_PROXY flag. The default proxy configuration can be + /// overridden for a new session by specifying the configuration with the WinHttpOpen function. + /// + /// + /// The dwAccessType member of the WINHTTP_PROXY_INFO structure pointed to by pProxyInfo should be set to + /// WINHTTP_ACCESS_TYPE_NAMED_PROXY if a proxy is specified. Otherwise, it should be set to WINHTTP_ACCESS_TYPE_DEFAULT_PROXY. + /// + /// Any new sessions created after calling this function use the new default proxy configuration. + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetdefaultproxyconfiguration WINHTTPAPI BOOL + // WinHttpSetDefaultProxyConfiguration( [in] WINHTTP_PROXY_INFO *pProxyInfo ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetDefaultProxyConfiguration")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetDefaultProxyConfiguration(in WINHTTP_PROXY_INFO pProxyInfo); + + /// The WinHttpSetOption function sets an Internet option. + /// + /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on + /// what option is being set. For more information about how to determine which handle is appropriate to use in setting a particular + /// option, see the Option Flags. + /// + /// + /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. + /// + /// A pointer to a buffer that contains the option setting. + /// + /// Unsigned long integer value that contains the length of the lpBuffer buffer. The length of the buffer is specified in + /// characters for the following options; for all other options, the length is specified in bytes. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value + /// lower than 15000. + /// + /// + /// + /// ERROR_WINHTTP_OPTION_NOT_SETTABLE + /// The requested option cannot be set, only queried. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value + /// lower than 15000. + /// + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use + /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. + /// + /// + /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. + /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [In] IntPtr lpBuffer, uint dwBufferLength); + + /// The WinHttpSetOption function sets an Internet option. + /// + /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on + /// what option is being set. For more information about how to determine which handle is appropriate to use in setting a particular + /// option, see the Option Flags. + /// + /// + /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. + /// + /// The option setting. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value + /// lower than 15000. + /// + /// + /// + /// ERROR_WINHTTP_OPTION_NOT_SETTABLE + /// The requested option cannot be set, only queried. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value + /// lower than 15000. + /// + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use + /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. + /// + /// + /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. + /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] + public static bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, T value) where T : struct + { + using var mem = SafeHGlobalHandle.CreateFromStructure(value); + return WinHttpSetOption(hInternet, dwOption, mem, mem.Size); + } + + /// + /// The WinHttpSetStatusCallback function sets up a callback function that WinHTTP can call as progress is made during an operation. + /// + /// HINTERNET handle for which the callback is to be set. + /// + /// Pointer to the callback function to call when progress is made. Set this to NULL to remove the existing callback function. + /// For more information about the callback function, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// Unsigned long integer value that specifies flags to indicate which events activate the callback function. + /// The possible values are as follows. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS + /// + /// Activates upon any completion notification. This flag specifies that all notifications required for read or write operations are + /// used. See WINHTTP_STATUS_CALLBACK for a list of completions. + /// + /// + /// + /// WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS + /// Activates upon any status change notification including completions. See WINHTTP_STATUS_CALLBACK for a list of notifications. + /// + /// + /// WINHTTP_CALLBACK_FLAG_RESOLVE_NAME + /// Activates upon beginning and completing name resolution. + /// + /// + /// WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER + /// Activates upon beginning and completing connection to the server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_DETECTING_PROXY + /// Activates when detecting the proxy server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE + /// Activates when completing a query for data. + /// + /// + /// WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE + /// Activates when the response headers are available for retrieval. + /// + /// + /// WINHTTP_CALLBACK_FLAG_READ_COMPLETE + /// Activates upon completion of a data-read operation. + /// + /// + /// WINHTTP_CALLBACK_FLAG_REQUEST_ERROR + /// Activates when an asynchronous error occurs. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SEND_REQUEST + /// Activates upon beginning and completing the sending of a request header with WinHttpSendRequest. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE + /// Activates when a request header has been sent with WinHttpSendRequest. + /// + /// + /// WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE + /// Activates upon completion of a data-post operation. + /// + /// + /// WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE + /// Activates upon beginning and completing the receipt of a resource from the HTTP server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION + /// Activates when beginning and completing the closing of an HTTP connection. + /// + /// + /// WINHTTP_CALLBACK_FLAG_HANDLES + /// Activates when an HINTERNET handle is created or closed. + /// + /// + /// WINHTTP_CALLBACK_FLAG_REDIRECT + /// Activates when the request is redirected. + /// + /// + /// WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE + /// Activates when receiving an intermediate (100 level) status code message from the server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SECURE_FAILURE + /// Activates upon a secure connection failure. + /// + /// + /// + /// This parameter is reserved and must be NULL. + /// + /// + /// If successful, returns a pointer to the previously defined status callback function or NULL if there was no previously + /// defined status callback function. Returns WINHTTP_INVALID_STATUS_CALLBACK if the callback function could not be installed. + /// For extended error information, call GetLastError. Among the error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// If you set the callback on the session handle before creating the request handle, the request handle inherits the callback + /// function pointer from its parent session. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// Both synchronous and asynchronous functions use the callback function to indicate the progress of the request, such as resolving + /// a name, connecting to a server, and so on. The callback function is required for an asynchronous operation. + /// + /// + /// A callback function can be set on any handle and is inherited by derived handles. A callback function can be changed using + /// WinHttpSetStatusCallback, provided there are no pending requests that need to use the previous callback value. However, + /// changing the callback function on a handle does not change the callbacks on derived handles, such as that returned by + /// WinHttpConnect. You must change the callback function at each level. + /// + /// + /// Many WinHTTP functions perform several operations on the network. Each operation can take time to complete and each can fail. + /// + /// + /// After initiating the WinHttpSetStatusCallback function, the callback function can be accessed from within WinHTTP for + /// monitoring time-intensive network operations. + /// + /// + /// At the end of asynchronous processing, the application may set the callback function to NULL. This prevents the client + /// application from receiving additional notifications. + /// + /// The following code snippet shows the recommended method for setting the callback function to NULL. + /// WinHttpSetStatusCallback( hOpen, NULL, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL ); + /// + /// Note, however, that WinHTTP does not synchronize WinHttpSetStatusCallback with worker threads. If a callback originating + /// in another thread is in progress when an application calls WinHttpSetStatusCallback, the application still receives a + /// callback notification even after WinHttpSetStatusCallback successfully sets the callback function to NULL and returns. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to install a callback function for asynchronous WinHTTP functions. The example assumes that a + /// WINHTTP_STATUS_CALLBACK function named "AsyncCallback( )" has been previously implemented: + /// + /// + /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Install the status callback function. WINHTTP_STATUS_CALLBACK isCallback = WinHttpSetStatusCallback( hSession, (WINHTTP_STATUS_CALLBACK)AsyncCallback, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL); // Place additional code here. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetstatuscallback WINHTTPAPI WINHTTP_STATUS_CALLBACK + // WinHttpSetStatusCallback( [in] HINTERNET hInternet, [in] WINHTTP_STATUS_CALLBACK lpfnInternetCallback, [in] DWORD + // dwNotificationFlags, [in] DWORD_PTR dwReserved ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetStatusCallback")] + public static extern IntPtr WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, + WINHTTP_CALLBACK_FLAG dwNotificationFlags, IntPtr dwReserved = default); + + /// The WinHttpSetTimeouts function sets time-outs involved with HTTP transactions. + /// The HINTERNET handle returned by WinHttpOpen or WinHttpOpenRequest. + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for name resolution. If resolution takes + /// longer than this time-out value, the action is canceled. The initial value is zero, meaning no time-out (infinite). + /// + /// + /// Windows Vista and Windows XP: If DNS timeout is specified using NAME_RESOLUTION_TIMEOUT, there is an overhead of one + /// thread per request. + /// + /// + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for server connection requests. If a + /// connection request takes longer than this time-out value, the request is canceled. The initial value is 60,000 (60 seconds). + /// + /// + /// TCP/IP can time out while setting up the socket during the three leg SYN/ACK exchange, regardless of the value of this parameter. + /// + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for sending requests. If sending a request + /// takes longer than this time-out value, the send is canceled. The initial value is 30,000 (30 seconds). + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to receive a response to a request. If a response + /// takes longer than this time-out value, the request is canceled. The initial value is 30,000 (30 seconds). + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// ERROR_INVALID_PARAMETER + /// One or more of the timeout parameters has a negative value other than -1. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// A value of 0 or -1 sets a time-out to wait infinitely. A value greater than 0 sets the time-out value in milliseconds. For + /// example, 30,000 would set the time-out to 30 seconds. All negative values other than -1 cause the function to fail with ERROR_INVALID_PARAMETER. + /// + /// + /// Important If a small timeout is set using WinHttpSetOption and WINHTTP_OPTION_RECEIVE_TIMEOUT, it can override the value + /// set with the dwReceiveTimeout parameter, causing a response to terminate earlier than expected. To avoid this, do not set + /// a timeout with the WINHTTP_OPTION_RECEIVE_TIMEOUT option that is smaller than the value set using dwReceiveTimeout. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// Examples + /// This example shows how to set new time-out values using WinHttpSetTimeouts. + /// + /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpSetTimeouts to set a new time-out values. if (!WinHttpSetTimeouts( hSession, 10000, 10000, 10000, 10000)) printf( "Error %u in WinHttpSetTimeouts.\n", GetLastError()); // PLACE ADDITIONAL CODE HERE. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsettimeouts BOOL WinHttpSetTimeouts( [in] HINTERNET + // hInternet, [in] int nResolveTimeout, [in] int nConnectTimeout, [in] int nSendTimeout, [in] int nReceiveTimeout ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetTimeouts")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetTimeouts(HINTERNET hInternet, int nResolveTimeout = 0, int nConnectTimeout = 60000, int nSendTimeout = 30000, int nReceiveTimeout = 30000); + + /// The WinHttpTimeFromSystemTime function formats a date and time according to the HTTP version 1.0 specification. + /// A pointer to a SYSTEMTIME structure that contains the date and time to format. + /// + /// A pointer to a string buffer that receives the formatted date and time. The buffer should equal to the size, in bytes, of WINHTTP_TIME_FORMAT_BUFSIZE. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError. Error codes + /// include the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP Start Page. + /// Examples + /// + /// The following code example code shows how to convert a SYSTEMTIME structure to a string that contains the time in HTTP format. + /// + /// + /// SYSTEMTIME sTime; LPWSTR pwszTimeStr; // Get the current time. GetSystemTime(&sTime); // Allocate memory for the string. // Note: WINHTTP_TIME_FORMAT_BUFSIZE is a byte count. // Therefore, you must divide the array by // sizeof WCHAR to get the proper string length. pwszTimeStr = new WCHAR[WINHTTP_TIME_FORMAT_BUFSIZE/sizeof(WCHAR)]; // Convert the current time to HTTP format. if(!WinHttpTimeFromSystemTime( &sTime, pwszTimeStr)) { printf( "Error %u in WinHttpTimeFromSystemTime.\n", GetLastError()); } else { // Print the time. printf("Current time is (%S)\n", pwszTimeStr); } // Free the memory. delete [] pwszTimeStr; + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimefromsystemtime BOOL WinHttpTimeFromSystemTime( + // [in] const SYSTEMTIME *pst, [out] LPWSTR pwszTime ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeFromSystemTime")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpTimeFromSystemTime(in SYSTEMTIME pst, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszTime); + + /// The WinHttpTimeToSystemTime function takes an HTTP time/date string and converts it to a SYSTEMTIME structure. + /// + /// Pointer to a null-terminated date/time string to convert. This value must use the format defined in section 3.3 of the RFC2616. + /// + /// Pointer to the SYSTEMTIME structure that receives the converted time. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned is: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// This example shows how to convert an HTTP formatted date to a SYSTEMTIME structure. + /// + /// SYSTEMTIME sTime; LPCWSTR pwszTimeStr = L"Tue, 21 Nov 2000 01:06:53 GMT"; // Convert the HTTP string to a SYSTEMTIME structure. if (!WinHttpTimeToSystemTime( pwszTimeStr, &sTime)) { printf( "Error %u in WinHttpTimeToSystemTime.\n", GetLastError()); } else { // Print the date. printf( "The U.S. formatted date is (%u/%u/%u)\n", sTime.wMonth, sTime.wDay, sTime.wYear); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimetosystemtime BOOL WinHttpTimeToSystemTime( [in] + // LPCWSTR pwszTime, [out] SYSTEMTIME *pst ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeToSystemTime")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpTimeToSystemTime([MarshalAs(UnmanagedType.LPWStr)] string pwszTime, out SYSTEMTIME pst); + + /// The WinHttpWebSocketClose function closes a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: USHORT + /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A detailed reason for the close. + /// + /// + /// Type: DWORD + /// The length of pvReason, in bytes. + /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. + /// + /// + /// Type: DWORD + /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// ERROR_INVALID_SERVER_RESPONSE + /// Invalid data was received from the server. + /// + /// + /// + /// + /// + /// WinHttpWebSocketClose completely closes a WebSocket connection. To close the send channel while still leaving the receive + /// channel open, use WinHttpWebSocketShutdown. + /// + /// + /// It is possible to receive a close frame during regular receive operations. In this case, WinHttpWebSocketClose will also + /// send a close frame. + /// + /// The close timer can be set by the property WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT. The default is 10 seconds. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketclose WINHTTPAPI DWORD + // WinHttpWebSocketClose( [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD dwReasonLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketClose")] + public static extern Win32Error WinHttpWebSocketClose(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, + [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); + + /// The WinHttpWebSocketCompleteUpgrade function completes a WebSocket handshake started by WinHttpSendRequest. + /// + /// Type: HINTERNET + /// HTTP request handle used to send a WebSocket handshake. + /// + /// + /// Type: DWORD_PTR + /// Context to be associated with the new handle. + /// + /// + /// Type: HINTERNET + /// A new WebSocket handle. If NULL, call GetLastError to determine the cause of failure. + /// + /// + /// + /// WinHttpWebSocketCompleteUpgrade can be called on an open HTTP request to get a WebSocket handle for performing other + /// WebSocket operations. + /// + /// + /// The request handle must be marked as a WebSocket upgrade by calling WinHttpSetOption with + /// WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET before sending the request. + /// + /// + /// The caller should check the HTTP status code returned by the server and call this function only if the status code was 101. + /// Calling it with any other status code will result in a failure. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketcompleteupgrade WINHTTPAPI HINTERNET + // WinHttpWebSocketCompleteUpgrade( [in] HINTERNET hRequest, [in, optional] DWORD_PTR pContext ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketCompleteUpgrade")] + public static extern SafeHINTERNET WinHttpWebSocketCompleteUpgrade(HINTERNET hRequest, [In, Optional] IntPtr pContext); + + /// The WinHttpWebSocketQueryCloseStatus function retrieves the close status sent by a server. + /// + /// Type: HINTERNET + /// Handle to a WebSocket + /// + /// + /// Type: USHORT* + /// A pointer to a close status code that will be filled upon return. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A pointer to a buffer that will receive a close reason on return. + /// + /// + /// Type: DWORD + /// The length of the pvReason buffer, in bytes. + /// + /// + /// Type: DWORD* + /// + /// The number of bytes consumed. If pvReason is NULL and dwReasonLength is 0, pdwReasonLengthConsumed + /// will contain the size of the buffer that needs to be allocated by the calling application. + /// + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INSUFFICIENT_BUFFER + /// There is not enough space in pvReason to write the whole close reason. + /// + /// + /// ERROR_INVALID_OPERATION + /// No close frame has been received yet. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// + /// + /// + /// Call WinHttpWebSocketQueryCloseStatus only after WinHttpWebSocketClose succeeds or if WinHttpWebSocketReceive returns WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE. + /// + /// + /// pdwReasonLengthConsumed will never be greater than 123, so allocating buffer with at least 123 will guarantee that + /// ERROR_INSUFFICIENT_BUFFER will never be returned. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketqueryclosestatus WINHTTPAPI DWORD + // WinHttpWebSocketQueryCloseStatus( [in] HINTERNET hWebSocket, [out] USHORT *pusStatus, [out] PVOID pvReason, [in] DWORD + // dwReasonLength, [out] DWORD *pdwReasonLengthConsumed ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketQueryCloseStatus")] + public static extern Win32Error WinHttpWebSocketQueryCloseStatus(HINTERNET hWebSocket, out WINHTTP_WEB_SOCKET_CLOSE_STATUS pusStatus, [Out] IntPtr pvReason, + uint dwReasonLength, out uint pdwReasonLengthConsumed); + + /// The WinHttpWebSocketReceive function receives data from a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: PVOID + /// Pointer to a buffer to receive the data. + /// + /// + /// Type: DWORD + /// Length of pvBuffer, in bytes. + /// + /// + /// Type: DWORD* + /// + /// Pointer to a DWORD that receives the number of bytes read from the connection at the end of the operation. This is set + /// only if WinHttpWebSocketReceive returns NO_ERROR and the handle was opened in synchronous mode. + /// + /// + /// + /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE* + /// + /// The type of a returned buffer. This is only set if WinHttpWebSocketReceive returns NO_ERROR and the handle was + /// opened in synchronous mode. + /// + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending, or the receive channel has already been closed. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// ERROR_INVALID_SERVER_RESPONSE + /// Invalid data was received from the server. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was cancelled because WinHttpWebSocketClose was called to close the connection. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketreceive WINHTTPAPI DWORD + // WinHttpWebSocketReceive( [in] HINTERNET hWebSocket, [out] PVOID pvBuffer, [in] DWORD dwBufferLength, [out] DWORD *pdwBytesRead, + // [out] WINHTTP_WEB_SOCKET_BUFFER_TYPE *peBufferType ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketReceive")] + public static extern Win32Error WinHttpWebSocketReceive(HINTERNET hWebSocket, [Out] IntPtr pvBuffer, uint dwBufferLength, + out uint pdwBytesRead, out WINHTTP_WEB_SOCKET_BUFFER_TYPE peBufferType); + + /// The WinHttpWebSocketSend function sends data over a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a websocket. + /// + /// + /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE + /// Type of buffer. + /// + /// + /// Type: PVOID + /// Pointer to a buffer containing the data to send. Can be NULL only if dwBufferLength is 0. + /// + /// + /// Type: DWORD + /// Length of pvBuffer. + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending, or the send channel has already been closed. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketsend WINHTTPAPI DWORD WinHttpWebSocketSend( + // [in] HINTERNET hWebSocket, [in] WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, [in] PVOID pvBuffer, [in] DWORD dwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketSend")] + public static extern Win32Error WinHttpWebSocketSend(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, + [In, Optional] IntPtr pvBuffer, [In, Optional] uint dwBufferLength); + + /// + /// The WinHttpWebSocketShutdown function sends a close frame to a WebSocket server to close the send channel, but leaves the + /// receive channel open. + /// + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: USHORT + /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A detailed reason for the close. + /// + /// + /// Type: DWORD + /// The length of pvReason, in bytes. + /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. + /// + /// + /// Type: DWORD + /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. + /// + /// + /// + /// Description + /// + /// + /// ERROR_IO_PENDING + /// The operation will complete asynchronously. + /// + /// + /// + /// + /// + /// WinHttpWebSocketShutdown sends a close frame and prevents additional data from being sent over the WebSocket connection. + /// It does not close the receive channel. Use WinHttpWebSocketClose when you want to completely close the connection and prevent any + /// subsequent receive operations. + /// + /// The application is responsible for receiving the close frame from the server (through regular receive operations). + /// + /// After WinHttpWebSocketShutdown is called, the application can call WinHttpWebSocketClose if it does not want to receive a + /// close frame on its own and delegate it to the stack. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketshutdown WINHTTPAPI DWORD + // WinHttpWebSocketShutdown( [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD + // dwReasonLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketShutdown")] + public static extern Win32Error WinHttpWebSocketShutdown(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, + [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); + + /// The WinHttpWriteData function writes request data to an HTTP server. + /// + /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. + /// + /// + /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after + /// WinHttpWriteData completes. + /// + /// Unsigned long integer value that contains the number of bytes to be written to the file. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData + /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must + /// be set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, + /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this + /// function can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to + /// get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion + /// to determine whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR + /// completion indicates that the operation completed asynchronously, but failed. + /// + /// + /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and + /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is + /// called, then the data transfer is aborted. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to + /// the server: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// + /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + /// + /// + /// + /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate + /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be + /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. + /// NTLM and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails + /// if the connection is broken prematurely. + /// + /// + /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for + /// each authentication legs. This can be very inefficient for large data uploads. + /// + /// + /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir + /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is + /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. + /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the + /// same socket as long as the socket is not pooled with concurrent requests competing for it. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// Examples + /// + /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is + /// fictitious and must be replaced with the name of a server for which you have write access. + /// + /// + /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET + // hRequest, [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] IntPtr lpBuffer, uint dwNumberOfBytesToWrite, out uint lpdwNumberOfBytesWritten); + } +} \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.Interfaces.cs b/PInvoke/WinHTTP/WinHTTP.Interfaces.cs new file mode 100644 index 00000000..619b770d --- /dev/null +++ b/PInvoke/WinHTTP/WinHTTP.Interfaces.cs @@ -0,0 +1,11 @@ +namespace Vanara.PInvoke +{ + /// Items from the WinHTTP.dll. + public static partial class WinHTTP + { + /* + IWinHttpRequest implements WinHTTP methods that do not involve events. + IWinHttpRequestEvents implements WinHTTP events and event-based methods. + */ + } +} \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.Structs.cs b/PInvoke/WinHTTP/WinHTTP.Structs.cs new file mode 100644 index 00000000..9e5767b1 --- /dev/null +++ b/PInvoke/WinHTTP/WinHTTP.Structs.cs @@ -0,0 +1,1265 @@ +using System; +using System.Runtime.InteropServices; +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 +{ + /// Items from the WinHTTP.dll. + public static partial class WinHTTP + { + /// Provides a handle to an internet connection. + [StructLayout(LayoutKind.Sequential)] + public struct HINTERNET : IHandle + { + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HINTERNET(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HINTERNET NULL { get; } = default; + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(HINTERNET h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HINTERNET(IntPtr h) => new(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HINTERNET h1, HINTERNET h2) => h1.handle != h2.handle; + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HINTERNET h1, HINTERNET h2) => h1.handle == h2.handle; + + /// + public override bool Equals(object obj) => (obj is IHandle h && handle == h.DangerousGetHandle()) || (obj is IntPtr p && handle == p); + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// The HTTP_VERSION_INFO structure contains the global HTTP version. + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-http_version_info typedef struct _HTTP_VERSION_INFO { DWORD + // dwMajorVersion; DWORD dwMinorVersion; } HTTP_VERSION_INFO, *LPHTTP_VERSION_INFO, *PHTTP_VERSION_INFO; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._HTTP_VERSION_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct HTTP_VERSION_INFO + { + /// Major version number. Must be 1. + public uint dwMajorVersion; + + /// Minor version number. Can be either 1 or 0. + public uint dwMinorVersion; + } + + /// + /// The WINHTTP_ASYNC_RESULT structure contains the result of a call to an asynchronous function. This structure is used with + /// the WINHTTP_STATUS_CALLBACK prototype. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_async_result typedef struct _WINHTTP_ASYNC_RESULT { + // DWORD_PTR dwResult; DWORD dwError; } WINHTTP_ASYNC_RESULT, *LPWINHTTP_ASYNC_RESULT, *PWINHTTP_ASYNC_RESULT; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_ASYNC_RESULT")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_ASYNC_RESULT + { + private readonly nuint _dwResult; + + /// Contains the error code if dwResult indicates that the function failed. + public Win32Error dwError; + + /// + /// + /// Return value from an asynchronous Microsoft Windows HTTP Services (WinHTTP) function. This member can be one of the following values: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// API_RECEIVE_RESPONSE 1 + /// The error occurred during a call to WinHttpReceiveResponse. + /// + /// + /// API_QUERY_DATA_AVAILABLE 2 + /// The error occurred during a call to WinHttpQueryDataAvailable. + /// + /// + /// API_READ_DATA 3 + /// The error occurred during a call to WinHttpReadData. + /// + /// + /// API_WRITE_DATA 4 + /// The error occurred during a call to WinHttpWriteData. + /// + /// + /// API_SEND_REQUEST 5 + /// The error occurred during a call to WinHttpSendRequest. + /// + /// + /// + public ASYNC_RESULT dwResult => (ASYNC_RESULT)_dwResult; + } + + /// + /// The WINHTTP_AUTOPROXY_OPTIONS structure is used to indicate to the WinHttpGetProxyForURL function whether to specify the + /// URL of the Proxy Auto-Configuration (PAC) file or to automatically locate the URL with DHCP or DNS queries to the network. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_autoproxy_options typedef struct + // _WINHTTP_AUTOPROXY_OPTIONS { DWORD dwFlags; DWORD dwAutoDetectFlags; LPCWSTR lpszAutoConfigUrl; LPVOID lpvReserved; DWORD + // dwReserved; BOOL fAutoLogonIfChallenged; } WINHTTP_AUTOPROXY_OPTIONS, *PWINHTTP_AUTOPROXY_OPTIONS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_AUTOPROXY_OPTIONS")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_AUTOPROXY_OPTIONS + { + /// + /// Mechanisms should be used to obtain the PAC file. + /// + /// + /// Value + /// Meaning + /// + /// + /// + /// + /// WINHTTP_AUTOPROXY_ALLOW_STATIC + /// Enables proxy detection via static configuration. + /// + /// + /// WINHTTP_AUTOPROXY_AUTO_DETECT + /// Attempt to automatically discover the URL of the PAC file using both DHCP and DNS queries to the local network. + /// + /// + /// WINHTTP_AUTOPROXY_CONFIG_URL + /// Download the PAC file from the URL specified by lpszAutoConfigUrl in the WINHTTP_AUTOPROXY_OPTIONS structure. + /// + /// + /// WINHTTP_AUTOPROXY_HOST_KEEPCASE + /// Maintains the case of the hostnames passed to the PAC script. This is the default behavior. + /// + /// + /// WINHTTP_AUTOPROXY_HOST_LOWERCASE + /// Converts hostnames to lowercase before passing them to the PAC script. + /// + /// + /// WINHTTP_AUTOPROXY_NO_CACHE_CLIENT + /// Disables querying a host to proxy cache of script execution results in the current process. + /// + /// + /// WINHTTP_AUTOPROXY_NO_CACHE_SVC + /// Disables querying a host to proxy cache of script execution results in the autoproxy service. + /// + /// + /// WINHTTP_AUTOPROXY_NO_DIRECTACCESS + /// Disables querying Direct Access proxy settings for this request. + /// + /// + /// WINHTTP_AUTOPROXY_RUN_INPROCESS + /// + /// Executes the Web Proxy Auto-Discovery (WPAD) protocol in-process instead of delegating to an out-of-process WinHTTP AutoProxy + /// Service, if available. This flag must be combined with one of the other flags. This option has no effect when passed to WinHttpGetProxyForUrlEx. + /// + /// + /// + /// WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY + /// + /// By default, WinHTTP is configured to fall back to auto-discover a proxy in-process. If this fallback behavior is undesirable + /// in the event that an out-of-process discovery fails, it can be disabled using this flag. This option has no effect when + /// passed to WinHttpGetProxyForUrlEx. + /// + /// + /// + /// WINHTTP_AUTOPROXY_SORT_RESULTS + /// Orders the proxy results based on a heuristic placing the fastest proxies first. + /// + /// + /// + public WINHTTP_AUTOPROXY dwFlags; + + /// + /// + /// If dwFlags includes the WINHTTP_AUTOPROXY_AUTO_DETECT flag, then dwAutoDetectFlags specifies what protocols are + /// to be used to locate the PAC file. If both the DHCP and DNS auto detect flags are specified, then DHCP is used first; if no + /// PAC URL is discovered using DHCP, then DNS is used. + /// + /// If dwFlags does not include the WINHTTP_AUTOPROXY_AUTO_DETECT flag, then dwAutoDetectFlags must be zero. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTO_DETECT_TYPE_DHCP + /// Use DHCP to locate the proxy auto-configuration file. + /// + /// + /// WINHTTP_AUTO_DETECT_TYPE_DNS_A + /// + /// Use DNS to attempt to locate the proxy auto-configuration file at a well-known location on the domain of the local computer. + /// + /// + /// + /// + public WINHTTP_AUTO_DETECT_TYPE dwAutoDetectFlags; + + /// + /// + /// If dwFlags includes the WINHTTP_AUTOPROXY_CONFIG_URL flag, the lpszAutoConfigUrl must point to a + /// null-terminated Unicode string that contains the URL of the proxy auto-configuration (PAC) file. + /// + /// If dwFlags does not include the WINHTTP_AUTOPROXY_CONFIG_URL flag, then lpszAutoConfigUrl must be NULL. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszAutoConfigUrl; + + /// Reserved for future use; must be NULL. + public IntPtr lpvReserved; + + /// Reserved for future use; must be zero. + public uint dwReserved; + + /// + /// + /// Specifies whether the client's domain credentials should be automatically sent in response to an NTLM or Negotiate + /// Authentication challenge when WinHTTP requests the PAC file. + /// + /// + /// If this flag is TRUE, credentials should automatically be sent in response to an authentication challenge. If this flag is + /// FALSE and authentication is required to download the PAC file, the WinHttpGetProxyForUrl function fails. + /// + /// + [MarshalAs(UnmanagedType.Bool)] + public bool fAutoLogonIfChallenged; + } + + /// + /// The WINHTTP_CERTIFICATE_INFO structure contains certificate information returned from the server. This structure is used + /// by the WinHttpQueryOption function. + /// + /// + /// + /// The WINHTTP_CERTIFICATE_INFO structure contains information on the certificate returned by the server when the connection + /// uses SSL/TLS. The WinHttpQueryOption function returns the WINHTTP_CERTIFICATE_INFO structure when the dwOption + /// parameter passed to the WinHttpQueryOption function is set to WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT. For more + /// information, see Option Flags. + /// + /// + /// The WinHttpQueryOption function does not set the lpszProtocolName, lpszSignatureAlgName, and + /// lpszEncryptionAlgName members of the WINHTTP_CERTIFICATE_INFO structure, so these member are always returned as NULL. + /// + /// + /// Once the application no longer needs the returned WINHTTP_CERTIFICATE_INFO structure, the LocalFree function should be + /// called to free any pointers returned in the structure. The structure members containing pointers that are not NULL and need to be + /// freed are lpszSubjectInfo and lpszIssuerInfo. + /// + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the Windows HTTP Services start page. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_certificate_info typedef struct + // _WINHTTP_CERTIFICATE_INFO { FILETIME ftExpiry; FILETIME ftStart; LPWSTR lpszSubjectInfo; LPWSTR lpszIssuerInfo; LPWSTR + // lpszProtocolName; LPWSTR lpszSignatureAlgName; LPWSTR lpszEncryptionAlgName; DWORD dwKeySize; } WINHTTP_CERTIFICATE_INFO, *PWINHTTP_CERTIFICATE_INFO; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_CERTIFICATE_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_CERTIFICATE_INFO + { + /// A FILETIME structure that contains the date the certificate expires. + public FILETIME ftExpiry; + + /// A FILETIME structure that contains the date the certificate becomes valid. + public FILETIME ftStart; + + /// + /// A pointer to a buffer that contains the name of the organization, site, and server for which the certificate was issued. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszSubjectInfo; + + /// A pointer to a buffer that contains the name of the organization, site, and server that issued the certificate. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszIssuerInfo; + + /// + /// A pointer to a buffer that contains the name of the protocol used to provide the secure connection. This member is not + /// current used. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProtocolName; + + /// + /// A pointer to a buffer that contains the name of the algorithm used to sign the certificate. This member is not current used. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszSignatureAlgName; + + /// + /// A pointer to a buffer that contains the name of the algorithm used to perform encryption over the secure channel (SSL/TLS) + /// connection. This member is not current used. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszEncryptionAlgName; + + /// The size, in bytes, of the key. + public uint dwKeySize; + } + + /// Represents a connection group. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_connection_group typedef struct + // _WINHTTP_CONNECTION_GROUP { ULONG cConnections; GUID guidGroup; } WINHTTP_CONNECTION_GROUP, *PWINHTTP_CONNECTION_GROUP; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_CONNECTION_GROUP")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_CONNECTION_GROUP + { + /// + /// Type: ULONG + /// The number of connections marked with guidGroup. + /// + public uint cConnections; + + /// + /// Type: GUID + /// A http connection GUID. + /// + public Guid guidGroup; + } + + /// + /// The WINHTTP_CONNECTION_INFO structure contains the source and destination IP address of the request that generated the response. + /// + /// + /// + /// When WinHttpReceiveResponse returns, the application can retrieve the source and destination IP address of the request that + /// generated the response. The application calls WinHttpQueryOption with the WINHTTP_OPTION_CONNECTION_INFO option, and + /// provides the WINHTTP_CONNECTION_INFO structure in the lpBuffer parameter. + /// + /// Examples + /// + /// The following code example shows the call to WinHttpQueryOption. Winsock2.h must be included before Winhttp.h when using the + /// WINHTTP_OPTION_CONNECTION_INFO option. + /// + /// + /// If the original request was redirected, the WINHTTP_CONNECTION_INFO structure contains the IP address and port of the + /// request that resulted from the first non-30X response. + /// + /// + /// WINHTTP_CONNECTION_INFO ConnInfo; DWORD dwConnInfoSize = sizeof(WINHTTP_CONNECTION_INFO); WinHttpQueryOption( hRequest, WINHTTP_OPTION_CONNECTION_INFO, &ConnInfo, &dwConnInfoSize); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_connection_info typedef struct + // _WINHTTP_CONNECTION_INFO { DWORD cbSize; SOCKADDR_STORAGE LocalAddress; SOCKADDR_STORAGE RemoteAddress; } WINHTTP_CONNECTION_INFO, *PWINHTTP_CONNECTION_INFO; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_CONNECTION_INFO")] + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct WINHTTP_CONNECTION_INFO + { + /// The size, in bytes, of the WINHTTP_CONNECTION_INFO structure. + public uint cbSize; + + /// A SOCKADDR_STORAGE structure that contains the local IP address and port of the original request. + public SOCKADDR_STORAGE LocalAddress; + + /// A SOCKADDR_STORAGE structure that contains the remote IP address and port of the original request. + public SOCKADDR_STORAGE RemoteAddress; + } + + /// + /// The WINHTTP_CREDS structure contains user credential information used for server and proxy authentication. + /// Note This structure has been deprecated. Instead, the use of the WINHTTP_CREDS_EX structure is recommended. + /// + /// + /// + /// This structure is used with options WINHTTP_OPTION_GLOBAL_SERVER_CREDS and WINHTTP_OPTION_GLOBAL_PROXY_CREDS option + /// flags. These options require the registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Internet + /// Settings!ShareCredsWithWinHttp. This registry key is not present by default. + /// + /// + /// When it is set, WinINet will send credentials down to WinHTTP. Whenever WinHttp gets an authentication challenge and if there are + /// no credentials set on the current handle, it will use the credentials provided by WinINet. In order to share server credentials + /// in addition to proxy credentials, users needs to set the WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS option flag. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_creds typedef struct tagWINHTTP_CREDS { LPSTR + // lpszUserName; LPSTR lpszPassword; LPSTR lpszRealm; DWORD dwAuthScheme; LPSTR lpszHostName; DWORD dwPort; } WINHTTP_CREDS, *PWINHTTP_CREDS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp.tagWINHTTP_CREDS")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_CREDS + { + /// Pointer to a buffer that contains username. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszUserName; + + /// Pointer to a buffer that contains password. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszPassword; + + /// Pointer to a buffer that contains realm. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszRealm; + + /// + /// A flag that contains the authentication scheme, as one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Use basic authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Use NTLM authentication. + /// + /// + /// INHTTP_AUTH_SCHEME_DIGEST + /// Use digest authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Select between NTLM and Kerberos authentication. + /// + /// + /// + public WINHTTP_AUTH_SCHEME dwAuthScheme; + + /// Pointer to a buffer that contains hostname. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszHostName; + + /// The server connection port. + public uint dwPort; + } + + /// The WINHTTP_CREDS_EX structure contains user credential information used for server and proxy authentication. + /// + /// + /// This structure is used with options WINHTTP_OPTION_GLOBAL_SERVER_CREDS and WINHTTP_OPTION_GLOBAL_PROXY_CREDS option + /// flags. These options require the registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Internet + /// Settings\ShareCredsWithWinHttp. This registry key is not present by default. + /// + /// + /// When it is set, WinINet will send credentials down to WinHTTP. Whenever WinHttp gets an authentication challenge and if there are + /// no credentials set on the current handle, it will use the credentials provided by WinINet. In order to share server credentials + /// in addition to proxy credentials, users needs to set the WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS option flag. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_creds_ex typedef struct tagWINHTTP_CREDS_EX { LPSTR + // lpszUserName; LPSTR lpszPassword; LPSTR lpszRealm; DWORD dwAuthScheme; LPSTR lpszHostName; DWORD dwPort; LPSTR lpszUrl; } + // WINHTTP_CREDS_EX, *PWINHTTP_CREDS_EX; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp.tagWINHTTP_CREDS_EX")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_CREDS_EX + { + /// Pointer to a buffer that contains username. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszUserName; + + /// Pointer to a buffer that contains password. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszPassword; + + /// Pointer to a buffer that contains realm. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszRealm; + + /// + /// A flag that contains the authentication scheme, as one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Use basic authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Use NTLM authentication. + /// + /// + /// INHTTP_AUTH_SCHEME_DIGEST + /// Use digest authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Select between NTLM and Kerberos authentication. + /// + /// + /// + public WINHTTP_AUTH_SCHEME dwAuthScheme; + + /// Pointer to a buffer that contains hostname. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszHostName; + + /// The server connection port. + public uint dwPort; + + /// Pointer to a buffer that contains target URL. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszUrl; + } + + /// The WINHTTP_CURRENT_USER_IE_PROXY_CONFIG structure contains the Internet Explorer proxy configuration information. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_current_user_ie_proxy_config typedef struct + // _WINHTTP_CURRENT_USER_IE_PROXY_CONFIG { BOOL fAutoDetect; LPWSTR lpszAutoConfigUrl; LPWSTR lpszProxy; LPWSTR lpszProxyBypass; } + // WINHTTP_CURRENT_USER_IE_PROXY_CONFIG, *PWINHTTP_CURRENT_USER_IE_PROXY_CONFIG; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_CURRENT_USER_IE_PROXY_CONFIG")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_CURRENT_USER_IE_PROXY_CONFIG + { + /// + /// If TRUE, indicates that the Internet Explorer proxy configuration for the current user specifies "automatically detect settings". + /// + [MarshalAs(UnmanagedType.Bool)] public bool fAutoDetect; + + /// + /// Pointer to a null-terminated Unicode string that contains the auto-configuration URL if the Internet Explorer proxy + /// configuration for the current user specifies "Use automatic proxy configuration". + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszAutoConfigUrl; + + /// + /// Pointer to a null-terminated Unicode string that contains the proxy URL if the Internet Explorer proxy configuration for the + /// current user specifies "use a proxy server". + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProxy; + + /// Pointer to a null-terminated Unicode string that contains the optional proxy by-pass server list. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProxyBypass; + } + + /// Represents an HTTP request header as a name/value string pair. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_extended_header typedef struct + // _WINHTTP_EXTENDED_HEADER { union { PCWSTR pwszName; PCSTR pszName; }; union { PCWSTR pwszValue; PCSTR pszValue; }; } + // WINHTTP_EXTENDED_HEADER, *PWINHTTP_EXTENDED_HEADER; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_EXTENDED_HEADER")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WINHTTP_EXTENDED_HEADER + { + /// A string containing a name. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszName; + + /// A string containing a value. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszValue; + + /// Initializes a new instance of the struct. + /// The name. + /// The value. + public WINHTTP_EXTENDED_HEADER(string name, string value) + { + pszName = name; + pszValue = value; + } + + /// Performs an implicit conversion from to . + /// The tuple. + /// The result of the conversion. + public static implicit operator WINHTTP_EXTENDED_HEADER((string name, string value) t) => new(t.name, t.value); + } + + /// Represents an HTTP request header name. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_header_name typedef union _WINHTTP_HEADER_NAME { + // PCWSTR pwszName; PCSTR pszName; } WINHTTP_HEADER_NAME, *PWINHTTP_HEADER_NAME; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_HEADER_NAME")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WINHTTP_HEADER_NAME + { + /// A string containing a name. + [MarshalAs(UnmanagedType.LPTStr)] + public string pszName; + } + + /// Represents a collection of connection groups. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_host_connection_group typedef struct + // _WINHTTP_HOST_CONNECTION_GROUP { PCWSTR pwszHost; ULONG cConnectionGroups; PWINHTTP_CONNECTION_GROUP pConnectionGroups; } + // WINHTTP_HOST_CONNECTION_GROUP, *PWINHTTP_HOST_CONNECTION_GROUP; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_HOST_CONNECTION_GROUP")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_HOST_CONNECTION_GROUP + { + /// + /// Type: PCWSTR + /// A string containing the host name. + /// + public StrPtrUni pwszHost; + + /// + /// Type: ULONG + /// The number of elements in pConnectionGroups. + /// + public uint cConnectionGroups; + + /// + /// Type: PWINHTTP_CONNECTION_GROUP + /// An array of WINHTTP_CONNECTION_GROUP objects. + /// + public IntPtr pConnectionGroups; + + /// Gets the list of WINHTTP_CONNECTION_GROUP objects. + public ReadOnlySpan ConnectionGroups => pConnectionGroups.AsReadOnlySpan((int)cConnectionGroups); + } + + /// + /// See the option flag WINHTTP_OPTION_MATCH_CONNECTION_GUID. That option takes as input a + /// WINHTTP_MATCH_CONNECTION_GUID value. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_match_connection_guid typedef struct + // _WINHTTP_MATCH_CONNECTION_GUID { GUID ConnectionGuid; ULONGLONG ullFlags; } WINHTTP_MATCH_CONNECTION_GUID, *PWINHTTP_MATCH_CONNECTION_GUID; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_MATCH_CONNECTION_GUID")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_MATCH_CONNECTION_GUID + { + /// + /// Type: GUID + /// A connection's GUID. + /// + /// When WINHTTP_OPTION_MATCH_CONNECTION_GUID is set on a request, WinHttp attempts to serve the request on a connection + /// matching ConnectionGuid. + /// + /// + public Guid ConnectionGuid; + + /// + /// Type: ULONGLONG + /// Flags. + /// + /// Due to the nature of connection-matching logic, it's possible for an unmarked connection to be assigned to serve the request + /// (if one is encountered before a matching marked connection is). Set ullFlags to + /// WINHTTP_MATCH_CONNECTION_GUID_FLAG_REQUIRE_MARKED_CONNECTION if you don't want an unmarked connection to be matched. + /// When using that flag, if no matching marked connection is found, then a new connection is created, and the request is sent on + /// that connection. + /// + /// + public WINHTTP_MATCH_CONNECTION_GUID_FLAG ullFlags; + } + + /// The WINHTTP_PROXY_INFO structure contains the session or default proxy configuration. + /// + /// + /// This structure is used with WinHttpSetOption and WinHttpQueryOption to get or set the proxy configuration for the current session + /// by specifying the WINHTTP_OPTION_PROXY flag. + /// + /// + /// This structure is used with WinHttpSetDefaultProxyConfiguration and WinHttpGetDefaultProxyConfiguration to get or set the default + /// proxy configuration in the registry. + /// + /// The proxy server list contains one or more of the following strings separated by semicolons or whitespace. + /// + /// ([<scheme>=][<scheme>"://"]<server>[":"<port>]) + /// + /// + /// The proxy bypass list contains one or more server names separated by semicolons or whitespace. The proxy bypass list can also + /// contain the string "<local>" to indicate that all local intranet sites are bypassed. Local intranet sites are considered to + /// be all servers that do not contain a period in their name. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_info typedef struct _WINHTTP_PROXY_INFO { + // DWORD dwAccessType; LPWSTR lpszProxy; LPWSTR lpszProxyBypass; } WINHTTP_PROXY_INFO, *LPWINHTTP_PROXY_INFO, *PWINHTTP_PROXY_INFO; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_PROXY_INFO + { + /// + /// Unsigned long integer value that contains the access type. This can be one of the following values: + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_ACCESS_TYPE_NO_PROXY + /// Internet accessed through a direct connection. + /// + /// + /// WINHTTP_ACCESS_TYPE_DEFAULT_PROXY + /// Applies only when setting proxy information. + /// + /// + /// WINHTTP_ACCESS_TYPE_NAMED_PROXY + /// Internet accessed using a proxy. + /// + /// + /// + public WINHTTP_ACCESS_TYPE dwAccessType; + + /// Pointer to a string value that contains the proxy server list. + public StrPtrUni lpszProxy; + + /// Pointer to a string value that contains the proxy bypass list. + public StrPtrUni lpszProxyBypass; + + /// Frees the memory tied to the strings in this structure. + public void FreeMemory() + { + Marshal.FreeHGlobal((IntPtr)lpszProxy); + Marshal.FreeHGlobal((IntPtr)lpszProxyBypass); + lpszProxy = lpszProxyBypass = default; + } + } + + /// The WINHTTP_PROXY_RESULT structure contains collection of proxy result entries provided by WinHttpGetProxyResult. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_result typedef struct _WINHTTP_PROXY_RESULT { + // DWORD cEntries; WINHTTP_PROXY_RESULT_ENTRY *pEntries; } WINHTTP_PROXY_RESULT; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_RESULT")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_PROXY_RESULT + { + /// The number of entries in the pEntries array. + public uint cEntries; + + /// A pointer to an array of WINHTTP_PROXY_RESULT_ENTRY structures. + public IntPtr pEntries; + + /// An array of WINHTTP_PROXY_RESULT_ENTRY structures. + public WINHTTP_PROXY_RESULT_ENTRY[] Entries => pEntries.ToArray((int)cEntries); + } + + /// The WINHTTP_PROXY_RESULT_ENTRY structure contains a result entry from a call to WinHttpGetProxyResult. + /// This structure is stored in an array inside of a WINHTTP_PROXY_RESULT structure. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_result_entry typedef struct + // _WINHTTP_PROXY_RESULT_ENTRY { BOOL fProxy; BOOL fBypass; INTERNET_SCHEME ProxyScheme; PWSTR pwszProxy; INTERNET_PORT ProxyPort; } WINHTTP_PROXY_RESULT_ENTRY; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_RESULT_ENTRY")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_PROXY_RESULT_ENTRY + { + /// + /// A BOOL that whether a result is from a proxy. It is set to TRUE if the result contains a proxy or FALSE + /// if the result does not contain a proxy. + /// + [MarshalAs(UnmanagedType.Bool)] + public bool fProxy; + + /// + /// A BOOL that indicates if the result is bypassing a proxy (on an intranet). It is set to TRUE if the result is + /// bypassing a proxy or FALSE if all traffic is direct. This parameter applies only if fProxy is FALSE. + /// + [MarshalAs(UnmanagedType.Bool)] + public bool fBypass; + + /// An INTERNET_SCHEME value that specifies the scheme of the proxy. + public INTERNET_SCHEME ProxyScheme; + + /// A string that contains the hostname of the proxy. + [MarshalAs(UnmanagedType.LPWStr)] + public string pwszProxy; + + /// An INTERNET_PORT value that specifies the port of the proxy. + public INTERNET_PORT ProxyPort; + } + + /// + [PInvokeData("winhttp.h")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_PROXY_SETTINGS + { + /// + public uint dwStructSize; + /// + public uint dwFlags; + /// + public uint dwCurrentSettingsVersion; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszConnectionName; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszProxy; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszProxyBypass; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszAutoconfigUrl; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszAutoconfigSecondaryUrl; + /// + public uint dwAutoDiscoveryFlags; + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pwszLastKnownGoodAutoConfigUrl; + /// + public uint dwAutoconfigReloadDelayMins; + /// + public FILETIME ftLastKnownDetectTime; + /// + public uint dwDetectedInterfaceIpCount; + /// + public IntPtr pdwDetectedInterfaceIp; + /// + public uint cNetworkKeys; + /// + public IntPtr pNetworkKeys; + } + + /// + public struct WINHTTP_PROXY_NETWORKING_KEY + { + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] + public byte[] pbBuffer; + } + + /// Represents a description of the current state of WinHttp's connections. Retrieved via WinHttpQueryConnectionGroup. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_query_connection_group_result typedef struct + // _WINHTTP_QUERY_CONNECTION_GROUP_RESULT { ULONG cHosts; PWINHTTP_HOST_CONNECTION_GROUP pHostConnectionGroups; } + // WINHTTP_QUERY_CONNECTION_GROUP_RESULT, *PWINHTTP_QUERY_CONNECTION_GROUP_RESULT; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_QUERY_CONNECTION_GROUP_RESULT")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_QUERY_CONNECTION_GROUP_RESULT + { + /// + /// Type: ULONG + /// The number of elements in pHostConnectionGroups. + /// + public uint cHosts; + + /// + /// Type: PWINHTTP_HOST_CONNECTION_GROUP + /// An array of WINHTTP_HOST_CONNECTION_GROUP objects. + /// + public IntPtr pHostConnectionGroups; + + /// + /// Gets a list of WINHTTP_HOST_CONNECTION_GROUP objects. + /// + public ReadOnlySpan HostConnectionGroups => pHostConnectionGroups.AsReadOnlySpan((int)cHosts); + } + + /// The WINHTTP_REQUEST_STATS structure contains a variety of statistics for a request. + /// + /// This structure is used with WinHttpQueryOption to retrieve statistics for a request by specifying the + /// WINHTTP_OPTION_REQUEST_STATS flag. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_request_stats typedef struct _WINHTTP_REQUEST_STATS + // { ULONGLONG ullFlags; ULONG ulIndex; ULONG cStats; ULONGLONG rgullStats[WinHttpRequestStatMax]; } WINHTTP_REQUEST_STATS, *PWINHTTP_REQUEST_STATS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_REQUEST_STATS")] + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct WINHTTP_REQUEST_STATS + { + /// + /// Flags containing details on how the request was made. The following flags are available. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_TCP_FAST_OPEN + /// TCP Fast Open occurred. + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_TLS_SESSION_RESUMPTION + /// TLS Session Resumption occurred. + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_TLS_FALSE_START + /// TLS False Start occurred. + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_PROXY_TLS_SESSION_RESUMPTION + /// TLS Session Resumption occurred for the proxy connection. + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_PROXY_TLS_FALSE_START + /// TLS False Start occurred for the proxy connection. + /// + /// + /// WINHTTP_REQUEST_STAT_FLAG_FIRST_REQUEST + /// This is the first request on the connection. + /// + /// + /// + public WINHTTP_REQUEST_STAT_FLAG ullFlags; + + /// + /// The index of the request on the connection. This indicates how many prior requests were sent over the shared connection. + /// + public uint ulIndex; + + /// + /// Unsigned long integer value that contains the number of statistics to retrieve. This should generally be set to WinHttpRequestStatLast. + /// + public uint cStats; + + /// Array of unsigned long long integer values that will contain the returned statistics, indexed by WINHTTP_REQUEST_STAT_ENTRY. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public ulong[] rgullStats; + } + + /// The WINHTTP_REQUEST_TIMES structure contains a variety of timing information for a request. + /// + /// This structure is used with WinHttpQueryOption to retrieve timing information for a request by specifying the + /// WINHTTP_OPTION_REQUEST_TIMES flag. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_request_times typedef struct _WINHTTP_REQUEST_TIMES + // { ULONG cTimes; ULONGLONG rgullTimes[WinHttpRequestTimeMax]; } WINHTTP_REQUEST_TIMES, *PWINHTTP_REQUEST_TIMES; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_REQUEST_TIMES")] + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct WINHTTP_REQUEST_TIMES + { + /// + /// Unsigned long integer value that contains the number of timings to retrieve. This should generally be set to WinHttpRequestTimeLast. + /// + public uint cTimes; + + /// + /// Array of unsigned long long integer values that will contain the returned timings, indexed by WINHTTP_REQUEST_TIME_ENTRY. + /// Times are measured as performance counter values; for more information, see QueryPerformanceCounter. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public ulong[] rgullTimes; + } + + /// The WINHTTP_SECURITY_INFO structure contains the SChannel connection and cipher information for a request. + /// + /// This structure is used with WinHttpQueryOption to retrieve security information for a request by specifying the + /// WINHTTP_OPTION_SECURITY_INFO flag. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_security_info typedef struct _WINHTTP_SECURITY_INFO + // { SecPkgContext_ConnectionInfo ConnectionInfo; SecPkgContext_CipherInfo CipherInfo; } WINHTTP_SECURITY_INFO, *PWINHTTP_SECURITY_INFO; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_SECURITY_INFO")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_SECURITY_INFO + { + /// SecPkgContext_ConnectionInfo containing the SChannel connection information for the request. + public SecPkgContext_ConnectionInfo ConnectionInfo; + + /// SecPkgContext_CipherInfo containing the SChannel cipher information for the request. + public SecPkgContext_CipherInfo CipherInfo; + } + + /// + /// The URL_COMPONENTS structure contains the constituent parts of a URL. This structure is used with the WinHttpCrackUrl and + /// WinHttpCreateUrl functions. + /// + /// + /// + /// For the WinHttpCrackUrl function, if a pointer member and its corresponding length member are both zero, that component of the + /// URL is not returned. If the pointer member is NULL but the length member is not zero, both the pointer and length members + /// are returned. If both pointer and corresponding length members are nonzero, the pointer member points to a buffer where the + /// component is copied. All escape sequences can be removed from a component, depending on the dwFlags parameter of WinHttpCrackUrl. + /// + /// + /// For the WinHttpCreateUrl function, the pointer members should be NULL if the component of the URL is not required. If the + /// corresponding length member is zero, the pointer member is the pointer to a zero-terminated string. If the length member is not + /// zero, it is the string length of the corresponding pointer member. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-url_components typedef struct _WINHTTP_URL_COMPONENTS { + // DWORD dwStructSize; LPWSTR lpszScheme; DWORD dwSchemeLength; INTERNET_SCHEME nScheme; LPWSTR lpszHostName; DWORD dwHostNameLength; + // INTERNET_PORT nPort; LPWSTR lpszUserName; DWORD dwUserNameLength; LPWSTR lpszPassword; DWORD dwPasswordLength; LPWSTR lpszUrlPath; + // DWORD dwUrlPathLength; LPWSTR lpszExtraInfo; DWORD dwExtraInfoLength; } URL_COMPONENTS, *LPURL_COMPONENTS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_URL_COMPONENTS")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_URL_COMPONENTS + { + /// + /// Size of this structure, in bytes. Used for version checking. The size of this structure must be set to initialize this + /// structure properly. + /// + public uint dwStructSize; + + /// Pointer to a string value that contains the scheme name. + public StrPtrUni lpszScheme; + + /// Length of the scheme name, in characters. + public uint dwSchemeLength; + + /// + /// Internet protocol scheme. This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// INTERNET_SCHEME_HTTP 1 + /// The Internet scheme is the HTTP protocol. See RFC 2616 for more information. + /// + /// + /// INTERNET_SCHEME_HTTPS 2 + /// The Internet scheme, HTTPS, is an HTTP protocol that uses secure transaction semantics. + /// + /// + /// + public INTERNET_SCHEME nScheme; + + /// Pointer to a string value that contains the host name. + public StrPtrUni lpszHostName; + + /// Length of the host name, in characters. + public uint dwHostNameLength; + + /// Port number. + public ushort nPort; + + /// Pointer to a string that contains the user name. + public StrPtrUni lpszUserName; + + /// Length of the user name, in characters. + public uint dwUserNameLength; + + /// Pointer to a string that contains the password. + public StrPtrUni lpszPassword; + + /// Length of the password, in characters. + public uint dwPasswordLength; + + /// Pointer to a string that contains the URL path. + public StrPtrUni lpszUrlPath; + + /// Length of the URL path, in characters. + public uint dwUrlPathLength; + + /// Pointer to a string value that contains the extra information, for example, ?something or #something. + public StrPtrUni lpszExtraInfo; + + /// Unsigned long integer value that contains the length of the extra information, in characters. + public uint dwExtraInfoLength; + + /// Initializes a new instance of the struct. + public WINHTTP_URL_COMPONENTS() + { + dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)); + lpszScheme = lpszHostName = lpszUrlPath = lpszUserName = lpszPassword = lpszExtraInfo = default; + nPort = 0; + nScheme = 0; + dwSchemeLength = dwHostNameLength = dwUserNameLength = dwPasswordLength = dwUrlPathLength = dwExtraInfoLength = unchecked((uint)-1); + } + } + + /// + /// The URL_COMPONENTS structure contains the constituent parts of a URL. This structure is used with the WinHttpCrackUrl and + /// WinHttpCreateUrl functions. + /// + /// + /// + /// For the WinHttpCrackUrl function, if a pointer member and its corresponding length member are both zero, that component of the + /// URL is not returned. If the pointer member is NULL but the length member is not zero, both the pointer and length members + /// are returned. If both pointer and corresponding length members are nonzero, the pointer member points to a buffer where the + /// component is copied. All escape sequences can be removed from a component, depending on the dwFlags parameter of WinHttpCrackUrl. + /// + /// + /// For the WinHttpCreateUrl function, the pointer members should be NULL if the component of the URL is not required. If the + /// corresponding length member is zero, the pointer member is the pointer to a zero-terminated string. If the length member is not + /// zero, it is the string length of the corresponding pointer member. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-url_components typedef struct _WINHTTP_URL_COMPONENTS { + // DWORD dwStructSize; LPWSTR lpszScheme; DWORD dwSchemeLength; INTERNET_SCHEME nScheme; LPWSTR lpszHostName; DWORD dwHostNameLength; + // INTERNET_PORT nPort; LPWSTR lpszUserName; DWORD dwUserNameLength; LPWSTR lpszPassword; DWORD dwPasswordLength; LPWSTR lpszUrlPath; + // DWORD dwUrlPathLength; LPWSTR lpszExtraInfo; DWORD dwExtraInfoLength; } URL_COMPONENTS, *LPURL_COMPONENTS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_URL_COMPONENTS")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_URL_COMPONENTS_IN + { + /// + /// Size of this structure, in bytes. Used for version checking. The size of this structure must be set to initialize this + /// structure properly. + /// + public uint dwStructSize; + + /// Pointer to a string value that contains the scheme name. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszScheme; + + /// Length of the scheme name, in characters. + public uint dwSchemeLength; + + /// + /// Internet protocol scheme. This member can be one of the following values. + /// + /// + /// Value + /// Meaning + /// + /// + /// INTERNET_SCHEME_HTTP 1 + /// The Internet scheme is the HTTP protocol. See RFC 2616 for more information. + /// + /// + /// INTERNET_SCHEME_HTTPS 2 + /// The Internet scheme, HTTPS, is an HTTP protocol that uses secure transaction semantics. + /// + /// + /// + public INTERNET_SCHEME nScheme; + + /// Pointer to a string value that contains the host name. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszHostName; + + /// Length of the host name, in characters. + public uint dwHostNameLength; + + /// Port number. + public ushort nPort; + + /// Pointer to a string that contains the user name. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszUserName; + + /// Length of the user name, in characters. + public uint dwUserNameLength; + + /// Pointer to a string that contains the password. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszPassword; + + /// Length of the password, in characters. + public uint dwPasswordLength; + + /// Pointer to a string that contains the URL path. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszUrlPath; + + /// Length of the URL path, in characters. + public uint dwUrlPathLength; + + /// Pointer to a string value that contains the extra information, for example, ?something or #something. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszExtraInfo; + + /// Unsigned long integer value that contains the length of the extra information, in characters. + public uint dwExtraInfoLength; + + /// Initializes a new instance of the struct. + public WINHTTP_URL_COMPONENTS_IN(string scheme = null, INTERNET_SCHEME iScheme = INTERNET_SCHEME.INTERNET_SCHEME_HTTPS, string host = null, + ushort port = 0, string user = null, string pwd = null, string urlPath = null, string extra = null) + { + dwStructSize = (uint)Marshal.SizeOf(typeof(WINHTTP_URL_COMPONENTS)); + lpszScheme = scheme; + lpszHostName = host; + lpszUrlPath = urlPath; + lpszUserName = user; + lpszPassword = pwd; + lpszExtraInfo = extra; + nPort = port; + nScheme = iScheme; + dwSchemeLength = dwHostNameLength = dwUserNameLength = dwPasswordLength = dwUrlPathLength = dwExtraInfoLength = 0; + } + + /// Performs an implicit conversion from to . + /// The value. + /// The result of the conversion. + public static implicit operator WINHTTP_URL_COMPONENTS_IN(WINHTTP_URL_COMPONENTS c) + { + return new(S(c.lpszScheme, c.dwSchemeLength), c.nScheme, S(c.lpszHostName, c.dwHostNameLength), c.nPort, S(c.lpszUserName, c.dwUserNameLength), + S(c.lpszPassword, c.dwPasswordLength), S(c.lpszUrlPath, c.dwUrlPathLength), S(c.lpszExtraInfo, c.dwExtraInfoLength)); + + static string S(StrPtrUni p, uint l) => StringHelper.GetString((IntPtr)p, (int)l, CharSet.Unicode); + } + } + + /// The WINHTTP_WEB_SOCKET_ASYNC_RESULT includes the result status of a WebSocket operation. + /// + /// A WINHTTP_WEB_SOCKET_ASYNC_RESULT structure is passed to the completion callbacks of WebSocket functions such as + /// WinHttpWebSocketSend, WinHttpWebSocketReceive, and WinHttpWebSocketClose when dwInternetStatus is WINHTTP_CALLBACK_STATUS_REQUEST_ERROR. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_web_socket_async_result typedef struct + // _WINHTTP_WEB_SOCKET_ASYNC_RESULT { WINHTTP_ASYNC_RESULT AsyncResult; WINHTTP_WEB_SOCKET_OPERATION Operation; } WINHTTP_WEB_SOCKET_ASYNC_RESULT; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_WEB_SOCKET_ASYNC_RESULT")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_WEB_SOCKET_ASYNC_RESULT + { + /// + /// Type: WINHTTP_ASYNC_RESULT + /// The result of a WebSocket operation. + /// + public WINHTTP_ASYNC_RESULT AsyncResult; + + /// + /// Type: WINHTTP_WEB_SOCKET_OPERATION + /// The type of WebSocket operation. + /// + public WINHTTP_WEB_SOCKET_OPERATION Operation; + } + + /// The WINHTTP_WEB_SOCKET_STATUS enumeration includes the status of a WebSocket operation. + /// + /// + /// A WINHTTP_WEB_SOCKET_STATUS structure is passed to the completion callback of WinHttpWebSocketSend when + /// dwInternetStatus is WINHTTP_CALLBACK_STATUS_READ_COMPLETE. + /// + /// + /// A WINHTTP_WEB_SOCKET_STATUS structure is passed to the completion callback of WinHttpWebSocketReceive when + /// dwInternetStatus is WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE. + /// + /// + /// A WINHTTP_WEB_SOCKET_STATUS structure is passed to the completion callback of WinHttpWebSocketClose when + /// dwInternetStatus is WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE. + /// + /// + /// A WINHTTP_WEB_SOCKET_STATUS structure is passed to the completion callback of WinHttpWebSocketShutdown when + /// dwInternetStatus is WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_web_socket_status typedef struct + // _WINHTTP_WEB_SOCKET_STATUS { DWORD dwBytesTransferred; WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType; } WINHTTP_WEB_SOCKET_STATUS; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_WEB_SOCKET_STATUS")] + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_WEB_SOCKET_STATUS + { + /// + /// Type: DWORD + /// The amount of bytes transferred in the operation. + /// + public uint dwBytesTransferred; + + /// + /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE + /// The type of data in the buffer. + /// + public WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType; + } + + /// Provides a for that is disposed using . + public class SafeHINTERNET : SafeHANDLE + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + public SafeHINTERNET(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeHINTERNET() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator HINTERNET(SafeHINTERNET h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => WinHttpCloseHandle(handle); + } + } +} \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.cs b/PInvoke/WinHTTP/WinHTTP.cs new file mode 100644 index 00000000..410bab52 --- /dev/null +++ b/PInvoke/WinHTTP/WinHTTP.cs @@ -0,0 +1,2863 @@ +using System; +using Vanara.InteropServices; +using static Vanara.PInvoke.Schannel; +using static Vanara.PInvoke.Ws2_32; + +namespace Vanara.PInvoke +{ + /// Items from the WinHTTP.dll. + public static partial class WinHTTP + { + /// The default internet HTTP port. + public const ushort INTERNET_DEFAULT_HTTP_PORT = 80; + + /// The default internet HTTPS port. + public const ushort INTERNET_DEFAULT_HTTPS_PORT = 443; + + /// The default internet port for the specified protocol. + public const ushort INTERNET_DEFAULT_PORT = 0; + + /// + public const WINHTTP_ADDREQ_FLAG WINHTTP_ADDREQ_FLAGS_MASK = (WINHTTP_ADDREQ_FLAG)0xFFFF0000; + + /// + public const WINHTTP_ADDREQ_FLAG WINHTTP_ADDREQ_INDEX_MASK = (WINHTTP_ADDREQ_FLAG)0x0000FFFF; + + /// Default value. + public const string WINHTTP_HEADER_NAME_BY_INDEX = null; + + /// Default value. + public const string WINHTTP_NO_ADDITIONAL_HEADERS = null; + + /// Default value. + public const string WINHTTP_NO_HEADER_INDEX = null; + + /// Default value. + public const string WINHTTP_NO_OUTPUT_BUFFER = null; + + /// Default value. + public const string WINHTTP_NO_REQUEST_DATA = null; + + /// The size of a string buffer to recieve a formatted time. + public const uint WINHTTP_TIME_FORMAT_BUFSIZE = 62; + + /// If the following value is returned by WinHttpSetStatusCallback, then probably an invalid (non-code) address was supplied for the callback. + public static readonly IntPtr WINHTTP_INVALID_STATUS_CALLBACK = new(-1); + + /// Return value from an asynchronous Microsoft Windows HTTP Services (WinHTTP) function. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_ASYNC_RESULT")] + public enum ASYNC_RESULT : ulong + { + /// The error occurred during a call to WinHttpReceiveResponse. + API_RECEIVE_RESPONSE = 1, + + /// The error occurred during a call to WinHttpQueryDataAvailable. + API_QUERY_DATA_AVAILABLE = 2, + + /// The error occurred during a call to WinHttpReadData. + API_READ_DATA = 3, + + /// The error occurred during a call to WinHttpWriteData. + API_WRITE_DATA = 4, + + /// The error occurred during a call to WinHttpSendRequest. + API_SEND_REQUEST = 5, + + /// The error occurred during a call to WinHttpGetProxyForUrl. + API_GET_PROXY_FOR_URL = 6, + } + + /// These constants and corresponding values indicate HTTP status codes returned by servers on the Internet. + [PInvokeData("winhttp.h")] + public enum HTTP_STATUS + { + /// The request can be continued. + HTTP_STATUS_CONTINUE = 100, + + /// The server has switched protocols in an upgrade header. + HTTP_STATUS_SWITCH_PROTOCOLS = 101, + + /// The request completed successfully. + HTTP_STATUS_OK = 200, + + /// The request has been fulfilled and resulted in the creation of a new resource. + HTTP_STATUS_CREATED = 201, + + /// The request has been accepted for processing, but the processing has not been completed. + HTTP_STATUS_ACCEPTED = 202, + + /// The returned meta information in the entity-header is not the definitive set available from the originating server. + HTTP_STATUS_PARTIAL = 203, + + /// The server has fulfilled the request, but there is no new information to send back. + HTTP_STATUS_NO_CONTENT = 204, + + /// + /// The request has been completed, and the client program should reset the document view that caused the request to be sent to + /// allow the user to easily initiate another input action. + /// + HTTP_STATUS_RESET_CONTENT = 205, + + /// The server has fulfilled the partial GET request for the resource. + HTTP_STATUS_PARTIAL_CONTENT = 206, + + /// + /// During a World Wide Web Distributed Authoring and Versioning (WebDAV) operation, this indicates multiple status codes for a + /// single response. The response body contains Extensible Markup Language (XML) that describes the status codes. For more + /// information, see HTTP Extensions for Distributed Authoring. + /// + HTTP_STATUS_WEBDAV_MULTI_STATUS = 207, + + /// The requested resource is available at one or more locations. + HTTP_STATUS_AMBIGUOUS = 300, + + /// + /// The requested resource has been assigned to a new permanent Uniform Resource Identifier (URI), and any future references to + /// this resource should be done using one of the returned URIs. + /// + HTTP_STATUS_MOVED = 301, + + /// The requested resource resides temporarily under a different URI. + HTTP_STATUS_REDIRECT = 302, + + /// + /// The response to the request can be found under a different URI and should be retrieved using a GET HTTP verb on that resource. + /// + HTTP_STATUS_REDIRECT_METHOD = 303, + + /// The requested resource has not been modified. + HTTP_STATUS_NOT_MODIFIED = 304, + + /// The requested resource must be accessed through the proxy given by the location field. + HTTP_STATUS_USE_PROXY = 305, + + /// The redirected request keeps the same HTTP verb. HTTP/1.1 behavior. + HTTP_STATUS_REDIRECT_KEEP_VERB = 307, + + /// The request could not be processed by the server due to invalid syntax. + HTTP_STATUS_BAD_REQUEST = 400, + + /// The requested resource requires user authentication. + HTTP_STATUS_DENIED = 401, + + /// Not implemented in the HTTP protocol. + HTTP_STATUS_PAYMENT_REQ = 402, + + /// The server understood the request, but cannot fulfill it. + HTTP_STATUS_FORBIDDEN = 403, + + /// The server has not found anything that matches the requested URI. + HTTP_STATUS_NOT_FOUND = 404, + + /// The HTTP verb used is not allowed. + HTTP_STATUS_BAD_METHOD = 405, + + /// No responses acceptable to the client were found. + HTTP_STATUS_NONE_ACCEPTABLE = 406, + + /// Proxy authentication required. + HTTP_STATUS_PROXY_AUTH_REQ = 407, + + /// The server timed out waiting for the request. + HTTP_STATUS_REQUEST_TIMEOUT = 408, + + /// + /// The request could not be completed due to a conflict with the current state of the resource. The user should resubmit with + /// more information. + /// + HTTP_STATUS_CONFLICT = 409, + + /// The requested resource is no longer available at the server, and no forwarding address is known. + HTTP_STATUS_GONE = 410, + + /// The server cannot accept the request without a defined content length. + HTTP_STATUS_LENGTH_REQUIRED = 411, + + /// + /// The precondition given in one or more of the request header fields evaluated to false when it was tested on the server. + /// + HTTP_STATUS_PRECOND_FAILED = 412, + + /// The server cannot process the request because the request entity is larger than the server is able to process. + HTTP_STATUS_REQUEST_TOO_LARGE = 413, + + /// The server cannot service the request because the request URI is longer than the server can interpret. + HTTP_STATUS_URI_TOO_LONG = 414, + + /// + /// The server cannot service the request because the entity of the request is in a format not supported by the requested + /// resource for the requested method. + /// + HTTP_STATUS_UNSUPPORTED_MEDIA = 415, + + /// The request should be retried after doing the appropriate action. + HTTP_STATUS_RETRY_WITH = 449, + + /// The server encountered an unexpected condition that prevented it from fulfilling the request. + HTTP_STATUS_SERVER_ERROR = 500, + + /// The server does not support the functionality required to fulfill the request. + HTTP_STATUS_NOT_SUPPORTED = 501, + + /// + /// The server, while acting as a gateway or proxy, received an invalid response from the upstream server it accessed in + /// attempting to fulfill the request. + /// + HTTP_STATUS_BAD_GATEWAY = 502, + + /// The service is temporarily overloaded. + HTTP_STATUS_SERVICE_UNAVAIL = 503, + + /// The request was timed out waiting for a gateway. + HTTP_STATUS_GATEWAY_TIMEOUT = 504, + + /// The server does not support the HTTP protocol version that was used in the request message. + HTTP_STATUS_VERSION_NOT_SUP = 505, + } + + /// Flags that control the operation of this function. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpCreateUrl")] + [Flags] + public enum ICU : uint + { + /// Does not convert unsafe characters to escape sequences. + ICU_NO_ENCODE = 0x20000000, + + /// Converts all %XX sequences to characters, including escape sequences, before the URL is parsed. + ICU_DECODE = 0x10000000, + + /// Does not remove meta sequences (such as "." and "..") from the URL. + ICU_NO_META = 0x08000000, + + /// Encodes spaces only. + ICU_ENCODE_SPACES_ONLY = 0x04000000, + + /// + /// Does not encode or decode characters after "#" or "?", and does not remove trailing white space after "?". If this value is + /// not specified, the entire URL is encoded and trailing white space is removed. + /// + ICU_BROWSER_MODE = 0x02000000, + + /// + /// Encodes any percent signs encountered. By default, percent signs are not encoded. This value is available in Microsoft + /// Internet Explorer 5 and later. + /// + ICU_ENCODE_PERCENT = 0x00001000, + + /// + /// Converts all unsafe characters to their corresponding escape sequences in the path string pointed to by the + /// lpszUrlPath member and in lpszExtraInfo the extra-information string pointed to by the member of the + /// URL_COMPONENTS structure pointed to by the lpUrlComponents parameter. + /// + ICU_ESCAPE = 0x80000000, + + /// + /// The percent character (%) in the IPv6 literal address must be percent escaped when present in the URI. For example, the scope + /// ID FE80::2%3, must appear in the URI as "https://[FE80::2%253]/", where %25 is the hex encoded percent character (%). If the + /// application retrieves the URI from a Unicode API, such as the Winsock WSAAddressToString API, the application must add the + /// escaped version of the percent character (%) in the hostname of the URI. To create the escaped version of the URI, + /// applications call InternetCreateUrl with the dwFlags parameter set to ICU_ESCAPE_AUTHORITY, and the IPv6 hostname specified + /// in the URL components structure specified in the lpUrlComponents parameter. + /// + ICU_ESCAPE_AUTHORITY = 0x00002000, + + /// + /// 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. + /// + ICU_REJECT_USERPWD = 0x00004000, + } + + /// Internet schemes supported by WinHTTP. + [PInvokeData("winhttp.h")] + public enum INTERNET_SCHEME + { + /// An HTTP internet scheme. + INTERNET_SCHEME_HTTP = 1, + + /// An HTTPS (SSL) internet scheme. + INTERNET_SCHEME_HTTPS = 2, + + /// An FTP internet scheme. This scheme is only supported for use in WinHttpGetProxyForUrl and WinHttpGetProxyForUrlEx. + INTERNET_SCHEME_FTP = 3, + + /// A SOCKS internet scheme. This scheme is only supported for use in WINHTTP_PROXY_RESULT_ENTRY. + INTERNET_SCHEME_SOCKS = 4, + } + + /// Contains the security flags for a handle. + [PInvokeData("winhttp.h")] + [Flags] + public enum SECURITY_FLAG : uint + { + /// Uses secure transfers. This is only returned in a call to WinHttpQueryOption. + SECURITY_FLAG_SECURE = 0x00000001, + + /// Uses weak (40-bit) encryption. This is only returned in a call to WinHttpQueryOption. + SECURITY_FLAG_STRENGTH_WEAK = 0x10000000, + + /// Uses medium (56-bit) encryption. This is only returned in a call to WinHttpQueryOption. + SECURITY_FLAG_STRENGTH_MEDIUM = 0x40000000, + + /// Uses strong (128-bit) encryption. This is only returned in a call to WinHttpQueryOption. + SECURITY_FLAG_STRENGTH_STRONG = 0x20000000, + + /// + /// Allows an invalid certificate authority. If this flag is set, the application does not receive a + /// WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA callback. + /// + SECURITY_FLAG_IGNORE_UNKNOWN_CA = 0x00000100, + + /// + /// Allows an invalid certificate date, that is, an expired or not-yet-effective certificate. If this flag is set, the + /// application does not receive a WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID callback. + /// + SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = 0x00002000, + + /// + /// Allows an invalid common name in a certificate; that is, the server name specified by the application does not match the + /// common name in the certificate. If this flag is set, the application does not receive a + /// WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID callback. + /// + SECURITY_FLAG_IGNORE_CERT_CN_INVALID = 0x00001000, + + /// Allows the identity of a server to be established with a non-server certificate (for example, a client certificate). + SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE = 0x00000200, + + /// + /// Allows a weak signature to be ignored. This flag is available in the rollup update for each OS starting with Windows 7 and + /// Windows Server 2008 R2. + /// + SECURITY_FLAG_IGNORE_ALL_CERT_ERRORS = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE + } + + /// The access type. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_INFO")] + public enum WINHTTP_ACCESS_TYPE : uint + { + /// Applies only when setting proxy information. + WINHTTP_ACCESS_TYPE_DEFAULT_PROXY = 0, + + /// Internet accessed through a direct connection. + WINHTTP_ACCESS_TYPE_NO_PROXY = 1, + + /// Internet accessed using a proxy. + WINHTTP_ACCESS_TYPE_NAMED_PROXY = 3, + + /// Internet accessed using an automatic proxy. + WINHTTP_ACCESS_TYPE_AUTOMATIC_PROXY = 4, + } + + /// contains the flags used to modify the semantics of this function. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpAddRequestHeaders")] + [Flags] + public enum WINHTTP_ADDREQ_FLAG : uint + { + /// Adds the header only if it does not already exist; otherwise, an error is returned. + WINHTTP_ADDREQ_FLAG_ADD_IF_NEW = 0x10000000, + + /// Adds the header if it does not exist. Used with WINHTTP_ADDREQ_FLAG_REPLACE. + WINHTTP_ADDREQ_FLAG_ADD = 0x20000000, + + /// + /// 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. + /// + WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA = 0x40000000, + + /// Merges headers of the same name using a semicolon. + WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON = 0x01000000, + + /// Merges headers of the same name. + WINHTTP_ADDREQ_FLAG_COALESCE = WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA, + + /// + /// 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. + /// + WINHTTP_ADDREQ_FLAG_REPLACE = 0x80000000, + } + + /// A flag that contains the authentication scheme. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp.tagWINHTTP_CREDS")] + [Flags] + public enum WINHTTP_AUTH_SCHEME : uint + { + /// Use basic authentication. + WINHTTP_AUTH_SCHEME_BASIC = 0x00000001, + + /// Use NTLM authentication. + WINHTTP_AUTH_SCHEME_NTLM = 0x00000002, + + /// Indicates passport authentication is available. + WINHTTP_AUTH_SCHEME_PASSPORT = 0x00000004, + + /// Use digest authentication. + WINHTTP_AUTH_SCHEME_DIGEST = 0x00000008, + + /// Select between NTLM and Kerberos authentication. + WINHTTP_AUTH_SCHEME_NEGOTIATE = 0x00000010, + } + + /// Specifies a flag that contains the authentication target. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryAuthSchemes")] + [Flags] + public enum WINHTTP_AUTH_TARGET : uint + { + /// Authentication target is a server. Indicates that a 401 status code has been received. + WINHTTP_AUTH_TARGET_SERVER = 0x00000000, + + /// Authentication target is a proxy. Indicates that a 407 status code has been received. + WINHTTP_AUTH_TARGET_PROXY = 0x00000001, + } + + /// Specifies what protocols are to be used to locate the PAC file. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_AUTOPROXY_OPTIONS")] + [Flags] + public enum WINHTTP_AUTO_DETECT_TYPE : uint + { + /// Use DHCP to locate the proxy auto-configuration file. + WINHTTP_AUTO_DETECT_TYPE_DHCP = 0x00000001, + + /// + /// Use DNS to attempt to locate the proxy auto-configuration file at a well-known location on the domain of the local computer. + /// + WINHTTP_AUTO_DETECT_TYPE_DNS_A = 0x00000002, + } + + /// Values for WINHTTP_OPTION_AUTOLOGON_POLICY. + [PInvokeData("winhttp.h")] + public enum WINHTTP_AUTOLOGON_SECURITY_LEVEL : uint + { + /// WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM + WINHTTP_AUTOLOGON_SECURITY_LEVEL_DEFAULT = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM, + + /// An authenticated log on using the default credentials is performed only for requests on the local Intranet. + WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM = 0, + + /// An authenticated log on using the default credentials is performed for all requests. + WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW = 1, + + /// + /// Default credentials are not used. Note that this flag takes effect only if you specify the server by the actual machine name. + /// It will not take effect, if you specify the server by "localhost" or IP address. + /// + WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH = 2, + } + + /// Mechanisms should be used to obtain the PAC file. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_AUTOPROXY_OPTIONS")] + [Flags] + public enum WINHTTP_AUTOPROXY : uint + { + /// Attempt to automatically discover the URL of the PAC file using both DHCP and DNS queries to the local network. + WINHTTP_AUTOPROXY_AUTO_DETECT = 0x00000001, + + /// + /// Download the PAC file from the URL specified by lpszAutoConfigUrl in the WINHTTP_AUTOPROXY_OPTIONS structure. + /// + WINHTTP_AUTOPROXY_CONFIG_URL = 0x00000002, + + /// Maintains the case of the hostnames passed to the PAC script. This is the default behavior. + WINHTTP_AUTOPROXY_HOST_KEEPCASE = 0x00000004, + + /// Converts hostnames to lowercase before passing them to the PAC script. + WINHTTP_AUTOPROXY_HOST_LOWERCASE = 0x00000008, + + /// Enables proxy detection via autoconfig URL. + WINHTTP_AUTOPROXY_ALLOW_AUTOCONFIG = 0x00000100, + + /// Enables proxy detection via static configuration. + WINHTTP_AUTOPROXY_ALLOW_STATIC = 0x00000200, + + /// Enables proxy detection via connection manager. + WINHTTP_AUTOPROXY_ALLOW_CM = 0x00000400, + + /// + /// Executes the Web Proxy Auto-Discovery (WPAD) protocol in-process instead of delegating to an out-of-process WinHTTP AutoProxy + /// Service, if available. This flag must be combined with one of the other flags. This option has no effect when passed to WinHttpGetProxyForUrlEx. + /// + WINHTTP_AUTOPROXY_RUN_INPROCESS = 0x00010000, + + /// + /// By default, WinHTTP is configured to fall back to auto-discover a proxy in-process. If this fallback behavior is undesirable + /// in the event that an out-of-process discovery fails, it can be disabled using this flag. This option has no effect when + /// passed to WinHttpGetProxyForUrlEx. + /// + WINHTTP_AUTOPROXY_RUN_OUTPROCESS_ONLY = 0x00020000, + + /// Disables querying Direct Access proxy settings for this request. + WINHTTP_AUTOPROXY_NO_DIRECTACCESS = 0x00040000, + + /// Disables querying a host to proxy cache of script execution results in the current process. + WINHTTP_AUTOPROXY_NO_CACHE_CLIENT = 0x00080000, + + /// Disables querying a host to proxy cache of script execution results in the autoproxy service. + WINHTTP_AUTOPROXY_NO_CACHE_SVC = 0x00100000, + + /// Orders the proxy results based on a heuristic placing the fastest proxies first. + WINHTTP_AUTOPROXY_SORT_RESULTS = 0x00400000, + } + + /// Specifies flags to indicate which events activate the callback function. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetStatusCallback")] + [Flags] + public enum WINHTTP_CALLBACK_FLAG : uint + { + /// Activates upon beginning and completing name resolution. + WINHTTP_CALLBACK_FLAG_RESOLVE_NAME = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_RESOLVING_NAME | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_NAME_RESOLVED, + + /// Activates upon beginning and completing connection to the server. + WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER, + + /// Activates upon beginning and completing the sending of a request header with WinHttpSendRequest. + WINHTTP_CALLBACK_FLAG_SEND_REQUEST = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_SENDING_REQUEST | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REQUEST_SENT, + + /// Activates upon beginning and completing the receipt of a resource from the HTTP server. + WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, + + /// Activates when beginning and completing the closing of an HTTP connection. + WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED, + + /// Activates when an HINTERNET handle is created or closed. + WINHTTP_CALLBACK_FLAG_HANDLES = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_HANDLE_CREATED | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, + + /// Activates when detecting the proxy server. + WINHTTP_CALLBACK_FLAG_DETECTING_PROXY = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_DETECTING_PROXY, + + /// Activates when the request is redirected. + WINHTTP_CALLBACK_FLAG_REDIRECT = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REDIRECT, + + /// Activates when receiving an intermediate (100 level) status code message from the server. + WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE, + + /// Activates upon a secure connection failure. + WINHTTP_CALLBACK_FLAG_SECURE_FAILURE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, + + /// Activates when a request header has been sent with WinHttpSendRequest. + WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE, + + /// Activates when the response headers are available for retrieval. + WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE, + + /// Activates when completing a query for data. + WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE, + + /// Activates upon completion of a data-read operation. + WINHTTP_CALLBACK_FLAG_READ_COMPLETE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_READ_COMPLETE, + + /// Activates upon completion of a data-post operation. + WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, + + /// Activates when an asynchronous error occurs. + WINHTTP_CALLBACK_FLAG_REQUEST_ERROR = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR, + + /// + WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE, + + /// + /// Activates upon any completion notification. This flag specifies that all notifications required for read or write operations + /// are used. See WINHTTP_STATUS_CALLBACK for a list of completions. + /// + WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS = WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE | + WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE | + WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_READ_COMPLETE | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE | + WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR | WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE, + + /// + /// Activates upon any status change notification including completions. See WINHTTP_STATUS_CALLBACK for a list of notifications. + /// + WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS = 0xffffffff, + } + + /// Specifies the status code that indicates why the callback function is called. + [PInvokeData("winhttp.h", MSDNShortId = "NC:winhttp.WINHTTP_STATUS_CALLBACK")] + [Flags] + public enum WINHTTP_CALLBACK_STATUS : uint + { + /// The connection was successfully closed via a call to WinHttpWebSocketClose. + WINHTTP_CALLBACK_STATUS_CLOSE_COMPLETE = 0x02000000, + + /// Closing the connection to the server. The lpvStatusInformation parameter is NULL. + WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION = 0x00000100, + + /// + /// Successfully connected to the server. The lpvStatusInformation parameter contains a pointer to an LPWSTR that + /// indicates the IP address of the server in dotted notation. + /// + WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER = 0x00000008, + + /// + /// Connecting to the server. The lpvStatusInformation parameter contains a pointer to an LPWSTR that indicates the + /// IP address of the server in dotted notation. + /// + WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER = 0x00000004, + + /// Successfully closed the connection to the server. The lpvStatusInformation parameter is NULL. + WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED = 0x00000200, + + /// + /// Data is available to be retrieved with WinHttpReadData. The lpvStatusInformation parameter points to a DWORD + /// that contains the number of bytes of data available. The dwStatusInformationLength parameter itself is 4 (the size of + /// a DWORD). + /// + WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE = 0x00040000, + + /// Not implemented. + WINHTTP_CALLBACK_STATUS_DETECTING_PROXY = 0x00001000, + + /// + /// The operation initiated by a call to WinHttpGetProxyForUrlEx is complete. Data is available to be retrieved with WinHttpReadData. + /// + WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE = 0x01000000, + + /// + /// This handle value has been terminated. The lpvStatusInformation parameter contains a pointer to the HINTERNET handle. + /// There will be no more callbacks for this handle. + /// + WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING = 0x00000800, + + /// + /// An HINTERNET handle has been created. The lpvStatusInformation parameter contains a pointer to the HINTERNET handle. + /// + WINHTTP_CALLBACK_STATUS_HANDLE_CREATED = 0x00000400, + + /// + /// The response header has been received and is available with WinHttpQueryHeaders. The lpvStatusInformation parameter is NULL. + /// + WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE = 0x00020000, + + /// + /// Received an intermediate (100 level) status code message from the server. The lpvStatusInformation parameter contains + /// a pointer to a DWORD that indicates the status code. + /// + WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE = 0x00008000, + + /// + /// Successfully found the IP address of the server. The lpvStatusInformation parameter contains a pointer to a + /// LPWSTR that indicates the name that was resolved. + /// + WINHTTP_CALLBACK_STATUS_NAME_RESOLVED = 0x00000002, + + /// + /// + /// Data was successfully read from the server. The lpvStatusInformation parameter contains a pointer to the buffer + /// specified in the call to WinHttpReadData. The dwStatusInformationLength parameter contains the number of bytes read. + /// + /// + /// When used by WinHttpWebSocketReceive, the lpvStatusInformation parameter contains a pointer to a + /// WINHTTP_WEB_SOCKET_STATUS structure, and the dwStatusInformationLength parameter indicates the size of lpvStatusInformation. + /// + /// + WINHTTP_CALLBACK_STATUS_READ_COMPLETE = 0x00080000, + + /// Waiting for the server to respond to a request. The lpvStatusInformation parameter is NULL. + WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE = 0x00000040, + + /// + /// An HTTP request is about to automatically redirect the request. The lpvStatusInformation parameter contains a pointer + /// to an LPWSTR 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. + /// + WINHTTP_CALLBACK_STATUS_REDIRECT = 0x00004000, + + /// + /// An error occurred while sending an HTTP request. The lpvStatusInformation parameter contains a pointer to a + /// WINHTTP_ASYNC_RESULT structure. Its dwResult member indicates the ID of the called function and dwError + /// indicates the return value. + /// + WINHTTP_CALLBACK_STATUS_REQUEST_ERROR = 0x00200000, + + /// + /// Successfully sent the information request to the server. The lpvStatusInformation parameter contains a pointer to a + /// DWORD indicating the number of bytes sent. + /// + WINHTTP_CALLBACK_STATUS_REQUEST_SENT = 0x00000020, + + /// + /// Looking up the IP address of a server name. The lpvStatusInformation parameter contains a pointer to the server name + /// being resolved. + /// + WINHTTP_CALLBACK_STATUS_RESOLVING_NAME = 0x00000001, + + /// + /// Successfully received a response from the server. The lpvStatusInformation parameter contains a pointer to a + /// DWORD indicating the number of bytes received. + /// + WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED = 0x00000080, + + /// + /// One or more errors were encountered while retrieving a Secure Sockets Layer (SSL) certificate from the server. The + /// lpvStatusInformation parameter contains a flag. For more information, see the description for lpvStatusInformation. + /// + WINHTTP_CALLBACK_STATUS_SECURE_FAILURE = 0x00010000, + + /// Sending the information request to the server. The lpvStatusInformation parameter is NULL. + WINHTTP_CALLBACK_STATUS_SENDING_REQUEST = 0x00000010, + + /// The request completed successfully. The lpvStatusInformation parameter is NULL. + WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE = 0x00400000, + + /// + WINHTTP_CALLBACK_STATUS_SETTINGS_READ_COMPLETE = 0x20000000, + + /// + WINHTTP_CALLBACK_STATUS_SETTINGS_WRITE_COMPLETE = 0x10000000, + + /// The connection was successfully shut down via a call to WinHttpWebSocketShutdown. + WINHTTP_CALLBACK_STATUS_SHUTDOWN_COMPLETE = 0x04000000, + + /// + /// + /// Data was successfully written to the server. The lpvStatusInformation parameter contains a pointer to a DWORD + /// that indicates the number of bytes written. + /// + /// + /// When used by WinHttpWebSocketSend, the lpvStatusInformation parameter contains a pointer to a + /// WINHTTP_WEB_SOCKET_STATUS structure, and the dwStatusInformationLength parameter indicates the size of lpvStatusInformation. + /// + /// + WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE = 0x00100000, + } + + /// + /// If the dwInternetStatus argument is WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, then lpvStatusInformation points to a + /// DWORD which is a bitwise-OR combination of one or more of the following values. + /// + [PInvokeData("winhttp.h", MSDNShortId = "NC:winhttp.WINHTTP_STATUS_CALLBACK")] + [Flags] + public enum WINHTTP_CALLBACK_STATUS_FLAG : uint + { + /// + /// 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. + /// + WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED = 0x00000001, + + /// SSL certificate is invalid. + WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT = 0x00000002, + + /// SSL certificate was revoked. + WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED = 0x00000004, + + /// The function is unfamiliar with the Certificate Authority that generated the server's certificate. + WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA = 0x00000008, + + /// + /// 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. + /// + WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID = 0x00000010, + + /// SSL certificate date that was received from the server is bad. The certificate is expired. + WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID = 0x00000020, + + /// + WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE = 0x00000040, + + /// The application experienced an internal error loading the SSL libraries. + WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR = 0x80000000, + } + + /// Flags which determine whether WinHTTP will automatically decompress response bodies with compressed Content-Encodings. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_DECOMPRESSION_FLAG : uint + { + /// Decompress Content-Encoding: gzip responses. + WINHTTP_DECOMPRESSION_FLAG_GZIP = 0x00000001, + + /// Decompress Content-Encoding: deflate responses. + WINHTTP_DECOMPRESSION_FLAG_DEFLATE = 0x00000002, + + /// Decompress responses with any supported Content-Encoding. + WINHTTP_DECOMPRESSION_FLAG_ALL = WINHTTP_DECOMPRESSION_FLAG_GZIP | WINHTTP_DECOMPRESSION_FLAG_DEFLATE + } + + /// Specifies which features are disabled. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_DISABLE : uint + { + /// + /// Automatic addition of cookie headers to requests is disabled. Also, returned cookies are not automatically added to the + /// cookie database. Disabling cookies can result in poor performance for Passport authentication. + /// + WINHTTP_DISABLE_COOKIES = 0x00000001, + + /// + /// Automatic redirection is disabled when sending requests with WinHttpSendRequest. If automatic redirection is disabled, an + /// application must register a callback function in order for Passport authentication to succeed. + /// + WINHTTP_DISABLE_REDIRECTS = 0x00000002, + + /// Automatic authentication is disabled. + WINHTTP_DISABLE_AUTHENTICATION = 0x00000004, + + /// + /// Disables keep-alive semantics for the connection. Keep-alive semantics are required for MSN, NTLM, and other types of authentication. + /// + WINHTTP_DISABLE_KEEP_ALIVE = 0x00000008, + } + + /// Specifies whether Passport Authentication in WinHTTP authentication is enabled. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_DISABLE_PASSPORT : uint + { + /// Microsoft Passport authentication is disabled. This is the default. + WINHTTP_DISABLE_PASSPORT_AUTH = 0x00000000, + + /// Passport authentication is enabled. + WINHTTP_ENABLE_PASSPORT_AUTH = 0x10000000, + + /// The Passport keyring is disabled. This is the default. + WINHTTP_DISABLE_PASSPORT_KEYRING = 0x20000000, + + /// The Passport keyring is enabled. + WINHTTP_ENABLE_PASSPORT_KEYRING = 0x40000000, + } + + /// Specifies the features currently enabled. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_ENABLE_SSL : uint + { + /// If enabled, WinHTTP allows SSL revocation. This value can be set only on the request handle. + WINHTTP_ENABLE_SSL_REVOCATION = 0x00000001, + + /// + /// If enabled, WinHTTP temporarily reverts client impersonation for the duration of SSL certificate authentication operations. + /// This value can be set only on the session handle. + /// + WINHTTP_ENABLE_SSL_REVERT_IMPERSONATION = 0x00000002, + } + + /// Flags for WinHttpAddRequestHeadersEx. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpAddRequestHeadersEx")] + [Flags] + public enum WINHTTP_EXTENDED_HEADER_FLAG : ulong + { + /// Indicate that the strings passed in are Unicode strings. + WINHTTP_EXTENDED_HEADER_FLAG_UNICODE = 1 + } + + /// Specifies which secure protocols are acceptable. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_FLAG_SECURE_PROTOCOL : uint + { + /// The SSL 2.0 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 = 0x00000008, + + /// The SSL 3.0 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 = 0x00000020, + + /// The TLS 1.0 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 = 0x00000080, + + /// The TLS 1.1 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 = 0x00000200, + + /// The TLS 1.2 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 = 0x00000800, + + /// The TLS 1.3 protocol can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_3 = 0x00002000, + + /// The Secure Sockets Layer (SSL) 2.0, SSL 3.0, and Transport Layer Security (TLS) 1.0 protocols can be used. + WINHTTP_FLAG_SECURE_PROTOCOL_ALL = WINHTTP_FLAG_SECURE_PROTOCOL_SSL2 | WINHTTP_FLAG_SECURE_PROTOCOL_SSL3 | WINHTTP_FLAG_SECURE_PROTOCOL_TLS1, + } + + /// The type of the HINTERNET handle passed in. + [PInvokeData("winhttp.h")] + public enum WINHTTP_HANDLE_TYPE : uint + { + /// The handle is a session handle. + WINHTTP_HANDLE_TYPE_SESSION = 1, + + /// The handle is a connection handle. + WINHTTP_HANDLE_TYPE_CONNECT = 2, + + /// The handle is a request handle. + WINHTTP_HANDLE_TYPE_REQUEST = 3, + } + + /// Flags for WINHTTP_MATCH_CONNECTION_GUID. + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_MATCH_CONNECTION_GUID")] + [Flags] + public enum WINHTTP_MATCH_CONNECTION_GUID_FLAG : ulong + { + /// + /// If you don't want an unmarked connection to be matched. When using that flag, if no matching marked connection is found, then + /// a new connection is created, and the request is sent on that connection. + /// + WINHTTP_MATCH_CONNECTION_GUID_FLAG_REQUIRE_MARKED_CONNECTION = 0x00000001 + } + + /// The flags that indicate various options affecting the behavior of WinHttpOpen. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpOpen")] + [Flags] + public enum WINHTTP_OPEN_FLAG : uint + { + /// + /// 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. + /// + WINHTTP_FLAG_ASYNC = 0x10000000, + + /// + /// 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 WINHTTP_OPTION_SECURE_PROTOCOLS, it will fail with ERROR_ACCESS_DENIED. Additionally, TLS fallback will + /// be disabled. Note that setting this flag also sets flag WINHTTP_FLAG_ASYNC. + /// + WINHTTP_FLAG_SECURE_DEFAULTS = 0x30000000, + } + + /// + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpOpenRequest")] + [Flags] + public enum WINHTTP_OPENREQ_FLAG : uint + { + /// + /// Uses secure transaction semantics. This translates to using Secure Sockets Layer (SSL)/Transport Layer Security (TLS). + /// + WINHTTP_FLAG_SECURE = 0x00800000, + + /// + /// The string passed in for pwszObjectName is converted from an LPCWSTR to an LPSTR. 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. + /// + WINHTTP_FLAG_ESCAPE_PERCENT = 0x00000004, + + /// + /// The string passed in for pwszObjectName is assumed to consist of valid ANSI characters represented by WCHAR. No + /// check are done for unsafe characters. Windows 7: This option is obsolete. + /// + WINHTTP_FLAG_NULL_CODEPAGE = 0x00000008, + + /// This flag provides the same behavior as WINHTTP_FLAG_REFRESH. + WINHTTP_FLAG_BYPASS_PROXY_CACHE = 0x00000100, + + /// + /// 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. + /// + WINHTTP_FLAG_REFRESH = WINHTTP_FLAG_BYPASS_PROXY_CACHE, + + /// Unsafe characters in the URL passed in for pwszObjectName are not converted to escape sequences. + WINHTTP_FLAG_ESCAPE_DISABLE = 0x00000040, + + /// + /// Unsafe characters in the query component of the URL passed in for pwszObjectName are not converted to escape sequences. + /// + WINHTTP_FLAG_ESCAPE_DISABLE_QUERY = 0x00000080, + } + + /// + /// The following option flags are supported by WinHttpQueryOption and WinHttpSetOption. + /// WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS + /// + /// The default is FALSE. If set to TRUE, WinHTTP does not guarantee progress if status callbacks are blocked by the client application. + /// + /// + /// The client application must take special care to perform minimal operations within the callback without blocking, returning as + /// quickly as possible, and in particular must not wait for any subsequent WinHTTP calls. If it does not follow these guidelines, + /// there is likely to be a negative performance impact or a potential application hang. If used in the prescribed manner, this + /// option may improve performance. + /// + /// + [PInvokeData("winhttp.h")] + public enum WINHTTP_OPTION + { + /// Undocumented. + WINHTTP_OPTION_AGGREGATE_PROXY_CONFIG = 181, + + /// Undocumented. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_ASSURED_NON_BLOCKING_CALLBACKS = 111, + + /// + /// Sets an unsigned long integer value that specifies the Automatic Logon Policy with one of the + /// WINHTTP_AUTOLOGON_SECURITY_LEVEL values. + /// + [CorrespondingType(typeof(WINHTTP_AUTOLOGON_SECURITY_LEVEL), CorrespondingAction.Set)] + WINHTTP_OPTION_AUTOLOGON_POLICY = 77, + + /// + /// When you set this option on a session handle, you must pass the number of connections you wish to open. Then, upon first + /// sending a request, rather than opening only a single connection, WinHttp opens a number of connections in parallel. This can + /// improve the performance of subsequent requests to the same destination, which won't have the overhead of connection establishment. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_BACKGROUND_CONNECTIONS = 172, + + /// Retrieves the pointer to the callback function set with WinHttpSetStatusCallback. + [CorrespondingType(typeof(WINHTTP_STATUS_CALLBACK))] + WINHTTP_OPTION_CALLBACK = 1, + + /// + /// + /// Sets the client certificate context. If an application receives ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED, it must call + /// WinHttpSetOption to supply a certificate before retrying the request. As a part of processing this option, WinHttp calls + /// CertDuplicateCertificateContext on the caller-provided certificate context so that the certificate context can be + /// independently released by the caller. + /// + /// + /// The application should not attempt to close the certificate store with the CERT_CLOSE_STORE_FORCE_FLAG flag + /// in the call to CertCloseStore on the certificate store from which the certificate context was retrieved. An access violation + /// may occur. + /// + /// + /// When the server requests a client certificate, WinHttpSendRequest, or WinHttpReceiveResponse returns an + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED error. If the server requests the certificate but does not require it, the application + /// can specify this option to indicate that it does not have a certificate. The server can choose another authentication scheme + /// or allow anonymous access to the server. The application provides the WINHTTP_NO_CLIENT_CERT_CONTEXT macro in the lpBuffer + /// parameter of WinHttpSetOption as shown in the following code example. + /// + /// + /// BOOL fRet = WinHttpSetOption(hRequest, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0); + /// + /// + /// If the server requires a client certificate, it may send a 403 HTTP status code in response. For more information, see the + /// WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST option. + /// + /// + [CorrespondingType(typeof(Crypt32.CERT_CONTEXT), CorrespondingAction.Set)] + WINHTTP_OPTION_CLIENT_CERT_CONTEXT = 47, + + /// + /// Retrieves a SecPkgContext_IssuerListInfoEx structure when the error from WinHttpSendRequest or WinHttpReceiveResponse is + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED. The issuer list in the structure contains a list of acceptable Certificate Authorities + /// (CA) from the server. The client application can filter the CA list to retrieve the client certificate for SSL authentication. + /// + /// Alternately, if the server requests the client certificate, but does not require it, the application can call + /// WinHttpSetOption with the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. For more information, see the + /// WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. + /// + /// + [CorrespondingType(typeof(SecPkgContext_IssuerListInfoEx), CorrespondingAction.Get)] + WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST = 94, + + /// Sets the code page that is used to process the URL (that is, query string). The default is UTF8. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_CODEPAGE = 68, + + /// + /// Sets a WINHTTP_DISABLE_PASSPORT value that specifies whether Passport Authentication in WinHTTP authentication is enabled. + /// + [CorrespondingType(typeof(WINHTTP_DISABLE_PASSPORT), CorrespondingAction.Set)] + WINHTTP_OPTION_CONFIGURE_PASSPORT_AUTH = 83, + + /// + /// Sets or retrieves an unsigned long integer value that contains the number of timesWinHTTP attempts to connect to a host. + /// Microsoft Windows HTTP Services (WinHTTP) only attempts once per Internet Protocol (IP) address. For example, if you attempt + /// to connect to a multihomed host that has 10 IP addresses and WINHTTP_OPTION_CONNECT_RETRIES is set to 7, then WinHTTP only + /// attempts to connect to the first seven IP address. Given the same set of 10 IP addresses, if WINHTTP_OPTION_CONNECT_RETRIES + /// is set to 20, WinHTTP attempts each of the 10 only once. If a connection attempt still fails after the specified number of + /// attempts, or if the connect timeout expired before then, the request is canceled. The default value for + /// WINHTTP_OPTION_CONNECT_RETRIES is five attempts. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_CONNECT_RETRIES = 4, + + /// + /// Sets or retrieves an unsigned long integer value that contains the time-out value, in milliseconds. Setting this option to + /// infinite (0xFFFFFFFF) will disable this timer. + /// + /// If a TCP connection request takes longer than this time-out value, the request is canceled. The default timeout is 60 + /// seconds. When you are attempting to connect to multiple IP addresses for a single host (a multihomed host), the timeout limit + /// is for each individual connection. + /// + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_CONNECT_TIMEOUT = 3, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_CONNECTION_FILTER = 131, + + /// Undocumented. + [CorrespondingType(typeof(Guid))] + WINHTTP_OPTION_CONNECTION_GUID = 178, + + /// + /// Retrieves the source and destination IP address, and port of the request that generated the response when + /// WinHttpReceiveResponse returns. The application calls WinHttpQueryOption with the WINHTTP_OPTION_CONNECTION_INFO option, and + /// provides the WINHTTP_CONNECTION_INFO structure in the lpBuffer parameter. For more information, see WINHTTP_CONNECTION_INFO. + /// Windows Server 2003 with SP1 and Windows XP with SP2: This flag is obsolete. + /// + [CorrespondingType(typeof(WINHTTP_CONNECTION_INFO))] + WINHTTP_OPTION_CONNECTION_INFO = 93, + + /// + /// Retreives the TCP_INFO_v0 struct for the underlying connection used by the request. The returned struct may contain + /// statistics from prior requests sent over the same connection. This option has been superseded by WINHTTP_OPTION_CONNECTION_STATS_V1. + /// + [CorrespondingType(typeof(TCP_INFO_v0))] + WINHTTP_OPTION_CONNECTION_STATS_V0 = 141, + + /// + /// Retreives the TCP_INFO_v1 struct for the underlying connection used by the request. The returned struct may contain + /// statistics from prior requests sent over the same connection. + /// + [CorrespondingType(typeof(TCP_INFO_v1))] + WINHTTP_OPTION_CONNECTION_STATS_V1 = 150, + + /// + /// Sets or retrieves a DWORD_PTR that contains a pointer to the context value associated with this HINTERNET handle. The value + /// stored in the buffer is used and the WINHTTP_OPTION_CONTEXT_VALUE option flag is assigned a new value. + /// + [CorrespondingType(typeof(IntPtr))] + WINHTTP_OPTION_CONTEXT_VALUE = 45, + + /// + /// Sets a WINHTTP_DECOMPRESSION_FLAG flag value which determine whether WinHTTP will automatically decompress response bodies + /// with compressed Content-Encodings. WinHTTP will also set an appropriate Accept-Encoding header, overriding any supplied by + /// the caller. + /// By default, WinHTTP will deliver compressed responses to the caller unmodified. + /// + [CorrespondingType(typeof(WINHTTP_DECOMPRESSION_FLAG), CorrespondingAction.Set)] + WINHTTP_OPTION_DECOMPRESSION = 118, + + /// + /// Setting this option on a WinHttp session handle allows you to enable/disable whether the server certificate chain is built. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_DISABLE_CERT_CHAIN_BUILDING = 171, + + /// + /// Sets a WINHTTP_DISABLE value that specifies which features are disabled with one or more of the following flags. Be aware + /// that this feature should only be passed to WinHttpSetOption on request handles after the request handle is created with + /// WinHttpOpenRequest, and before the request is sent with WinHttpSendRequest. + /// + [CorrespondingType(typeof(WINHTTP_DISABLE), CorrespondingAction.Set)] + WINHTTP_OPTION_DISABLE_FEATURE = 63, + + /// Undocumented. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_DISABLE_PROXY_LINK_LOCAL_NAME_RESOLUTION = 176, + + /// + /// Prevents WinHTTP from retrying a connection with a lower version of the security protocol when the initial protocol + /// negotiation fails. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_DISABLE_SECURE_PROTOCOL_FALLBACK = 144, + + /// + /// Allows new requests to open an additional HTTP/2 connection when the maximum concurrent stream limit is reached, rather than + /// waiting for the next available stream on an existing connection. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_DISABLE_STREAM_QUEUE = 139, + + /// Sets a WINHTTP_ENABLE_SSL value that specifies the features currently enabled. + [CorrespondingType(typeof(WINHTTP_ENABLE_SSL), CorrespondingAction.Set)] + WINHTTP_OPTION_ENABLE_FEATURE = 79, + + /// + /// Sets a DWORD bitmask of acceptable advanced HTTP versions. + /// Legacy versions of HTTP (1.1 and prior) cannot be disabled using this option. The default is 0x0. + /// + [CorrespondingType(typeof(WINHTTP_PROTOCOL_FLAG), CorrespondingAction.Set)] + WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL = 133, + + /// + /// This option can be set on a WinHttp session handle to allow WinHttp to use the caller-provided client certificate context + /// when HTTP/2 is being used. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_ENABLE_HTTP2_PLUS_CLIENT_CERT = 161, + + /// Undocumented. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_ENABLE_TEST_SIGNING = 174, + + /// + /// Sets a BOOL value that specifies whether tracing is currently enabled. For more information about the trace facility in + /// WinHTTP, see WinHTTP Trace Facility. This option can only be set on a NULL HINTERNET handle. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_ENABLETRACING = 85, + + /// + /// Enables URL percent encoding for path and query string. Alternatively, you can percent encode before calling WinHttp. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_ENCODE_EXTRA = 138, + + /// + /// This option can only be set on a request handle which is still active (sending or receiving). Setting this option will tell + /// WinHttp to stop serving requests on the connection associated with the request handle passed in. The connection will be + /// closed after the request handle this option is called with is completed. This option does not take any parameters. + /// + [CorrespondingType(null, CorrespondingAction.Set)] + WINHTTP_OPTION_EXPIRE_CONNECTION = 143, + + /// + /// Retrieves an unsigned long integer value that contains a Microsoft Windows Sockets error code that was mapped to the + /// ERROR_WINHTTP_* error messages last returned in this thread context. You can pass NULL as the handle value. + /// + [CorrespondingType(typeof(Win32Error), CorrespondingAction.Get)] + WINHTTP_OPTION_EXTENDED_ERROR = 24, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_FAILED_CONNECTION_RETRIES = 162, + + /// + /// By default, when WinHttp sends a request, if there are no available connections to serve the request, WinHttp will attempt to + /// establish a new connection, and the request will be bound to this new connection. When you set this option, such a request + /// will instead be served on the first connection that becomes available, and not necessarily the one being established. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_FIRST_AVAILABLE_CONNECTION = 173, + + /// + /// Takes a pointer to a WINHTTP_CREDS_EX structure with the hInternet function parameter set to NULL. This option requires + /// registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings!ShareCredsWithWinHttp. If this registry key is + /// not set WinHTTP will return error ERROR_WINHTTP_INVALID_OPTION. This registry key is not present by default. When it is set, + /// WinINet will send credentials down to WinHTTP. Whenever WinHttp gets an authentication challenge and if there are no + /// credentials set on the current handle, it will use the credentials provided by WinINet. In order to share server credentials + /// in addition to proxy credentials, users needs to set WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS. + /// + [CorrespondingType(typeof(WINHTTP_CREDS_EX), CorrespondingAction.Set)] + WINHTTP_OPTION_GLOBAL_PROXY_CREDS = 97, + + /// + /// Takes a pointer to a WINHTTP_CREDS_EX structure with the hInternet function parameter set to NULL. This option requires + /// registry key HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings!ShareCredsWithWinHttp. If this registry key is + /// not set WinHTTP will return error ERROR_WINHTTP_INVALID_OPTION. This registry key is not present by default. When it is set, + /// WinINet will send credentials down to WinHTTP. Whenever WinHttp gets an authentication challenge and if there are no + /// credentials set on the current handle, it will use the credentials provided by WinINet. In order to share server credentials + /// in addition to proxy credentials, users needs to set WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS. + /// + [CorrespondingType(typeof(WINHTTP_CREDS_EX), CorrespondingAction.Set)] + WINHTTP_OPTION_GLOBAL_SERVER_CREDS = 98, + + /// Retrieves an unsigned long integer value that contains the type of the HINTERNET handle passed in. + [CorrespondingType(typeof(WINHTTP_HANDLE_TYPE), CorrespondingAction.Get)] + WINHTTP_OPTION_HANDLE_TYPE = 9, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_HEAP_EXTENSION = 157, + + /// + /// Prevents protocol versions other than those enabled by WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL from being used for the request. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_HTTP_PROTOCOL_REQUIRED = 145, + + /// + /// Gets a DWORD indicating which advanced HTTP version was used on a given request. For a list of possible values, see WINHTTP_OPTION_ENABLE_HTTP_PROTOCOL. + /// + [CorrespondingType(typeof(WINHTTP_PROTOCOL_FLAG), CorrespondingAction.Get)] + WINHTTP_OPTION_HTTP_PROTOCOL_USED = 134, + + /// + /// Sets or retrieves an HTTP_VERSION_INFO structure that contains the HTTP version being supported. This is a process-wide + /// option; use NULL for the handle. + /// + [CorrespondingType(typeof(HTTP_VERSION_INFO))] + WINHTTP_OPTION_HTTP_VERSION = 59, + + /// + /// This option can be set on a session handle to have WinHttp use HTTP/2 PING frames as a keepalive mechanism. Callers specify a + /// timeout in milliseconds, and after there is no activity on a connection for that timeout period, WinHttp will begin to send + /// HTTP/2 PING frames. Callers cannot set a timeout value less than 5000 milliseconds. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_HTTP2_KEEPALIVE = 164, + + /// + /// This option can be set on a WinHttp request handle to control how WinHttp behaves when an HTTP/2 response contains a + /// "Transfer-Encoding" header. In such a case, WinHttp will return an error if this option is set to FALSE. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_HTTP2_PLUS_TRANSFER_ENCODING = 169, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_HTTP2_RECEIVE_WINDOW = 183, + + /// + /// Allows secure connections to use security certificates for which the certificate revocation list could not be downloaded. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_IGNORE_CERT_REVOCATION_OFFLINE = 155, + + /// + /// Enables IPv6 fast fallback (Happier Eyeballs) for the connection. This behavior is similar to the Happy Eyeballs behavior + /// described in RFC 6555 for improving connection times on networks where IPv6 is unreliable. + /// + /// + /// If both IPv6 and IPv4 addresses are resolved for a given host, WinHttp will begin by connecting to the first resolved IPv6 + /// address with a short (300ms) timeout. + /// + /// Should that connection fail, WinHttp will attempt to connect to the first resolved IPv4 address with the standard timeout. + /// Should the second connection fail, WinHttp will retry the first resolved IPv6 address with the standard timeout. + /// + /// Should the third connection fail, WinHttp will revert to the default behavior for any remaining addresses, attempting a + /// connection to each one with the standard timeout until a connection is made or no addresses remain. + /// + /// + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_IPV6_FAST_FALLBACK = 140, + + /// Gets whether or not a Proxy Return Connect Response can be retrieved. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Get)] + WINHTTP_OPTION_IS_PROXY_CONNECT_RESPONSE = 104, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_KDC_PROXY_SETTINGS = 136, + + /// Undocumented. + [CorrespondingType(typeof(Guid), CorrespondingAction.Set)] + WINHTTP_OPTION_MATCH_CONNECTION_GUID = 179, + + /// + /// Sets or retrieves an unsigned long integer value that contains the maximum number of connections allowed per HTTP/1.0 server. + /// The default value is INFINITE. + /// Windows Vista with SP1 and Windows Server 2008: This flag is obsolete. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_CONNS_PER_1_0_SERVER = 74, + + /// + /// Sets or retrieves an unsigned long integer value that contains the maximum number of connections allowed per server. The + /// default value is INFINITE. + /// When this option is set to zero, WinHTTP sets the limit on the number of connections to 2. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_CONNS_PER_SERVER = 73, + + /// + /// Sets the maximum number of redirects that WinHTTP follows; the default is 10. This limit prevents unauthorized sites from + /// making the WinHTTP client pause following a large number of redirects. + /// Windows XP with SP1 and Windows 2000 with SP3: This flag is obsolete. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_HTTP_AUTOMATIC_REDIRECTS = 89, + + /// + /// The maximum number of Informational 100-199 status code responses ignored before returning the final status code to the + /// WinHTTP client. Informational 100-199 status codes can be sent by the server before the final status code, and are described + /// in the specification for HTTP/1.1 (for more information, see RFC 2616). The default is 10. + /// Windows XP with SP1 and Windows 2000 with SP3: This flag is obsolete. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_HTTP_STATUS_CONTINUE = 90, + + /// + /// A bound on the amount of data drained from responses in order to reuse a connection, specified in bytes. The default is 1MB. + /// Windows XP with SP1 and Windows 2000 with SP3: This flag is obsolete. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_RESPONSE_DRAIN_SIZE = 92, + + /// + /// A bound set on the maximum size of the header portion of the server response, specified in bytes. This bound protects the + /// client from an unauthorized server attempting to stall the client by sending a response with an infinite amount of header + /// data. The default value is 64KB. + /// Windows XP with SP1 and Windows 2000 with SP3: This flag is obsolete. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_MAX_RESPONSE_HEADER_SIZE = 91, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_NTSERVICE_FLAG_TEST = 175, + + /// Retrieves the parent handle to this handle. + [CorrespondingType(typeof(HINTERNET), CorrespondingAction.Get)] + WINHTTP_OPTION_PARENT_HANDLE = 21, + + /// + /// Retrieves a string that contains the cobranding text provided by the Passport logon server. This option should be retrieved + /// immediately after the logon server responds with a 401 status code. An application should pass in a buffer size, in bytes, + /// that is big enough to hold the returned string. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Get)] + WINHTTP_OPTION_PASSPORT_COBRANDING_TEXT = 81, + + /// + /// Retrieves a string that contains a URL for a cobranding graphic provided by the Passport logon server. This option should be + /// retrieved immediately after the logon server responds with a 401 status code. An application should pass in a buffer size, in + /// bytes, that is big enough to hold the returned string. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Get)] + WINHTTP_OPTION_PASSPORT_COBRANDING_URL = 82, + + /// Sets a read-only option on a request handle that retrieves the Passport return URL. + [CorrespondingType(typeof(IntPtr), CorrespondingAction.Set)] + WINHTTP_OPTION_PASSPORT_RETURN_URL = 87, + + /// + /// Sets the option on a session handle to sign out of any Passport logins. An application should pass in the Passport return URL + /// that was retrieved with WINHTTP_OPTION_PASSPORT_RETURN_URL. All cookies related to the return URL are cleared. + /// + [CorrespondingType(typeof(IntPtr), CorrespondingAction.Set)] + WINHTTP_OPTION_PASSPORT_SIGN_OUT = 86, + + /// Sets or retrieves a string value that contains the password associated with a request handle. + [CorrespondingType(typeof(string))] + WINHTTP_OPTION_PASSWORD = 0x1001, + + /// + /// Sets or retrieves an WINHTTP_PROXY_INFO structure that contains the proxy data on an existing session handle or request + /// handle. When retrieving proxy data, an application must free the lpszProxy and lpszProxyBypass strings contained in this + /// structure (if they are non-NULL) using the GlobalFree function. An application can query for the global proxy data (the + /// default proxy) by passing a NULL handle. + /// + [CorrespondingType(typeof(WINHTTP_PROXY_INFO))] + WINHTTP_OPTION_PROXY = 38, + + /// Undocumented. + [CorrespondingType(typeof(WINHTTP_PROXY_SETTINGS))] + WINHTTP_OPTION_PROXY_CONFIG_INFO = 180, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_PROXY_DISABLE_SERVICE_CALLS = 137, + + /// Sets or retrieves a string value that contains the password used to access the proxy. + [CorrespondingType(typeof(string))] + WINHTTP_OPTION_PROXY_PASSWORD = 0x1003, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_PROXY_RESULT_ENTRY = 39, + + /// + /// Gets the proxy Server Principal Name that WinHTTP supplied to SSPI during authentication. This string value is usefor passing + /// to SspiPromptForCredentials after an authentication failure. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Get)] + WINHTTP_OPTION_PROXY_SPN_USED = 107, + + /// Sets or retrieves a string value that contains the user name used to access the proxy. + [CorrespondingType(typeof(string))] + WINHTTP_OPTION_PROXY_USERNAME = 0x1002, + + /// This option has been deprecated; it has no effect. + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_READ_BUFFER_SIZE = 12, + + /// Sets whether or not the proxy response entity can be retrieved. This option is disabled by default. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_RECEIVE_PROXY_CONNECT_RESPONSE = 103, + + /// + /// Sets or retrieves an unsigned long integer value that contains the timeout value, in milliseconds, to wait to receive all + /// response headers to a request. If WinHTTP fails to receive all the headers within this timeout period, the request is + /// canceled. The default timeout value is 90 seconds. + /// + /// This timeout is checked only when data is received from the socket. As a result, when the timeout expires the client + /// application is not notified until more data arrives from the server. If no data arrives from the server, the delay between + /// the timeout expiration and notification of the client application could be as large as the timeout value set using the + /// dwReceiveTimeout parameter of the WinHttpSetTimeouts function. + /// + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT = 7, + + /// + /// Sets or retrieves an unsigned long integer value that contains the time-out value, in milliseconds, to receive a partial + /// response to a request or read some data. If the response takes longer than this time-out value, the request is canceled. The + /// default timeout value is 30 seconds. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_RECEIVE_TIMEOUT = 6, + + /// + /// Sets the behavior of WinHTTP regarding the handling of a 30x HTTP redirect status code. This option can be set on a session + /// or request handle. + /// + [CorrespondingType(typeof(WINHTTP_OPTION_REDIRECT_POLICY), CorrespondingAction.Set)] + WINHTTP_OPTION_REDIRECT_POLICY = 88, + + /// Undocumented. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_REFERER_TOKEN_BINDING_HOSTNAME = 168, + + /// + /// Rejects URLs that contain a username and password. This option also rejects URLs that contain username:password semantics, + /// even if no username or password is specified. For example, "u:p@hostname", ":@hostname", "u:@hostname", and ":p@hostname" + /// would all be flagged as invalid. If an invalid URL is passed to the function, it returns ERROR_WINHTTP_INVALID_URL. This + /// option is turned off by default. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.GetSet)] + WINHTTP_OPTION_REJECT_USERPWD_IN_URL = 100, + + /// This option has been deprecated; it has no effect. + [CorrespondingType(typeof(uint), CorrespondingAction.GetSet)] + WINHTTP_OPTION_REQUEST_PRIORITY = 58, + + /// Retreives statistics for the request. For a list of the available statistics, see WINHTTP_REQUEST_STATS. + [CorrespondingType(typeof(WINHTTP_REQUEST_STATS), CorrespondingAction.Get)] + WINHTTP_OPTION_REQUEST_STATS = 146, + + /// Retreives timing information for the request. For a list of the available timings, see WINHTTP_REQUEST_TIMES. + [CorrespondingType(typeof(WINHTTP_REQUEST_TIMES), CorrespondingAction.Get)] + WINHTTP_OPTION_REQUEST_TIMES = 142, + + /// + /// This option tells WinHttp to ignore "Content-Length" response headers, and continue receiving on a stream until the + /// END_STREAM flag is received. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_REQUIRE_STREAM_END = 160, + + /// + /// This option can be set on a WinHttp request handle before it has been sent. If set, WinHttp will use the caller-provided + /// string as the hostname for DNS resolution. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Set)] + WINHTTP_OPTION_RESOLUTION_HOSTNAME = 165, + + /// + /// Sets or retrieves an unsigned long integer value that contains the time-out value, in milliseconds, to resolve a host name. + /// The default timeout value is INFINITE. If a non-default value is specified, there is an overhead of one thread-creation per + /// name resolution. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_RESOLVE_TIMEOUT = 2, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_RESOLVER_CACHE_CONFIG = 170, + + /// + /// Sets an unsigned long integer value that specifies which secure protocols are acceptable. By default only SSL3 and TLS1 are + /// enabled in Windows 7 and Windows 8. By default only SSL3, TLS1.0, TLS1.1, and TLS1.2 are enabled in Windows 8.1 and Windows 10. + /// + [CorrespondingType(typeof(WINHTTP_FLAG_SECURE_PROTOCOL), CorrespondingAction.Set)] + WINHTTP_OPTION_SECURE_PROTOCOLS = 84, + + /// + /// Retrieves the certificate for a SSL/TLS server into the WINHTTP_CERTIFICATE_INFO structure. The application must free the + /// lpszSubjectInfo and lpszIssuerInfo members with LocalFree. + /// + [CorrespondingType(typeof(WINHTTP_CERTIFICATE_INFO), CorrespondingAction.Get)] + WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT = 32, + + /// Sets or retrieves an unsigned long integer value that contains the security flags for a handle. + [CorrespondingType(typeof(SECURITY_FLAG))] + WINHTTP_OPTION_SECURITY_FLAGS = 31, + + /// Retreives the SChannel connection and cipher information for a request. + [CorrespondingType(typeof(WINHTTP_SECURITY_INFO), CorrespondingAction.Get)] + WINHTTP_OPTION_SECURITY_INFO = 151, + + /// + /// Retrieves an unsigned long integer value that contains the cipher strength of the encryption key. A larger number indicates + /// stronger cipher strength encryption. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Get)] + WINHTTP_OPTION_SECURITY_KEY_BITNESS = 36, + + /// Undocumented. + [CorrespondingType(typeof(WINHTTP_PROXY_SETTINGS))] + WINHTTP_OPTION_SELECTED_PROXY_CONFIG_INFO = 182, + + /// + /// Sets or retrieves an unsigned long integer value that contains the time-out value, in milliseconds, to send a request or + /// write some data. If sending the request takes longer than the timeout, the send operation is canceled. The default timeout is + /// 30 seconds. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_SEND_TIMEOUT = 5, + + /// + /// Gets a pointer to SecPkgContext_Bindings structure that specifies a Channel Binding Token (CBT). + /// + /// A Channel Binding Token is a property of a secure transport channel and is used to bind an authentication channel to the + /// secure transport channel. This token can only be obtained by this option after an SSL connection has been established. + /// + /// Passing this option and a null value for lpBuffer to WinHttpQueryOption will return + /// ERROR_INSUFFICIENT_BUFFER and the required byte size for the buffer in the lpdwBufferLength parameter.This returned buffer + /// size value can be passed in a subsequent call to query for the Channel Binding Token.These steps are necessary when handling + /// WINHTTP_CALLBACK_STATUS_REQUEST if you want to modify request headers based on the Channel Binding Token. Note that Windows + /// XP and Vista do not support modifying request headers during this callback. + /// + [CorrespondingType(typeof(Secur32.SecPkgContext_Bindings), CorrespondingAction.Get)] + WINHTTP_OPTION_SERVER_CBT = 108, + + /// + /// Retrieves the server certification chain context. WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT can be passed to obtain a + /// duplicated pointer to the CERT_CHAIN_CONTEXT for a server certificate chain received during a negotiated SSL connection. The + /// client must call CertFreeCertificateContext on the returned PCCERT_CONTEXT pointer that is filled into the buffer. + /// + [CorrespondingType(typeof(Crypt32.PCCERT_CHAIN_CONTEXT), CorrespondingAction.Get)] + WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT = 147, + + /// + /// Retrieves the server certification context. WINHTTP_OPTION_SERVER_CERT_CONTEXT can be passed to obtain a duplicated pointer + /// to the CERT CONTEXT for a server certificate received during a negotiated SSL connection. The client must call + /// CertFreeCertificateContext on the returned PCCERT_CONTEXT pointer that is filled into the buffer. + /// + [CorrespondingType(typeof(Crypt32.PCCERT_CONTEXT), CorrespondingAction.Get)] + WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78, + + /// + /// Gets the server Server Principal Name that WinHTTP supplied to SSPI during authentication. This string value can be passed to + /// SspiPromptForCredentials after an authentication failure. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Get)] + WINHTTP_OPTION_SERVER_SPN_USED = 106, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_SET_GLOBAL_CALLBACK = 163, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_SET_TOKEN_BINDING = 166, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_SOURCE_ADDRESS = 156, + + /// + /// Includes or removes the server port number when the SPN (service principal name) is built for Kerberos or Negotiate Kerberos authentication. + /// + [CorrespondingType(typeof(WINHTTP_SPN), CorrespondingAction.Set)] + WINHTTP_OPTION_SPN = 96, + + /// + /// This option can be queried on a WinHttp request handle, and will return the error code indicated by a RST_STREAM frame + /// received on an HTTP stream. + /// + [CorrespondingType(typeof(Win32Error), CorrespondingAction.Get)] + WINHTTP_OPTION_STREAM_ERROR_CODE = 159, + + /// Enables TCP Fast Open for the connection. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_TCP_FAST_OPEN = 153, + + /// + /// This option can be set on a WinHttp session handle to enable TCP keep-alive behavior on the underlying socket. Takes a + /// tcp_keepalive struct. + /// + [CorrespondingType(typeof(tcp_keepalive), CorrespondingAction.Set)] + WINHTTP_OPTION_TCP_KEEPALIVE = 152, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_TCP_PRIORITY_HINT = 128, + + /// Undocumented. + [CorrespondingType(typeof(ulong), CorrespondingAction.GetSet)] + WINHTTP_OPTION_TCP_PRIORITY_STATUS = 177, + + /// Enables TLS False Start for the connection. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_TLS_FALSE_START = 154, + + /// + /// This option can be set on a WinHttp session handle to control whether fallback to TLS 1.0 is allowed if there is a TLS + /// handshake failure with a newer protocol version. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_TLS_PROTOCOL_INSECURE_FALLBACK = 158, + + /// Undocumented. + [CorrespondingType(typeof(uint), CorrespondingAction.GetSet)] + WINHTTP_OPTION_TOKEN_BINDING_PUBLIC_KEY = 167, + + /// + /// Takes an event that will be set when the last callback has completed for a particular session. This flag must be must be used + /// on a session handle. The event cannot be closed until after it has been set by WinHTTP. + /// + [CorrespondingType(typeof(HEVENT), CorrespondingAction.Set)] + WINHTTP_OPTION_UNLOAD_NOTIFY_EVENT = 99, + + /// This option is reserved for internal use and should not be called. + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_UNSAFE_HEADER_PARSING = 110, + + /// Instructs the stack to start a WebSocket handshake process with WinHttpSendRequest. This option takes no parameters. + [CorrespondingType(null, CorrespondingAction.Set)] + WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET = 114, + + /// + /// Retrieves a string value that contains the full URL of a downloaded resource. If the original URL contained any extra data, + /// such as search strings or anchors, or if the call was redirected, the URL returned differs from the original. The application + /// should pass in a buffer, sized in bytes, that is big enough to hold the returned URL in wide char. + /// + [CorrespondingType(typeof(string), CorrespondingAction.Get)] + WINHTTP_OPTION_URL = 34, + + /// + /// Takes a BOOL and can be set only a session handle. It will only propagate down to handles created from the session handle + /// after the option has been set. If TRUE, this option causes as a last resort the use of global server credentials that were + /// pushed down from WinInet. The default for this option is FALSE. This option requires registry key + /// HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings!ShareCredsWithWinHttp. This registry key is not present by + /// default. When it is set, WinINet will send credentials down to WinHTTP. Whenever WinHttp gets an authentication challenge and + /// if there are no credentials set on the current handle, it will use the credentials provided by WinINet. + /// + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + WINHTTP_OPTION_USE_GLOBAL_SERVER_CREDENTIALS = 101, + + /// + /// Sets or retrieves the user agent string on handles supplied by WinHttpOpen and used in subsequent WinHttpSendRequest + /// functions, as long as it is not overridden by a header added by WinHttpAddRequestHeaders or WinHttpSendRequest. When + /// retrieving a user agent, the application should pass in a buffer, sized in bytes, that is big enough to hold the returned URL + /// in wide char. When setting the user agent, the buffer size is the length of the string, in characters, plus the NULL terminator. + /// + [CorrespondingType(typeof(string), CorrespondingAction.GetSet)] + WINHTTP_OPTION_USER_AGENT = 41, + + /// Sets or retrieves a string that contains the user name. + [CorrespondingType(typeof(string), CorrespondingAction.GetSet)] + WINHTTP_OPTION_USERNAME = 0x1000, + + /// + /// Sets the time, in milliseconds, that WinHttpWebSocketClose should wait to complete the close handshake. The default is 10 seconds. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT = 115, + + /// + /// Sets the interval, in milliseconds, to send a keep-alive packet over the connection. The default interval is 30000 (30 + /// seconds). The minimum interval is 15000 (15 seconds). Using WinHttpSetOption to set a value lower than 15000 will return with + /// ERROR_INVALID_PARAMETER. The default value for WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is read from + /// HKLM:\SOFTWARE\Microsoft\WebSocket\KeepaliveInterval. If a value is not set, the default value of 30000 will be used. It is + /// not possible to have a lower keepalive interval than 15000 milliseconds. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL = 116, + + /// Sets or retrieves a DWORD which specifies the receive buffer size to be used on WebSocket connections. + [CorrespondingType(typeof(uint), CorrespondingAction.GetSet)] + WINHTTP_OPTION_WEB_SOCKET_RECEIVE_BUFFER_SIZE = 122, + + /// Sets or retrieves a DWORD which specifies the send buffer size to be used on WebSocket connections. + [CorrespondingType(typeof(uint), CorrespondingAction.GetSet)] + WINHTTP_OPTION_WEB_SOCKET_SEND_BUFFER_SIZE = 123, + + /// + /// Sets an unsigned long integer value that specifies the number of worker threads the thread pool should use for asynchronous + /// completions. The default value of this option is zero, which specifies that the number of worker threads is equal to the + /// number of CPUs on the system. This option can only be set on a NULL HINTERNET handle before an asynchronous operation has + /// occurred. This option can only be set once. + /// Windows Server 2008 R2 and Windows 7: This flag is obsolete. + /// + [CorrespondingType(typeof(uint), CorrespondingAction.Set)] + WINHTTP_OPTION_WORKER_THREAD_COUNT = 80, + + /// This option has been deprecated; it has no effect. + [CorrespondingType(typeof(uint))] + WINHTTP_OPTION_WRITE_BUFFER_SIZE = 13, + } + + /// The behavior of WinHTTP regarding the handling of a 30x HTTP redirect status code. + [PInvokeData("winhttp.h")] + public enum WINHTTP_OPTION_REDIRECT_POLICY : uint + { + /// WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP + WINHTTP_OPTION_REDIRECT_POLICY_DEFAULT = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, + + /// Redirects are never followed. The 30x status is returned to the application. + WINHTTP_OPTION_REDIRECT_POLICY_NEVER = 0, + + /// + /// All redirects are followed, except those that originate from a secure (https) URL to an unsecure (http) URL. This is the + /// default setting. + /// + WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP = 1, + + /// All redirects are followed automatically. + WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS = 2, + } + + /// Bitmask of acceptable advanced HTTP versions. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_PROTOCOL_FLAG : uint + { + /// Restricts the request to HTTP/1.1 and prior. + None = 0, + + /// Enables HTTP/2 for the request. + WINHTTP_PROTOCOL_FLAG_HTTP2 = 0x1, + + /// Enables HTTP/3 for the request. + WINHTTP_PROTOCOL_FLAG_HTTP3 = 0x2, + } + + /// + /// These attributes and modifiers are used by WinHttpQueryHeaders. + /// + /// The attribute flags are used by WinHttpQueryHeaders to indicate what information to retrieve. Most of the attribute flags map + /// directly to a specific HTTP header. There are also some special flags, such as WINHTTP_QUERY_RAW_HEADERS, that are not related to + /// a specific header. + /// + /// + /// The modifier flags are used in conjunction with an attribute flag to modify the request. Modifier flags either modify the format + /// of the data returned or indicate where the WinHttpQueryHeaders function should search for the information. + /// + /// + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_QUERY : uint + { + /// Retrieves the acceptable media types for the response. + WINHTTP_QUERY_ACCEPT = 24, + + /// Retrieves the acceptable character sets for the response. + WINHTTP_QUERY_ACCEPT_CHARSET = 25, + + /// Retrieves the acceptable content-coding values for the response. + WINHTTP_QUERY_ACCEPT_ENCODING = 26, + + /// Retrieves the acceptable natural languages for the response. + WINHTTP_QUERY_ACCEPT_LANGUAGE = 27, + + /// Retrieves the types of range requests that are accepted for a resource. + WINHTTP_QUERY_ACCEPT_RANGES = 42, + + /// + /// Retrieves the Age response-header field, which contains the sender's estimate of the amount of time since the response was + /// generated at the originating server. + /// + [CorrespondingType(typeof(uint))] + WINHTTP_QUERY_AGE = 48, + + /// Receives the HTTP verbs supported by the server. + WINHTTP_QUERY_ALLOW = 7, + + /// Retrieves the Authentication-Info header. + WINHTTP_QUERY_AUTHENTICATION_INFO = 76, + + /// Retrieves the authorization credentials used for a request. + WINHTTP_QUERY_AUTHORIZATION = 28, + + /// Retrieves the cache control directives. + WINHTTP_QUERY_CACHE_CONTROL = 49, + + /// + /// Retrieves any options that are specified for a particular connection and must not be communicated by proxies over further connections. + /// + WINHTTP_QUERY_CONNECTION = 23, + + /// Retrieves the base Uniform Resource Identifier (URI) to resolve relative URLs within the entity. + WINHTTP_QUERY_CONTENT_BASE = 50, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_CONTENT_DESCRIPTION = 4, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_CONTENT_DISPOSITION = 47, + + /// Retrieves additional content coding that has been applied to the entire resource. + WINHTTP_QUERY_CONTENT_ENCODING = 29, + + /// Retrieves the content identification. + WINHTTP_QUERY_CONTENT_ID = 3, + + /// Retrieves the language that the content is written in. + WINHTTP_QUERY_CONTENT_LANGUAGE = 6, + + /// Retrieves the size of the resource, in bytes. + [CorrespondingType(typeof(uint))] + WINHTTP_QUERY_CONTENT_LENGTH = 5, + + /// Retrieves the resource location for the entity enclosed in the message. + WINHTTP_QUERY_CONTENT_LOCATION = 51, + + /// + /// Retrieves an MD5 digest of the entity body for the purpose of providing an end-to-end message integrity check for the entity + /// body. For more information, see RFC 1864. + /// + WINHTTP_QUERY_CONTENT_MD5 = 52, + + /// + /// Retrieves the location in the full entity body where the partial entity body should be inserted and the total size of the + /// full entity body. + /// + WINHTTP_QUERY_CONTENT_RANGE = 53, + + /// + /// Retrieves an encoding transformation applicable to an entity-body. It may already have been applied, may need to be applied, + /// or may be optionally applicable. + /// + WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING = 2, + + /// Receives the content type of the resource, such as text or html. + WINHTTP_QUERY_CONTENT_TYPE = 1, + + /// Retrieves any cookies associated with the request. + WINHTTP_QUERY_COOKIE = 44, + + /// Not supported. + WINHTTP_QUERY_COST = 15, + + /// + /// Causes WinHttpQueryHeaders to search for the header name specified in the pwszName parameter and store the header information + /// in lpBuffer. An application can use WINHTTP_OPTION_RECEIVE_RESPONSE_TIMEOUT to limit the maximum time this query waits for + /// all headers to be received. + /// + WINHTTP_QUERY_CUSTOM = 65535, + + /// Receives the date and time at which the message was originated. + [CorrespondingType(typeof(SYSTEMTIME))] + WINHTTP_QUERY_DATE = 9, + + /// Not supported. + WINHTTP_QUERY_DERIVED_FROM = 14, + + /// Retrieves the entity tag for the associated entity. + WINHTTP_QUERY_ETAG = 54, + + /// Retrieves the Expect header, which indicates whether the client application should expect 100 series responses. + WINHTTP_QUERY_EXPECT = 68, + + /// Receives the date and time after which the resource should be considered outdated. + [CorrespondingType(typeof(SYSTEMTIME))] + WINHTTP_QUERY_EXPIRES = 10, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_FORWARDED = 30, + + /// Retrieves the e-mail address for the user who controls the requesting user agent if the From header is given. + WINHTTP_QUERY_FROM = 31, + + /// Retrieves the Internet host and port number of the resource being requested. + WINHTTP_QUERY_HOST = 55, + + /// Retrieves the contents of the If-Match request-header field. + WINHTTP_QUERY_IF_MATCH = 56, + + /// Retrieves the contents of the If-Modified-Since header. + [CorrespondingType(typeof(SYSTEMTIME))] + WINHTTP_QUERY_IF_MODIFIED_SINCE = 32, + + /// Retrieves the contents of the If-None-Match request-header field. + WINHTTP_QUERY_IF_NONE_MATCH = 57, + + /// + /// Retrieves the contents of the If-Range request-header field. This header allows the client application to check if the entity + /// related to a partial copy of the entity in the client application's cache has not been updated. If the entity has not been + /// updated, send the parts that the client application is missing. If the entity has been updated, send the entire updated entity. + /// + WINHTTP_QUERY_IF_RANGE = 58, + + /// Retrieves the contents of the If-Unmodified-Since request-header field. + [CorrespondingType(typeof(SYSTEMTIME))] + WINHTTP_QUERY_IF_UNMODIFIED_SINCE = 59, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_LINK = 11, + + /// Receives the date and time at which the resource was last modified. The date and time are determined by the server. + [CorrespondingType(typeof(SYSTEMTIME))] + WINHTTP_QUERY_LAST_MODIFIED = 16, + + /// Retrieves the absolute URI used in a Location response-header. + WINHTTP_QUERY_LOCATION = 33, + + /// Indicates the maximum value of a WINHTTP_QUERY_* value. Not a query flag. + WINHTTP_QUERY_MAX = 78, + + /// Retrieves the number of proxies or gateways that can forward the request to the next inbound server. + [CorrespondingType(typeof(uint))] + WINHTTP_QUERY_MAX_FORWARDS = 60, + + /// Not supported. + WINHTTP_QUERY_MESSAGE_ID = 12, + + /// + /// Receives the version of the Multipurpose Internet Mail Extensions (MIME) protocol that was used to construct the message. + /// + WINHTTP_QUERY_MIME_VERSION = 0, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_ORIG_URI = 34, + + /// + /// Receives the implementation-specific directives that might apply to any recipient along the request/response chain. + /// + WINHTTP_QUERY_PRAGMA = 17, + + /// Retrieves the authentication scheme and realm returned by the proxy. + WINHTTP_QUERY_PROXY_AUTHENTICATE = 41, + + /// + /// Retrieves the header that is used to identify the user to a proxy that requires authentication. This header can only be + /// retrieved before the request is sent to the server. + /// + WINHTTP_QUERY_PROXY_AUTHORIZATION = 61, + + /// Retrieves the Proxy-Connection header. + WINHTTP_QUERY_PROXY_CONNECTION = 69, + + /// Retrieves the Proxy-Support header. + WINHTTP_QUERY_PROXY_SUPPORT = 75, + + /// Receives HTTP verbs available at this server. + WINHTTP_QUERY_PUBLIC = 8, + + /// Retrieves the byte range of an entity. + WINHTTP_QUERY_RANGE = 62, + + /// + /// Receives all the headers returned by the server. Each header is terminated by "\0". An additional "\0" terminates the list of headers. + /// + [CorrespondingType(typeof(string[]))] + WINHTTP_QUERY_RAW_HEADERS = 21, + + /// + /// Receives all the headers returned by the server. Each header is separated by a carriage return/line feed (CR/LF) sequence. + /// + [CorrespondingType(typeof(string))] + WINHTTP_QUERY_RAW_HEADERS_CRLF = 22, + + /// Receives the URI of the resource where the requested URI was obtained. + [CorrespondingType(typeof(string))] + WINHTTP_QUERY_REFERER = 35, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_REFRESH = 46, + + /// Receives the HTTP verb that is being used in the request, typically GET or POST. + [CorrespondingType(typeof(string))] + WINHTTP_QUERY_REQUEST_METHOD = 45, + + /// Retrieves the amount of time the service is expected to be unavailable. + WINHTTP_QUERY_RETRY_AFTER = 36, + + /// Retrieves information about the software used by the originating server to handle the request. + WINHTTP_QUERY_SERVER = 37, + + /// Receives the value of the cookie set for the request. + WINHTTP_QUERY_SET_COOKIE = 43, + + /// Receives the status code returned by the server. For a list of possible values, see HTTP Status Codes. + [CorrespondingType(typeof(HTTP_STATUS))] + WINHTTP_QUERY_STATUS_CODE = 19, + + /// Receives additional text returned by the server on the response line. + WINHTTP_QUERY_STATUS_TEXT = 20, + + /// Obsolete. Maintained for legacy application compatibility. + WINHTTP_QUERY_TITLE = 38, + + /// + /// Retrieves the type of transformation that has been applied to the message body so it can be safely transferred between the + /// sender and recipient. + /// + WINHTTP_QUERY_TRANSFER_ENCODING = 63, + + /// Retrieves the Unless-Modified-Since header. + WINHTTP_QUERY_UNLESS_MODIFIED_SINCE = 70, + + /// Retrieves the additional communication protocols that are supported by the server. + WINHTTP_QUERY_UPGRADE = 64, + + /// Receives some or all of the URI by which the Request-URI resource can be identified. + WINHTTP_QUERY_URI = 13, + + /// Retrieves information about the user agent that made the request. + WINHTTP_QUERY_USER_AGENT = 39, + + /// + /// Retrieves the header that indicates that the entity was selected from a number of available representations of the response + /// using server-driven negotiation. + /// + WINHTTP_QUERY_VARY = 65, + + /// Retrieves the HTTP version that is present in the status line. + WINHTTP_QUERY_VERSION = 18, + + /// + /// Retrieves the intermediate protocols and recipients between the user agent and the server on requests, and between the origin + /// server and the client on responses. + /// + WINHTTP_QUERY_VIA = 66, + + /// + /// Retrieves additional information about the status of a response that might not be reflected by the response status code. + /// + WINHTTP_QUERY_WARNING = 67, + + /// Retrieves the authentication scheme and realm returned by the server. + WINHTTP_QUERY_WWW_AUTHENTICATE = 40, + + /// Returns the data as a 32-bit number for headers whose value is a number, such as the status code. + WINHTTP_QUERY_FLAG_NUMBER = 0x20000000, + + /// Queries request headers only. + WINHTTP_QUERY_FLAG_REQUEST_HEADERS = 0x80000000, + + /// + /// Returns the header value as a SYSTEMTIME structure, which does not require the application to parse the data. Use for headers + /// whose value is a date/time string, such as "Last-Modified-Time". + /// + WINHTTP_QUERY_FLAG_SYSTEMTIME = 0x40000000, + + /// + /// Queries response trailers. Prior to querying response trailers, you must call WinHttpReadData until it returns 0 bytes read. + /// + WINHTTP_QUERY_FLAG_TRAILERS = 0x02000000, + + /// + /// By default, WinHttpQueryHeaders performs a Unicode conversion before returning the header that was queried. If this flag is + /// set, WinHttp returns the header to the caller without performing this conversion. + /// + WINHTTP_QUERY_FLAG_WIRE_ENCODING = 0x01000000, + + /// + WINHTTP_QUERY_EX_ALL_HEADERS = WINHTTP_QUERY_RAW_HEADERS, + + /// Returns the data as a 64-bit number for headers whose value is a number, such as the status code. + WINHTTP_QUERY_FLAG_NUMBER64 = 0x08000000, + } + + /// Flags for WinHttpQueryConnectionGroup. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryConnectionGroup")] + [Flags] + public enum WINHTTP_QUERY_CONNECTION_GROUP_FLAG : ulong + { + /// Indicate that you want non-HTTPS connections (see hInternet). + WINHTTP_QUERY_CONNECTION_GROUP_FLAG_INSECURE = 1 + } + + /// Flags for WinHttpReadDataEx. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_READ_DATA_EX_FLAG : ulong + { + /// + /// WinHttp won't complete the call to WinHttpReadDataEx until the provided data buffer has been filled, or the response + /// is complete. + /// + WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER = 0x0000000000000001 + } + + /// The WINHTTP_REQUEST_STAT_ENTRY enumeration lists the available types of request statistics. + /// + /// This structure is used with WinHttpQueryOption to retrieve statistics for a request by specifying the + /// WINHTTP_OPTION_REQUEST_STATS flag. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_request_stat_entry typedef enum + // _WINHTTP_REQUEST_STAT_ENTRY { WinHttpConnectFailureCount = 0, WinHttpProxyFailureCount, WinHttpTlsHandshakeClientLeg1Size, + // WinHttpTlsHandshakeServerLeg1Size, WinHttpTlsHandshakeClientLeg2Size, WinHttpTlsHandshakeServerLeg2Size, + // WinHttpRequestHeadersSize, WinHttpRequestHeadersCompressedSize, WinHttpResponseHeadersSize, WinHttpResponseHeadersCompressedSize, + // WinHttpResponseBodySize, WinHttpResponseBodyCompressedSize, WinHttpProxyTlsHandshakeClientLeg1Size, + // WinHttpProxyTlsHandshakeServerLeg1Size, WinHttpProxyTlsHandshakeClientLeg2Size, WinHttpProxyTlsHandshakeServerLeg2Size, + // WinHttpRequestStatLast, WinHttpRequestStatMax = 32 } WINHTTP_REQUEST_STAT_ENTRY; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_REQUEST_STAT_ENTRY")] + public enum WINHTTP_REQUEST_STAT_ENTRY : uint + { + /// + /// Value: + /// 0 + /// The number of connection failures during connection establishment. + /// + WinHttpConnectFailureCount = 0, + + /// The number of proxy connection failures during connection establishment. + WinHttpProxyFailureCount, + + /// The size of the client data for the first leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg1Size, + + /// The size of the server data for the first leg of the TLS handshake. + WinHttpTlsHandshakeServerLeg1Size, + + /// The size of the client data for the second leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg2Size, + + /// The size of the server data for the second leg of the TLS handshake. + WinHttpTlsHandshakeServerLeg2Size, + + /// The size of the request headers. + WinHttpRequestHeadersSize, + + /// The compressed size of the request headers. + WinHttpRequestHeadersCompressedSize, + + /// The size of the response headers. + WinHttpResponseHeadersSize, + + /// The compressed size of the response headers. + WinHttpResponseHeadersCompressedSize, + + /// The size of the response body. + WinHttpResponseBodySize, + + /// The compressed size of the response body. + WinHttpResponseBodyCompressedSize, + + /// The size of the client data for the first leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg1Size, + + /// The size of the server data for the first leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeServerLeg1Size, + + /// The size of the client data for the second leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg2Size, + + /// The size of the server data for the second leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeServerLeg2Size, + + /// Marker for the end of the list of available statistics. + WinHttpRequestStatLast, + + /// + /// Value: + /// 32 + /// The maximum number of statistics available. + /// + WinHttpRequestStatMax = 32, + } + + /// Flags containing details on how the request was made. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_REQUEST_STAT_FLAG : ulong + { + /// TCP Fast Open occurred. + WINHTTP_REQUEST_STAT_FLAG_TCP_FAST_OPEN = 0x00000001, + + /// TLS Session Resumption occurred. + WINHTTP_REQUEST_STAT_FLAG_TLS_SESSION_RESUMPTION = 0x00000002, + + /// TLS False Start occurred. + WINHTTP_REQUEST_STAT_FLAG_TLS_FALSE_START = 0x00000004, + + /// TLS Session Resumption occurred for the proxy connection. + WINHTTP_REQUEST_STAT_FLAG_PROXY_TLS_SESSION_RESUMPTION = 0x00000008, + + /// TLS False Start occurred for the proxy connection. + WINHTTP_REQUEST_STAT_FLAG_PROXY_TLS_FALSE_START = 0x00000010, + + /// This is the first request on the connection. + WINHTTP_REQUEST_STAT_FLAG_FIRST_REQUEST = 0x00000020, + } + + /// The WINHTTP_REQUEST_TIME_ENTRY enumeration lists the available types of request timing information. + /// + /// This structure is used with WinHttpQueryOption to retrieve timing information for a request by specifying the + /// WINHTTP_OPTION_REQUEST_TIMES flag. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_request_time_entry typedef enum + // _WINHTTP_REQUEST_TIME_ENTRY { WinHttpProxyDetectionStart = 0, WinHttpProxyDetectionEnd, WinHttpConnectionAcquireStart, + // WinHttpConnectionAcquireWaitEnd, WinHttpConnectionAcquireEnd, WinHttpNameResolutionStart, WinHttpNameResolutionEnd, + // WinHttpConnectionEstablishmentStart, WinHttpConnectionEstablishmentEnd, WinHttpTlsHandshakeClientLeg1Start, + // WinHttpTlsHandshakeClientLeg1End, WinHttpTlsHandshakeClientLeg2Start, WinHttpTlsHandshakeClientLeg2End, + // WinHttpTlsHandshakeClientLeg3Start, WinHttpTlsHandshakeClientLeg3End, WinHttpStreamWaitStart, WinHttpStreamWaitEnd, + // WinHttpSendRequestStart, WinHttpSendRequestHeadersCompressionStart, WinHttpSendRequestHeadersCompressionEnd, + // WinHttpSendRequestHeadersEnd, WinHttpSendRequestEnd, WinHttpReceiveResponseStart, WinHttpReceiveResponseHeadersDecompressionStart, + // WinHttpReceiveResponseHeadersDecompressionEnd, WinHttpReceiveResponseHeadersEnd, WinHttpReceiveResponseBodyDecompressionDelta, + // WinHttpReceiveResponseEnd, WinHttpProxyTunnelStart, WinHttpProxyTunnelEnd, WinHttpProxyTlsHandshakeClientLeg1Start, + // WinHttpProxyTlsHandshakeClientLeg1End, WinHttpProxyTlsHandshakeClientLeg2Start, WinHttpProxyTlsHandshakeClientLeg2End, + // WinHttpProxyTlsHandshakeClientLeg3Start, WinHttpProxyTlsHandshakeClientLeg3End, WinHttpRequestTimeLast, WinHttpRequestTimeMax = 64 + // } WINHTTP_REQUEST_TIME_ENTRY; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_REQUEST_TIME_ENTRY")] + public enum WINHTTP_REQUEST_TIME_ENTRY : uint + { + /// + /// Value: + /// 0 + /// Start of proxy detection. + /// + WinHttpProxyDetectionStart = 0, + + /// End of proxy detection. + WinHttpProxyDetectionEnd, + + /// Start of connection acquisition. + WinHttpConnectionAcquireStart, + + /// End waiting for an available connection. + WinHttpConnectionAcquireWaitEnd, + + /// End of connection acquisition. + WinHttpConnectionAcquireEnd, + + /// Start of name resolution. + WinHttpNameResolutionStart, + + /// End of name resolution. + WinHttpNameResolutionEnd, + + /// Start of connection establishment. + WinHttpConnectionEstablishmentStart, + + /// End of connection establishment. + WinHttpConnectionEstablishmentEnd, + + /// Start of the first leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg1Start, + + /// End of the first leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg1End, + + /// Start of the second leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg2Start, + + /// End of the second leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg2End, + + /// Start of the third leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg3Start, + + /// End of the third leg of the TLS handshake. + WinHttpTlsHandshakeClientLeg3End, + + /// Start waiting for an available stream. + WinHttpStreamWaitStart, + + /// End waiting for an available stream. + WinHttpStreamWaitEnd, + + /// Start sending a request. + WinHttpSendRequestStart, + + /// Start of request header compression. + WinHttpSendRequestHeadersCompressionStart, + + /// End of request header compression. + WinHttpSendRequestHeadersCompressionEnd, + + /// End sending request headers. + WinHttpSendRequestHeadersEnd, + + /// End sending a request. + WinHttpSendRequestEnd, + + /// Start receiving a response. + WinHttpReceiveResponseStart, + + /// Start of response header decompression. + WinHttpReceiveResponseHeadersDecompressionStart, + + /// End of response header decompression. + WinHttpReceiveResponseHeadersDecompressionEnd, + + /// End receiving response headers. + WinHttpReceiveResponseHeadersEnd, + + /// Delta between start and end times for response body decompression. + WinHttpReceiveResponseBodyDecompressionDelta, + + /// End receiving a response. + WinHttpReceiveResponseEnd, + + /// Start establishing a proxy tunnel. + WinHttpProxyTunnelStart, + + /// End establishing a proxy tunnel. + WinHttpProxyTunnelEnd, + + /// Start of the first leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg1Start, + + /// End of the first leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg1End, + + /// Start of the second leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg2Start, + + /// End of the second leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg2End, + + /// Start of the third leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg3Start, + + /// End of the third leg of the proxy TLS handshake. + WinHttpProxyTlsHandshakeClientLeg3End, + + /// Marker for the end of the list of available timings. + WinHttpRequestTimeLast, + + /// + /// Value: + /// 64 + /// The maximum number of timings available. + /// + WinHttpRequestTimeMax = 64, + } + + /// A set of flags that affects the reset operation. + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpResetAutoProxy")] + [Flags] + public enum WINHTTP_RESET : uint + { + /// Forces a flush and retry of non-persistent proxy information on the current network. + WINHTTP_RESET_STATE = 0x00000001, + + /// Flush the PAD information for the current network. + WINHTTP_RESET_SWPAD_CURRENT_NETWORK = 0x00000002, + + /// Flush the PAD information for all networks. + WINHTTP_RESET_SWPAD_ALL = 0x00000004, + + /// Flush the persistent HTTP cache of proxy scripts. + WINHTTP_RESET_SCRIPT_CACHE = 0x00000008, + + /// Forces a flush and retry of all proxy information on the current network. + WINHTTP_RESET_ALL = 0x0000FFFF, + + /// Flush the current proxy information and notify that the network changed. + WINHTTP_RESET_NOTIFY_NETWORK_CHANGED = 0x00010000, + + /// + /// Act on the autoproxy service instead of the current process. Applications that use the WinHttpGetProxyForUrl function to + /// purge in-process caching should close the hInternet handle and open a new handle for future calls. + /// + WINHTTP_RESET_OUT_OF_PROC = 0x00020000, + + /// + WINHTTP_RESET_DISCARD_RESOLVERS = 0x00040000, + } + + /// Includes or removes the server port number when the SPN (service principal name) is built for Kerberos or Negotiate Kerberos authentication. + [PInvokeData("winhttp.h")] + [Flags] + public enum WINHTTP_SPN : uint + { + /// Removes the server port number. + WINHTTP_DISABLE_SPN_SERVER_PORT = 0x00000000, + + /// Includes the server port number. + WINHTTP_ENABLE_SPN_SERVER_PORT = 0x00000001, + } + /// The WINHTTP_WEB_SOCKET_BUFFER_TYPE enumeration includes types of WebSocket buffers. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_web_socket_buffer_type typedef enum + // _WINHTTP_WEB_SOCKET_BUFFER_TYPE { WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE = 0, + // WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE = 1, WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE = 2, + // WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE = 3, WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE = 4 } WINHTTP_WEB_SOCKET_BUFFER_TYPE; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_WEB_SOCKET_BUFFER_TYPE")] + public enum WINHTTP_WEB_SOCKET_BUFFER_TYPE + { + /// + /// Value: + /// 0 + /// Buffer contains either the entire binary message or the last part of it. + /// + WINHTTP_WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE, + + /// + /// Value: + /// 1 + /// Buffer contains only part of a binary message. + /// + WINHTTP_WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE, + + /// + /// Value: + /// 2 + /// Buffer contains either the entire UTF-8 message or the last part of it. + /// + WINHTTP_WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE, + + /// + /// Value: + /// 3 + /// Buffer contains only part of a UTF-8 message. + /// + WINHTTP_WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE, + + /// + /// Value: + /// 4 + /// The server sent a close frame. + /// + WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE, + } + + /// The WINHTTP_WEB_SOCKET_CLOSE_STATUS enumeration includes the status of a WebSocket close operation. + /// WINHTTP_WEB_SOCKET_CLOSE_STATUS is used by WinHttpWebSocketClose, WinHttpWebSocketShutdown, and WinHttpWebSocketQueryCloseStatus. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_web_socket_close_status typedef enum + // _WINHTTP_WEB_SOCKET_CLOSE_STATUS { WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000, + // WINHTTP_WEB_SOCKET_ENDPOINT_TERMINATED_CLOSE_STATUS = 1001, WINHTTP_WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS = 1002, + // WINHTTP_WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS = 1003, WINHTTP_WEB_SOCKET_EMPTY_CLOSE_STATUS = 1005, + // WINHTTP_WEB_SOCKET_ABORTED_CLOSE_STATUS = 1006, WINHTTP_WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS = 1007, + // WINHTTP_WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS = 1008, WINHTTP_WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS = 1009, + // WINHTTP_WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS = 1010, WINHTTP_WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS = 1011, + // WINHTTP_WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS = 1015 } WINHTTP_WEB_SOCKET_CLOSE_STATUS; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_WEB_SOCKET_CLOSE_STATUS")] + public enum WINHTTP_WEB_SOCKET_CLOSE_STATUS : ushort + { + /// + /// Value: + /// 1000 + /// The connection closed successfully. + /// + WINHTTP_WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000, + + /// + /// Value: + /// 1001 + /// The peer is going away and terminating the connection. + /// + WINHTTP_WEB_SOCKET_ENDPOINT_TERMINATED_CLOSE_STATUS, + + /// + /// Value: + /// 1002 + /// A protocol error occurred. + /// + WINHTTP_WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS, + + /// + /// Value: + /// 1003 + /// Invalid data received by the peer. + /// + WINHTTP_WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS, + + /// + /// Value: + /// 1005 + /// The close message was empty. + /// + WINHTTP_WEB_SOCKET_EMPTY_CLOSE_STATUS = 1005, + + /// + /// Value: + /// 1006 + /// The connection was aborted. + /// + WINHTTP_WEB_SOCKET_ABORTED_CLOSE_STATUS, + + /// + /// Value: + /// 1007 + /// The payload was invalid. + /// + WINHTTP_WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS, + + /// + /// Value: + /// 1008 + /// The message violates an endpoint's policy. + /// + WINHTTP_WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS, + + /// + /// Value: + /// 1009 + /// The message sent was too large to process. + /// + WINHTTP_WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS, + + /// + /// Value: + /// 1010 + /// + /// A client endpoint expected the server to negotiate one or more extensions, but the server didn't return them in the response + /// message of the WebSocket handshake. + /// + /// + WINHTTP_WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS, + + /// + /// Value: + /// 1011 + /// An unexpected condition prevented the server from + /// fulfilling the request. + /// + WINHTTP_WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS, + + /// + /// Value: + /// 1015 + /// The TLS handshake could not be completed. + /// + WINHTTP_WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS = 1015, + } + + /// The WINHTTP_WEB_SOCKET_OPERATION enumeration includes the WebSocket operation type. + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_web_socket_operation typedef enum + // _WINHTTP_WEB_SOCKET_OPERATION { WINHTTP_WEB_SOCKET_SEND_OPERATION = 0, WINHTTP_WEB_SOCKET_RECEIVE_OPERATION = 1, + // WINHTTP_WEB_SOCKET_CLOSE_OPERATION = 2, WINHTTP_WEB_SOCKET_SHUTDOWN_OPERATION = 3 } WINHTTP_WEB_SOCKET_OPERATION; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_WEB_SOCKET_OPERATION")] + public enum WINHTTP_WEB_SOCKET_OPERATION + { + /// + /// Value: + /// 0 + /// A + /// WinHttpWebSocketSend + /// operation. + /// + WINHTTP_WEB_SOCKET_SEND_OPERATION, + + /// + /// Value: + /// 1 + /// A + /// WinHttpWebSocketReceive + /// operation. + /// + WINHTTP_WEB_SOCKET_RECEIVE_OPERATION, + + /// + /// Value: + /// 2 + /// A + /// WinHttpWebSocketClose + /// operation. + /// + WINHTTP_WEB_SOCKET_CLOSE_OPERATION, + + /// + /// Value: + /// 3 + /// A + /// WinHttpWebSocketShutdown + /// operation. + /// + WINHTTP_WEB_SOCKET_SHUTDOWN_OPERATION, + } + + /// The WinHttpRequestAutoLogonPolicy enumeration includes possible settings for the Automatic Logon Policy. + /// + /// To set the automatic logon policy, call the SetAutoLogonPolicy method and specify one of the preceding constants. + /// + /// Note + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/winhttp/winhttprequestautologonpolicy typedef enum WinHttpRequestAutoLogonPolicy { + // AutoLogonPolicy_Always = 0, AutoLogonPolicy_OnlyIfBypassProxy = 1, AutoLogonPolicy_Never = 2 } WinHttpRequestAutoLogonPolicy; + [PInvokeData("winhttp.h")] + public enum WinHttpRequestAutoLogonPolicy + { + /// An authenticated log on, using the default credentials, is performed for all requests. + AutoLogonPolicy_Always, + + /// + /// An authenticated log on, using the default credentials, is performed only for requests on the local intranet. The local + /// intranet is considered to be any server on the proxy bypass list in the current proxy configuration. + /// + AutoLogonPolicy_OnlyIfBypassProxy, + + /// Authentication is not used automatically. + AutoLogonPolicy_Never, + } + + /// + /// The WinHttpRequestOption enumeration includes options that can be set or retrieved for the current Microsoft Windows HTTP + /// Services (WinHTTP) session. + /// + /// + /// Set an option by specifying one of the preceding constants as the parameter of the Option property. + /// + /// Note + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/winhttp/winhttprequestoption typedef enum WinHttpRequestOption { + // WinHttpRequestOption_UserAgentString, WinHttpRequestOption_URL, WinHttpRequestOption_URLCodePage, + // WinHttpRequestOption_EscapePercentInURL, WinHttpRequestOption_SslErrorIgnoreFlags, WinHttpRequestOption_SelectCertificate, + // WinHttpRequestOption_EnableRedirects, WinHttpRequestOption_UrlEscapeDisable, WinHttpRequestOption_UrlEscapeDisableQuery, + // WinHttpRequestOption_SecureProtocols, WinHttpRequestOption_EnableTracing, WinHttpRequestOption_RevertImpersonationOverSsl, + // WinHttpRequestOption_EnableHttpsToHttpRedirects, WinHttpRequestOption_EnablePassportAuthentication, + // WinHttpRequestOption_MaxAutomaticRedirects, WinHttpRequestOption_MaxResponseHeaderSize, WinHttpRequestOption_MaxResponseDrainSize, + // WinHttpRequestOption_EnableHttp1_1, WinHttpRequestOption_EnableCertificateRevocationCheck } WinHttpRequestOption; + [PInvokeData("winhttp.h")] + public enum WinHttpRequestOption + { + /// Sets or retrieves a VARIANT that contains the user agent string. + WinHttpRequestOption_UserAgentString, + + /// + /// Retrieves a VARIANT that contains the URL of the resource. This value is read-only; you cannot set the URL using this + /// property. The URL cannot be read until the Open method is called. This option is useful for checking the URL after the + /// Send method is finished to verify that any redirection occurred. + /// + WinHttpRequestOption_URL, + + /// + /// Sets or retrieves a VARIANT that identifies the code page for the URL string. The default value is the UTF-8 code + /// page. The code page is used to convert the Unicode URL string, passed in the Open method, to a single-byte string representation. + /// + WinHttpRequestOption_URLCodePage, + + /// + /// Sets or retrieves a VARIANT that indicates whether percent characters in the URL string are converted to an escape + /// sequence. The default value of this option is VARIANT_TRUE which specifies all unsafe American National Standards + /// Institute (ANSI) characters except the percent symbol are converted to an escape sequence. + /// + WinHttpRequestOption_EscapePercentInURL, + + /// + /// + /// Sets or retrieves a VARIANT that indicates which server certificate errors should be ignored. This can be a + /// combination of one or more of the following flags. + /// + /// + /// + /// Error + /// Value + /// + /// + /// Unknown certification authority (CA) or untrusted root + /// 0x0100 + /// + /// + /// Wrong usage + /// 0x0200 + /// + /// + /// Invalid common name (CN) + /// 0x1000 + /// + /// + /// Invalid date or certificate expired + /// 0x2000 + /// + /// + /// + /// The default value of this option in Version 5.1 of WinHTTP is zero, which results in no errors being ignored. In earlier + /// versions of WinHTTP, the default setting was 0x3300, which resulted in all server certificate errors being ignored by default. + /// + /// + WinHttpRequestOption_SslErrorIgnoreFlags, + + /// + /// Sets a VARIANT that specifies the client certificate that is sent to a server for authentication. This option + /// indicates the location, certificate store, and subject of a client certificate delimited with backslashes. For more + /// information about selecting a client certificate, see SSL in WinHTTP. + /// + WinHttpRequestOption_SelectCertificate, + + /// + /// Sets or retrieves a VARIANT that indicates whether requests are automatically redirected when the server specifies a + /// new location for the resource. The default value of this option is VARIANT_TRUE to indicate that requests are + /// automatically redirected. + /// + WinHttpRequestOption_EnableRedirects, + + /// + /// Sets or retrieves a VARIANT that indicates whether unsafe characters in the path and query components of a URL are + /// converted to escape sequences. The default value of this option is VARIANT_TRUE, which specifies that characters in + /// the path and query are converted. + /// + WinHttpRequestOption_UrlEscapeDisable, + + /// + /// Sets or retrieves a VARIANT that indicates whether unsafe characters in the query component of the URL are converted + /// to escape sequences. The default value of this option is VARIANT_TRUE, which specifies that characters in the query + /// are converted. + /// + WinHttpRequestOption_UrlEscapeDisableQuery, + + /// + /// + /// Sets or retrieves a VARIANT that indicates which secure protocols can be used. This option selects the protocols + /// acceptable to the client. The protocol is negotiated during the Secure Sockets Layer (SSL) handshake. This can be a + /// combination of one or more of the following flags. + /// + /// + /// + /// Protocol + /// Value + /// + /// + /// SSL 2.0 + /// 0x0008 + /// + /// + /// SSL 3.0 + /// 0x0020 + /// + /// + /// Transport Layer Security (TLS) 1.0 + /// 0x0080 + /// + /// + /// + /// The default value of this option is 0x0028, which indicates that SSL 2.0 or SSL 3.0 can be used. If this option is set to + /// zero, the client and server are not able to determine an acceptable security protocol and the next Send results in an error. + /// + /// + WinHttpRequestOption_SecureProtocols, + + /// + /// Sets or retrieves a VARIANT that indicates whether tracing is currently enabled. For more information about the trace + /// facility in Microsoft Windows HTTP Services (WinHTTP), see WinHTTP Trace Facility. + /// + WinHttpRequestOption_EnableTracing, + + /// + /// Controls whether the WinHttpRequest object temporarily reverts client impersonation for the duration of the SSL + /// certificate authentication operations. The default setting for the WinHttpRequest object is TRUE. Set this + /// option to FALSE to keep impersonation while performing certificate authentication operations. + /// + WinHttpRequestOption_RevertImpersonationOverSsl, + + /// + /// Controls whether or not WinHTTP allows redirects. By default, all redirects are automatically followed, except those that + /// transfer from a secure (https) URL to an non-secure (http) URL. Set this option to TRUE to enable HTTPS to HTTP redirects. + /// + WinHttpRequestOption_EnableHttpsToHttpRedirects, + + /// + /// Enables or disables support for Passport authentication. By default, automatic support for Passport authentication is + /// disabled; set this option to TRUE to enable Passport authentication support. + /// + WinHttpRequestOption_EnablePassportAuthentication, + + /// + /// + /// Sets or retrieves the maximum number of redirects that WinHTTP follows; the default is 10. This limit prevents unauthorized + /// sites from making the WinHTTP client stall following a large number of redirects. + /// + /// Windows XP with SP1 and Windows 2000 with SP3: This enumeration value is not supported. + /// + WinHttpRequestOption_MaxAutomaticRedirects, + + /// + /// + /// Sets or retrieves a bound set on the maximum size of the header portion of the server's response. This bound protects the + /// client from a malicious server attempting to stall the client by sending a response with an infinite amount of header data. + /// The default value is 64 KB. + /// + /// Windows XP with SP1 and Windows 2000 with SP3: This enumeration value is not supported. + /// + WinHttpRequestOption_MaxResponseHeaderSize, + + /// + /// + /// Sets or retrieves a bound on the amount of data that will be drained from responses in order to reuse a connection. The + /// default is 1 MB. + /// + /// Windows XP with SP1 and Windows 2000 with SP3: This enumeration value is not supported. + /// + WinHttpRequestOption_MaxResponseDrainSize, + + /// + /// + /// Sets or retrieves a boolean value that indicates whether HTTP/1.1 or HTTP/1.0 should be used. The default is TRUE, so + /// that HTTP/1.1 is used by default. + /// + /// Windows XP with SP1 and Windows 2000 with SP3: This enumeration value is not supported. + /// + WinHttpRequestOption_EnableHttp1_1, + + /// + /// + /// Enables server certificate revocation checking during SSL negotiation. When the server presents a certificate, a check is + /// performed to determine whether the certificate has been revoked by its issuer. If the certificate is indeed revoked, or the + /// revocation check fails because the Certificate Revocation List (CRL) cannot be downloaded, the request fails; such revocation + /// errors cannot be suppressed. + /// + /// Windows XP with SP1 and Windows 2000 with SP3: This enumeration value is not supported. + /// + WinHttpRequestOption_EnableCertificateRevocationCheck, + } + } +} \ No newline at end of file diff --git a/UnitTests/PInvoke/WinHTTP/WinHTTP.csproj b/UnitTests/PInvoke/WinHTTP/WinHTTP.csproj new file mode 100644 index 00000000..11e74b24 --- /dev/null +++ b/UnitTests/PInvoke/WinHTTP/WinHTTP.csproj @@ -0,0 +1,8 @@ + + + UnitTest.PInvoke.WinHTTP + + + + + \ No newline at end of file diff --git a/UnitTests/PInvoke/WinHTTP/WinHTTPTests.cs b/UnitTests/PInvoke/WinHTTP/WinHTTPTests.cs new file mode 100644 index 00000000..3e0db6de --- /dev/null +++ b/UnitTests/PInvoke/WinHTTP/WinHTTPTests.cs @@ -0,0 +1,418 @@ +using NUnit.Framework; +using NUnit.Framework.Internal; +using System; +using System.Linq; +using System.Text; +using Vanara.Extensions; +using Vanara.InteropServices; +using static Vanara.PInvoke.WinHTTP; + +namespace Vanara.PInvoke.Tests +{ + [TestFixture] + public class WinHTTPTests + { + private const string host = "www.microsoft.com"; + private const string userAgent = "A WinHTTP Example Program/1.0"; + + [OneTimeSetUp] + public void _Setup() + { + } + + [OneTimeTearDown] + public void _TearDown() + { + } + + [Test] + public void WinHttpCheckPlatformTest() => Assert.That(WinHttpCheckPlatform(), Is.True); + + [Test] + public void WinHttpCrackUrlTest() + { + const string url = "https://www.example.com/index.html?query1=value1&query2=value2#section"; + + WINHTTP_URL_COMPONENTS comps = new(); + Assert.That(WinHttpCrackUrl(url, 0, 0, ref comps), ResultIs.Successful); + + uint len = 0U; + Assert.That(WinHttpCreateUrl(comps, 0, null, ref len), ResultIs.Failure); + StringBuilder sb = new((int)len); + Assert.That(WinHttpCreateUrl(comps, 0, sb, ref len), ResultIs.Successful); + Assert.That(sb.ToString(), Is.EqualTo(url)); + } + + [Test] + public void WinHttpDetectAutoProxyConfigUrlTest() + { + Assert.That(WinHttpDetectAutoProxyConfigUrl(WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DNS_A, out SafeHGlobalHandle url), ResultIs.Successful); + TestContext.Write(url.ToString(-1)); + } + + [Test] + public void WinHttpGetDefaultProxyConfigurationTest() + { + Assert.That(WinHttpGetDefaultProxyConfiguration(out WINHTTP_PROXY_INFO pInfo), ResultIs.Successful); + pInfo.WriteValues(); + } + + [Test] + public void WinHttpGetIEProxyConfigForCurrentUserTest() + { + Assert.That(WinHttpGetIEProxyConfigForCurrentUser(out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG prxCfg), ResultIs.Successful); + prxCfg.WriteValues(); + } + + [Test, RequiresThread] + public void WinHttpGetProxyForUrlExTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent, dwFlags: WINHTTP_OPEN_FLAG.WINHTTP_FLAG_ASYNC); + Assert.That(hSession, ResultIs.ValidHandle); + + if (!WinHttpGetIEProxyConfigForCurrentUser(out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG prxCfg)) + { + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_FILE_NOT_FOUND); + } + + Assert.That(WinHttpCreateProxyResolver(hSession, out SafeHINTERNET hResolver), ResultIs.Successful); + + using System.Threading.ManualResetEvent evt = new System.Threading.ManualResetEvent(false); + Win32Error cbErr = Win32Error.ERROR_SUCCESS; + IntPtr prevCb = WinHttpSetStatusCallback(hResolver, callback, WINHTTP_CALLBACK_FLAG.WINHTTP_CALLBACK_FLAG_REQUEST_ERROR | WINHTTP_CALLBACK_FLAG.WINHTTP_CALLBACK_FLAG_GETPROXYFORURL_COMPLETE); + Assert.That(prevCb, Is.Not.EqualTo(WINHTTP_INVALID_STATUS_CALLBACK)); + + WINHTTP_AUTOPROXY_OPTIONS opts; + if (prxCfg.fAutoDetect) + { + opts = new() + { + dwFlags = WINHTTP_AUTOPROXY.WINHTTP_AUTOPROXY_AUTO_DETECT, + dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DNS_A | WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DHCP, + fAutoLogonIfChallenged = true, + }; + // Call WinHttpGetProxyForUrl with our target URL, then set the proxy info on the request handle. + Assert.That(WinHttpGetProxyForUrlEx(hResolver, "https://www.microsoft.com/ms.htm", opts), Is.EqualTo((Win32Error)Win32Error.ERROR_IO_PENDING)); + } + + evt.WaitOne(5000); + Assert.That(cbErr, ResultIs.Successful); + + void callback(HINTERNET hInternet, IntPtr dwContext, WINHTTP_CALLBACK_STATUS dwInternetStatus, IntPtr lpvStatusInformation, uint dwStatusInformationLength) + { + if (dwInternetStatus == WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_REQUEST_ERROR) + { + WINHTTP_ASYNC_RESULT res = lpvStatusInformation.ToStructure(dwStatusInformationLength); + if (res.dwResult != ASYNC_RESULT.API_GET_PROXY_FOR_URL) + { + return; + } + + cbErr = res.dwError; + } + else if (dwInternetStatus == WINHTTP_CALLBACK_STATUS.WINHTTP_CALLBACK_STATUS_GETPROXYFORURL_COMPLETE) + { + cbErr = WinHttpGetProxyResult(hInternet, out WINHTTP_PROXY_RESULT proxyRes); + if (cbErr.Succeeded) + { + proxyRes.WriteValues(); + WinHttpFreeProxyResult(ref proxyRes); + } + } + evt.Set(); + } + } + + [Test] + public void WinHttpGetProxyForUrlTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTP_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", "ms.htm", "HTTP/1.1"); + Assert.That(hRequest, ResultIs.ValidHandle); + + // Call WinHttpGetProxyForUrl with our target URL, then set the proxy info on the request handle. + WINHTTP_AUTOPROXY_OPTIONS opts = new() + { + dwFlags = WINHTTP_AUTOPROXY.WINHTTP_AUTOPROXY_AUTO_DETECT, + dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DNS_A | WINHTTP_AUTO_DETECT_TYPE.WINHTTP_AUTO_DETECT_TYPE_DHCP, + fAutoLogonIfChallenged = true, + }; + Assert.That(WinHttpGetProxyForUrl(hSession, "https://www.microsoft.com/ms.htm", opts, out WINHTTP_PROXY_INFO info), ResultIs.Successful); + try + { + TestContext.WriteLine($"{info.dwAccessType}; {info.lpszProxy}; {info.lpszProxyBypass}"); + // A proxy configuration was found, set it on the request handle. + Assert.That(WinHttpSetOption(hRequest, WINHTTP_OPTION.WINHTTP_OPTION_PROXY, info), ResultIs.Successful); + } + finally + { + info.FreeMemory(); + } + + // Send the request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + + // Wait for the response. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + } + + [Test] // TODO: Need to find URL where this works + public void WinHttpQueryAuthSchemesTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, "drive.google.com", INTERNET_DEFAULT_HTTPS_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", "file/d/0ByJOdIdwOr5COHpTRTNFakgzSk0/view?usp=sharing&resourcekey=0-TUcpJ5N1-M9-Mw1DP4VT7A", dwFlags: WINHTTP_OPENREQ_FLAG.WINHTTP_FLAG_SECURE); + Assert.That(hRequest, ResultIs.ValidHandle); + // Send the request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + // Wait for the response. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + + var stat = WinHttpQueryHeaders(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_STATUS_CODE); + Assert.That(stat, Is.EqualTo(401).Or.EqualTo(407)); + + Assert.That(WinHttpQueryAuthSchemes(hRequest, out var sch, out var first, out var target), ResultIs.Successful); + TestContext.Write($"Auth: {sch}, {first}, {target}"); + } + + //[Test] // Can't get this ever pass + public void WinHttpQueryConnectionGroupTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTPS_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + try + { + IntPtr res = default; + Assert.That(WinHttpQueryConnectionGroup(hConnect, default, 0, ref res), ResultIs.Successful); + WinHttpFreeQueryConnectionGroupResult(res); + } + finally + { + if (!hConnect.IsNull) + { + WinHttpCloseHandle(hSession); + } + + if (!hSession.IsNull) + { + WinHttpCloseHandle(hSession); + } + } + } + + [Test] + public void WinHttpQueryHeadersExTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTPS_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", dwFlags: WINHTTP_OPENREQ_FLAG.WINHTTP_FLAG_SECURE); + Assert.That(hRequest, ResultIs.ValidHandle); + // Add a request header. + WINHTTP_EXTENDED_HEADER[] hdr = new WINHTTP_EXTENDED_HEADER[] { ("If-Modified-Since", "Mon, 20 Nov 2000 20:00:00 GMT"), ("Accept-Charset", "utf-8") }; + Assert.That(WinHttpAddRequestHeadersEx(hRequest, WINHTTP_ADDREQ_FLAG.WINHTTP_ADDREQ_FLAG_ADD, + WINHTTP_EXTENDED_HEADER_FLAG.WINHTTP_EXTENDED_HEADER_FLAG_UNICODE, 0, hdr.Length, hdr), ResultIs.Successful); + // Send a request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + // End the request. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + // Get status header + uint sz = 256U; + using var pin = new SafeHGlobalHandle(sz); + Assert.That(WinHttpQueryHeadersEx(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_CONNECTION, 0, 0, + default, default, pin, ref sz, out var hdrs, out var cHdrs), ResultIs.Successful); + Assert.That(sz, Is.GreaterThan(0)); + Assert.That(cHdrs, Is.GreaterThan(0)); + hdrs.ToArray((int)cHdrs)[0].WriteValues(); + } + + [Test] + public void WinHttpQueryHeadersTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTP_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET"); + Assert.That(hRequest, ResultIs.ValidHandle); + // Add a request header. + Assert.That(WinHttpAddRequestHeaders(hRequest, "If-Modified-Since: Mon, 20 Nov 2000 20:00:00 GMT\r\nAccept-Charset: utf-8", -1, WINHTTP_ADDREQ_FLAG.WINHTTP_ADDREQ_FLAG_ADD), ResultIs.Successful); + // Send a request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + // End the request. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + + Assert.That(WinHttpQueryHeaders(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_FLAG_NUMBER | WINHTTP_QUERY.WINHTTP_QUERY_STATUS_CODE), Is.GreaterThanOrEqualTo(200)); + Assert.That(WinHttpQueryHeaders(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_FLAG_SYSTEMTIME | WINHTTP_QUERY.WINHTTP_QUERY_DATE).wYear, Is.EqualTo(DateTime.Today.Year)); + //uint idx = 2; + //Assert.That(() => WinHttpQueryHeaders(hRequest, WINHTTP_QUERY.WINHTTP_QUERY_RAW_HEADERS, null, ref idx), Throws.Nothing); + + for (uint i = 0; i < 78; i++) + { + try + { + string hdrs = WinHttpQueryHeaders(hRequest, (WINHTTP_QUERY)i); + TestContext.WriteLine($"{i}) {(WINHTTP_QUERY)i}: {hdrs}"); + } + catch (System.ComponentModel.Win32Exception wex) when (wex.NativeErrorCode == 0x2f76) { } + catch (Exception ex) + { + TestContext.WriteLine($"{i}) {(WINHTTP_QUERY)i}: ERR: {ex.Message}"); + } + } + } + + [Test] + public void WinHttpQueryOptionTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + uint data = WinHttpQueryOption(hSession, WINHTTP_OPTION.WINHTTP_OPTION_CONNECT_TIMEOUT); + TestContext.Write($"Connection timeout: {data} ms\n"); + } + + [Test] + public void WinHttpQueryOptionTypeTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTPS_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", dwFlags: WINHTTP_OPENREQ_FLAG.WINHTTP_FLAG_SECURE); + Assert.That(hRequest, ResultIs.ValidHandle); + // Send a request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + // End the request. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + + foreach (WINHTTP_OPTION opt in Enum.GetValues(typeof(WINHTTP_OPTION))) + { + uint len = 0; + TestContext.Write($"{opt} ({(int)opt}): "); + var err = WinHttpQueryOption(hSession, opt, default, ref len) ? Win32Error.ERROR_SUCCESS : Win32Error.GetLastError(); + if (err.Failed) + { + if (err == Win32Error.ERROR_INTERNET_INCORRECT_HANDLE_TYPE) + { + len = 0; + err = WinHttpQueryOption(hRequest, opt, default, ref len) ? Win32Error.ERROR_SUCCESS : Win32Error.GetLastError(); + } + if (err == Win32Error.ERROR_INVALID_PARAMETER && + CorrespondingTypeAttribute.GetAttrForEnum(opt, CorrespondingAction.Get).FirstOrDefault() is null) + { + TestContext.WriteLine("SET ONLY"); + continue; + } + if (err != Win32Error.ERROR_INSUFFICIENT_BUFFER) + { + TestContext.WriteLine($"Err = {err}"); + continue; + } + } + var type = CorrespondingTypeAttribute.GetCorrespondingTypes(opt).FirstOrDefault(); + TestContext.WriteLine($"{type?.Name ?? "[Unk]"} = {len}"); + if (type is not null && type.IsValueType && opt != WINHTTP_OPTION.WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST && + opt != WINHTTP_OPTION.WINHTTP_OPTION_SELECTED_PROXY_CONFIG_INFO) + Assert.That((uint)InteropExtensions.SizeOf(type), Is.LessThanOrEqualTo(len)); + } + } + + [Test] + public void WinHttpReadDataTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + // Specify an HTTP server. + using SafeHINTERNET hConnect = WinHttpConnect(hSession, host, INTERNET_DEFAULT_HTTPS_PORT); + Assert.That(hConnect, ResultIs.ValidHandle); + // Create an HTTP request handle. + using SafeHINTERNET hRequest = WinHttpOpenRequest(hConnect, "GET", dwFlags: WINHTTP_OPENREQ_FLAG.WINHTTP_FLAG_SECURE); + Assert.That(hRequest, ResultIs.ValidHandle); + // Send a request. + Assert.That(WinHttpSendRequest(hRequest), ResultIs.Successful); + // End the request. + Assert.That(WinHttpReceiveResponse(hRequest), ResultIs.Successful); + // Report data size + Assert.That(WinHttpQueryDataAvailable(hRequest, out uint bytes), ResultIs.Successful); + TestContext.Write($"Bytes in request: {bytes}"); + Assert.That(bytes, Is.GreaterThan(0)); + // Read from stream + using var mem = new SafeHGlobalHandle(bytes + 1); + Assert.That(WinHttpReadData(hRequest, mem, bytes, out var read), ResultIs.Successful); + Assert.That(read, Is.LessThanOrEqualTo((uint)mem.Size)); + TestContext.WriteLine($", Bytes read: {read}"); + TestContext.WriteLine(mem.ToString(-1, System.Runtime.InteropServices.CharSet.Ansi)); + } + + [Test] + public void WinHttpResetAutoProxyTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + Assert.That(hSession, ResultIs.ValidHandle); + + Assert.That(WinHttpResetAutoProxy(hSession, WINHTTP_RESET.WINHTTP_RESET_STATE), ResultIs.Successful); + } + + [Test] + public void WinHttpSetDefaultProxyConfigurationTest() + { + Assert.That(WinHttpGetDefaultProxyConfiguration(out WINHTTP_PROXY_INFO pInfo), ResultIs.Successful); + pInfo.WriteValues(); + Assert.That(WinHttpSetDefaultProxyConfiguration(pInfo), ResultIs.Successful); + } + + [Test] + public void WinHttpSetTimeoutsTest() + { + // Use WinHttpOpen to obtain a session handle. + using SafeHINTERNET hSession = WinHttpOpen(userAgent); + + var rslv = WinHttpQueryOption(hSession, WINHTTP_OPTION.WINHTTP_OPTION_RESOLVE_TIMEOUT); + var conn = WinHttpQueryOption(hSession, WINHTTP_OPTION.WINHTTP_OPTION_CONNECT_TIMEOUT); + var send = WinHttpQueryOption(hSession, WINHTTP_OPTION.WINHTTP_OPTION_SEND_TIMEOUT); + var recv = WinHttpQueryOption(hSession, WINHTTP_OPTION.WINHTTP_OPTION_RECEIVE_TIMEOUT); + Assert.That(WinHttpSetTimeouts(hSession, rslv, conn, send, recv), ResultIs.Successful); + } + + [Test] + public void WinHttpTimeFromSystemTimeTest() + { + var st = new SYSTEMTIME(2000, 2, 20, 14, 20, 2); + var sb = new StringBuilder(256); + Assert.That(WinHttpTimeFromSystemTime(st, sb), ResultIs.Successful); + Assert.That(sb.ToString(), Contains.Substring("2000")); + + Assert.That(WinHttpTimeToSystemTime(sb.ToString(), out var st2), ResultIs.Successful); + Assert.That(st.Ticks, Is.EqualTo(st2.Ticks)); + } + } +} \ No newline at end of file diff --git a/Vanara.sln b/Vanara.sln index bf255143..82068a1a 100644 --- a/Vanara.sln +++ b/Vanara.sln @@ -364,6 +364,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vanara.PInvoke.AMSI", "PInv EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AMSI", "UnitTests\PInvoke\AMSI\AMSI.csproj", "{496DFA71-4C35-49AE-95C1-4B802DB91615}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.WinHTTP", "PInvoke\WinHTTP\Vanara.PInvoke.WinHTTP.csproj", "{B8A58F84-9707-4B9C-9AE0-04DDE718E232}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WinHTTP", "UnitTests\PInvoke\WinHTTP\WinHTTP.csproj", "{20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -2289,6 +2293,40 @@ Global {496DFA71-4C35-49AE-95C1-4B802DB91615}.Release|x64.Build.0 = Release|Any CPU {496DFA71-4C35-49AE-95C1-4B802DB91615}.Release|x86.ActiveCfg = Release|Any CPU {496DFA71-4C35-49AE-95C1-4B802DB91615}.Release|x86.Build.0 = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|x64.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|x64.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|x86.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Debug|x86.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|Any CPU.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|Any CPU.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|x64.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|x64.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|x86.ActiveCfg = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.DebugNoTests|x86.Build.0 = Debug|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|Any CPU.Build.0 = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|x64.ActiveCfg = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|x64.Build.0 = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|x86.ActiveCfg = Release|Any CPU + {B8A58F84-9707-4B9C-9AE0-04DDE718E232}.Release|x86.Build.0 = Release|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|x64.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|x64.Build.0 = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|x86.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Debug|x86.Build.0 = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.DebugNoTests|Any CPU.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.DebugNoTests|x64.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.DebugNoTests|x64.Build.0 = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.DebugNoTests|x86.ActiveCfg = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.DebugNoTests|x86.Build.0 = Debug|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Release|x64.ActiveCfg = Release|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Release|x64.Build.0 = Release|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Release|x86.ActiveCfg = Release|Any CPU + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -2447,6 +2485,8 @@ Global {E21DCE50-E36E-41B3-BE57-D908ACBE88E5} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} {129B31E3-1247-4D73-AA45-52D0B2B4C6FD} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90} {496DFA71-4C35-49AE-95C1-4B802DB91615} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} + {B8A58F84-9707-4B9C-9AE0-04DDE718E232} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90} + {20FB9D67-52BB-4C82-A5FE-BCA09B69CAC5} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}