From 17acbee104a431543d7bd66c4fb7fcba1ca80cb4 Mon Sep 17 00:00:00 2001 From: David Hall Date: Tue, 25 Oct 2022 11:24:37 -0600 Subject: [PATCH] Added new functions introducted in Win11 --- PInvoke/Kernel32/IoRingApi.cs | 171 ++ PInvoke/QoS/QoS2.cs | 2 +- PInvoke/User32/WinUser.Window.cs | 105 + PInvoke/User32/WinUser.cs | 84 + PInvoke/WinHTTP/WinHTTP.Funcs2.cs | 5082 +++++++++++++++++++----------------- PInvoke/WinHTTP/WinHTTP.Structs.cs | 2765 +++++++++++--------- PInvoke/WinHTTP/WinHTTP.cs | 34 + 7 files changed, 4519 insertions(+), 3724 deletions(-) diff --git a/PInvoke/Kernel32/IoRingApi.cs b/PInvoke/Kernel32/IoRingApi.cs index 5749d14a..0c00575b 100644 --- a/PInvoke/Kernel32/IoRingApi.cs +++ b/PInvoke/Kernel32/IoRingApi.cs @@ -5,6 +5,29 @@ namespace Vanara.PInvoke { public static partial class Kernel32 { + /// Undocumented + [PInvokeData("winbase.h", MinClient = PInvokeClient.Windows11)] + public enum FILE_FLUSH_MODE + { + /// same as WIN32 FlushFileBuffers(); Flushes data, metadata, AND sends a SYNC command to the hardware + FILE_FLUSH_DEFAULT = 0, + /// Flush data only + FILE_FLUSH_DATA, + /// Flush data + SYNC (minimal metadata) + FILE_FLUSH_MIN_METADATA, + /// Flush data + metadata + FILE_FLUSH_NO_SYNC, + } + + /// Undocumented + [PInvokeData("winbase.h", MinClient = PInvokeClient.Windows11)] + public enum FILE_WRITE_FLAGS + { + /// Undocumented + FILE_WRITE_FLAGS_NONE, + /// Undocumented + FILE_WRITE_FLAGS_WRITE_THROUGH = 0x000000001, + } /// Specifies advisory flags for creating an I/O ring with a call to CreateIoRing. /// /// Use the IORING_CREATE_FLAGS structure to pass flags into CreateIoRing. Any unknown or unsupported advisory flags provided @@ -115,6 +138,52 @@ namespace Vanara.PInvoke [PInvokeData("ioringapi.h", MSDNShortId = "NF:ioringapi.BuildIoRingCancelRequest", MinClient = PInvokeClient.Windows11)] public static extern HRESULT BuildIoRingCancelRequest(HIORING ioRing, IORING_HANDLE_REF file, IntPtr opToCancel, [In, Optional] IntPtr userData); + /// Undocumented. + /// An HIORING representing a handle to the I/O ring for which a cancellation is requested. + /// An IORING_HANDLE_REF representing the file associated with the operation to flush. + /// The flush mode. + /// + /// A UINT_PTR value identifying the file write operation. Specify this value when cancelling the operation with a call to + /// BuildIoRingCancelRequest. If an app implements cancellation behavior for the operation, the userData value must be unique. + /// Otherwise, the value is treated as opaque by the system and can be anything, including 0. + /// + /// + /// A bitwise OR combination of values from the IORING_SQE_FLAGS enumeration specifying kernel behavior options for I/O ring + /// submission queue entries. + /// + /// + /// + /// + /// Value + /// Description + /// + /// + /// S_OK + /// Success + /// + /// + /// IORING_E_SUBMISSION_QUEUE_FULL + /// + /// The submission queue is full, and no additional entries are available to build. The application must submit the existing entries + /// and wait for some of them to complete before adding more operations to the queue. + /// + /// + /// + /// IORING_E_UNKNOWN_REQUIRED_FLAG + /// + /// The application provided a required flag that is not known to the implementation. Library code should check the IoRingVersion + /// field of the IORING_INFO obtained from a call to GetIoRingInfo to determine the API version of an I/O ring which determines the + /// operations and flags that are supported. Applications should know the version they used to create the I/O ring and therefore + /// should not provide unsupported flags at runtime. + /// + /// + /// + /// + [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ioringapi.h", MinClient = PInvokeClient.Windows11)] + public static extern HRESULT BuildIoRingFlushFile([In] HIORING ioRing, IORING_HANDLE_REF fileRef, FILE_FLUSH_MODE flushMode, + IntPtr userData, IORING_SQE_FLAGS sqeFlags); + /// Performs an asynchronous read from a file using an I/O ring. This operation is similar to calling ReadFileEx. /// An HIORING representing a handle to the I/O ring which will perform the read operation. /// An IORING_HANDLE_REF specifying the file to read. @@ -275,6 +344,61 @@ namespace Vanara.PInvoke public static extern HRESULT BuildIoRingRegisterFileHandles(HIORING ioRing, uint count, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] HANDLE[] handles, [In, Optional] IntPtr userData); + /// Undocumented. Performs an asynchronous write to a file using an I/O ring. This operation is similar to calling WriteFileEx. + /// An HIORING representing a handle to the I/O ring for which a cancellation is requested. + /// An IORING_HANDLE_REF specifying the file to write. + /// + /// An IORING_BUFFER_REF specifying the buffer into which the file is write. The provided buffer must have a size of at least + /// numberOfBytesToRead bytes. + /// + /// The number of bytes to write. + /// The offset into the file to begin reading. + /// The write flags. + /// + /// A UINT_PTR value identifying the file write operation. Specify this value when cancelling the operation with a call to + /// BuildIoRingCancelRequest. If an app implements cancellation behavior for the operation, the userData value must be unique. + /// Otherwise, the value is treated as opaque by the system and can be anything, including 0. + /// + /// + /// A bitwise OR combination of values from the IORING_SQE_FLAGS enumeration specifying kernel behavior options for I/O ring + /// submission queue entries. + /// + /// + /// Returns an HRESULT including, but not limited to the following: + /// + /// + /// Value + /// Description + /// + /// + /// S_OK + /// Success + /// + /// + /// IORING_E_SUBMISSION_QUEUE_FULL + /// + /// The submission queue is full, and no additional entries are available to build. The application must submit the existing entries + /// and wait for some of them to complete before adding more operations to the queue. + /// + /// + /// + /// IORING_E_UNKNOWN_REQUIRED_FLAG + /// + /// The application provided a required flag that is not known to the implementation. Library code should check the IoRingVersion + /// field of the IORING_INFO obtained from a call to GetIoRingInfo to determine the API version of an I/O ring which determines the + /// operations and flags that are supported. Applications should know the version they used to create the I/O ring and therefore + /// should not provide unsupported flags at runtime. + /// + /// + /// + /// + /// + /// Check I/O ring support for read file operations by calling IsIoRingOpSupported and specifying IORING_OP_WRITE for the op parameter. + /// + [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] + [PInvokeData("ioringapi.h", MinClient = PInvokeClient.Windows11)] + public static extern HRESULT BuildIoRingWriteFile([In] HIORING ioRing, IORING_HANDLE_REF fileRef, IORING_BUFFER_REF bufferRef, + uint numberOfBytesToWrite, ulong fileOffset, FILE_WRITE_FLAGS writeFlags, IntPtr userData, IORING_SQE_FLAGS sqeFlags); /// Closes an HIORING handle that was previously opened with a call to CreateIoRing. /// The HIORING handle to close. /// Returns S_OK on success. @@ -462,6 +586,53 @@ namespace Vanara.PInvoke [PInvokeData("ioringapi.h", MSDNShortId = "NF:ioringapi.QueryIoRingCapabilities", MinClient = PInvokeClient.Windows11)] public static extern HRESULT QueryIoRingCapabilities(out IORING_CAPABILITIES capabilities); + /// Registers a completion queue event with an I/O ring. + /// An HIORING representing a handle to the I/O ring for which the completion event is registered. + /// A handle to the event object. The CreateEvent or OpenEvent function returns this handle. + /// + /// Returns an HRESULT including the following values: + /// + /// + /// Value + /// Description + /// + /// + /// S_OK + /// Success + /// + /// + /// E_INVALID_HANDLE + /// An invalid handle was passed in the ioRing parameter. + /// + /// + /// E_INVALIDARG + /// An invalid handle was passed in the hEvent parameter. + /// + /// + /// + /// + /// + /// The kernel will signal this event when it places the first entry into an empty completion queue, i.e. the kernel only sets the + /// event to the signaled state when the completion queue transitions from the empty to non-empty state. Applications should call + /// PopIoRingCompletion until it indicates no more entries and then wait for any additional async completions to complete via the + /// provided HANDLE. Otherwise, the event won’t enter the signaled state and the wait may block until a timeout occurs, or forever if + /// an infinite timeout is used. + /// + /// + /// The kernel will internally duplicate the handle, so it is safe for the application to close the handle when waits are no longer + /// needed. Providing an event handle value of NULL simply clears any existing value. Setting a value of INVALID_HANDLE_VALUE raises + /// an error, as will any other invalid handle value, to aid in detecting code bugs early. + /// + /// + /// There is, at most, one event handle associated with an HIORING, attempting to set a second one will replace any that already exists. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/ioringapi/nf-ioringapi-setioringcompletionevent + // HRESULT SetIoRingCompletionEvent( HIORING ioRing, HANDLE hEvent ); + [PInvokeData("ioringapi.h", MSDNShortId = "NF:ioringapi.SetIoRingCompletionEvent")] + [DllImport(Lib.KernelBase, SetLastError = false, ExactSpelling = true)] + public static extern HRESULT SetIoRingCompletionEvent(HIORING ioRing, HEVENT hEvent); + /// /// Submits all constructed but not yet submitted entries to the kernel’s queue and optionally waits for a set of operations to complete. /// diff --git a/PInvoke/QoS/QoS2.cs b/PInvoke/QoS/QoS2.cs index 37ba8346..9d3f0b3c 100644 --- a/PInvoke/QoS/QoS2.cs +++ b/PInvoke/QoS/QoS2.cs @@ -12,7 +12,7 @@ public static partial class Qwave /// public const ulong QOS_OUTGOING_DEFAULT_MINIMUM_BANDWIDTH = 0xFFFFFFFF; - /// Flags used by . + /// Flags used by . [PInvokeData("qos2.h")] public enum QOS_FLOW_TYPE { diff --git a/PInvoke/User32/WinUser.Window.cs b/PInvoke/User32/WinUser.Window.cs index d19a2da6..c3e0d1b9 100644 --- a/PInvoke/User32/WinUser.Window.cs +++ b/PInvoke/User32/WinUser.Window.cs @@ -5927,6 +5927,111 @@ namespace Vanara.PInvoke [PInvokeData("winuser.h", MSDNShortId = "")] public static extern HWND SetActiveWindow(HWND hWnd); + /// + /// SetAdditionalForegroundBoostProcesses is a limited access feature. Contact + /// foregroundboostprocs@microsoft.com for more information. + /// + /// SetAdditionalForegroundBoostProcesses is a performance assist API to help applications with a multi-process application model + /// where multiple processes contribute to a foreground experience, either as data or rendering. Examples include browsers (with the + /// browser manager or frame, tabs, plugins, etc. hosted in different processes) and IDEs (which spawn processes for compilation and + /// other tasks). + /// + /// + /// Applications can use this API to provide a foreground priority boost to worker processes that help support the main application. + /// Such applications can have a uniform priority boost applied to all of their constituent processes when the application's top + /// level window is in the foreground. + /// + /// + /// A handle to the top level window (HWND) of the application. + /// + /// The number of process handles in processHandleArray. This function can be called at a single time with a maximum of 32 + /// handles. Set this parameter to 0 along with setting processHandleArray to NULL to clear a prior boost configuration. + /// + /// + /// A group of process handles to be foreground boosted or de-boosted. Set this parameter to NULL along with setting + /// processHandleCount to 0 to clear a prior boost configuration. + /// + /// + /// Returns TRUE if the call succeeds in boosting the application, FALSE otherwise. + /// SetAdditionalForegroundBoostProcesses sets the last error code, so the application can call GetLastError() to obtain + /// extended information if the call failed (for example, ERROR_INVALID_PARAMETER, ERROR_NOT_ENOUGH_MEMORY, or ERROR_ACCESS_DENIED). + /// + /// + /// + /// This function takes a group of process handles that all get foreground boosted or de-boosted when the passed-in top level HWND + /// moves to the foreground or background respectively. Whenever the passed-in top level HWND becomes the foreground window, a + /// foreground boost will also be applied to the processes passed in the handle array. A similar de-boost happens when the top level + /// HWND moves to the background. + /// + /// + /// The top level HWND passed to this function must be owned by the calling process. The calling process should have the + /// PROCESS_SET_INFORMATION access right on the process handles in the processHandleArray - in other words, you must + /// have full control of every window in your process. If some external component injects a window that takes foreground, or if a + /// dialog box appears, then you lose your boost. + /// + /// If you have two top level windows, you need to call this function for each one. + /// + /// If the passed-in top level HWND is already in the foreground when SetAdditionalForegroundBoostProcesses is called, all of + /// the processes in the processHandleArray are immediately boosted. + /// + /// + /// A process whose handle is in the processHandleArray will get a foreground boost only when the top level HWND becomes the + /// foreground window. + /// + /// Additional foreground boost is applied only when: + /// + /// + /// The foreground window changes, or + /// + /// + /// + /// If this function is called while the window is in the foreground and the new list has the process handle, or the list does not + /// include the process handle while it was previously included. + /// + /// + /// + /// + /// When the process owning the top level HWND exits or terminates, the additional boosting relationship is torn down and secondary + /// processes do not receive any additional foreground boosting. + /// + /// + /// The primary process's top level HWND will continue to hold references to secondary processes until either the primary process's + /// top level HWND clears its grouped boost state, or the HWND is destroyed. + /// + /// + /// + /// + /// In this simple scenario, the application sets up its foreground process boost configuration when the top level window is created. + /// When WM_CREATE is handled, the function is called with handles in the lParam and the count of handles in the wParam. These + /// processes will get foreground or background priority boosted as m_AppWindow moves in and out of being the foreground window. If + /// the m_AppWindow is the foreground window when the function is called, the processes will also get an immediate foreground + /// priority boost. + /// + /// (lParam); + /// DWORD cHandles = reinterpret_cast(wParam); + /// + /// if (!SetAdditionalForegroundBoostProcesses(m_AppWindow, cHandles, pMyHandles)) + /// { + /// printf(“SetAdditionalForegroundBoostProcesses() setup failed with error code: % d\n”, GetLastError()); + /// } + /// + /// break;]]> + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setadditionalforegroundboostprocesses + // BOOL SetAdditionalForegroundBoostProcesses( HWND topLevelWindow, DWORD processHandleCount, HANDLE *processHandleArray ); + [PInvokeData("Winuser.h", MSDNShortId = "NF:winuser.SetAdditionalForegroundBoostProcesses", MinClient = PInvokeClient.Windows11)] + [DllImport(Lib.User32, SetLastError = true, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SetAdditionalForegroundBoostProcesses(HWND topLevelWindow, uint processHandleCount, + [Optional, In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] HPROCESS[] processHandleArray); + /// /// /// Sets the mouse capture to the specified window belonging to the current thread. SetCapture captures mouse input either diff --git a/PInvoke/User32/WinUser.cs b/PInvoke/User32/WinUser.cs index 2cb907a3..28d03029 100644 --- a/PInvoke/User32/WinUser.cs +++ b/PInvoke/User32/WinUser.cs @@ -47,6 +47,20 @@ namespace Vanara.PInvoke AR_LAPTOP = 0x80, } + /// Defines constants that indicate whether a window is registered or unregistered to receive tooltip dismiss notifications. + /// This enumeration is used by the RegisterForTooltipDismissNotification function. + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/ne-winuser-tooltip_dismiss_flags + // typedef enum { TDF_REGISTER, TDF_UNREGISTER } TOOLTIP_DISMISS_FLAGS; + [PInvokeData("winuser.h", MSDNShortId = "NE:winuser.__unnamed_enum_2")] + public enum TOOLTIP_DISMISS_FLAGS + { + /// The window is registered to receive tooltip dismiss notifications. + TDF_REGISTER, + + /// The window is unregistered from receiving tooltip dismiss notifications. + TDF_UNREGISTER, + } + /// /// Translates a string into the OEM-defined character set. /// Warning Do not use. See Security Considerations. @@ -196,6 +210,76 @@ namespace Vanara.PInvoke [return: MarshalAs(UnmanagedType.Bool)] public static extern bool OemToCharBuff(string lpszSrc, StringBuilder lpszDst, uint cchDstLength); + /// Registers or unregisters windows to receive notification to dismiss their tooltip windows. + /// + /// Type: HWND + /// The handle of the window to receive the WM_TOOLTIPDISMISS message. + /// + /// + /// Type: TOOLTIP_DISMISS_FLAGS + /// + /// A value of the enumeration that specifies whether the function registers or unregisters the window. TDF_REGISTER to + /// register; TDF_UNREGISTER to unregister. + /// + /// + /// TRUE if the window was successfully registered or unregistered; otherwise, FALSE. (See Remarks.) + /// + /// + /// This function makes tooltips more accessible by letting apps and frameworks that support tooltips register and unregister to be + /// notified by a WM_TOOLTIPDISMISS message when the system requires all showing tooltips to be dismissed. + /// + /// + /// Apps should register for this notification each time they show a tooltip and hide their tooltips in response to a + /// WM_TOOLTIPDISMISS message. When a tooltip is hidden for some other reason, like a mouse action, the app should unregister. + /// + /// + /// System-defined triggers for tooltip dismissal include a solitary Ctrl key up or Ctrl+Shift+F10. (The set of triggers may change + /// over time.) + /// + /// The function takes either the HWND of a tooltip window or the HWND of an app window that has child tooltips. + /// + /// + /// + /// If a tooltip HWND itself is registered, the tooltip window is expected to register upon showing and to dismiss upon + /// receiving a WM_TOOLTIPDISMISS message. + /// + /// + /// + /// + /// If an app HWND registers on behalf of its tooltips, the app's window is expected to register upon showing tooltips and + /// dismiss all of its tooltips upon receiving a WM_TOOLTIPDISMISS message. + /// + /// + /// + /// + /// Tooltip or app windows are expected to call the function to register each time tooltips are shown. Registered windows are + /// automatically unregistered upon posting WM_TOOLTIPDISMISS. + /// + /// + /// The TDF_UNREGISTER flag is used to explicitly unregister a window when a tooltip window is dismissed by application or + /// framework prerogative (such as moving the cursor out of the "safe zone"). If an app or framework calls with TDF_UNREGISTER + /// after the window has been automatically unregistered, the function returns FALSE. There is no impact on future registrations. + /// + /// Return values + /// The HWND passed into the function must be owned by the calling process; otherwise, the function returns FALSE. + /// + /// When called with TDF_REGISTER and a window belonging to the calling process, the function returns TRUE if the + /// window was successfully registered or FALSE if the window was already registered. The window is treated as registered + /// either way. + /// + /// + /// When called with TDF_UNREGISTER and a windows belonging to the calling process, the function returns TRUE if the + /// window is successfully unregistered, or FALSE if the windows was not currently registered. The window is treated as + /// unregistered either way. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-registerfortooltipdismissnotification?view=vs-2019 + // BOOL RegisterForTooltipDismissNotification( HWND hWnd, TOOLTIP_DISMISS_FLAGS tdFlags ); + [PInvokeData("winuser.h", MSDNShortId = "NF:winuser.RegisterForTooltipDismissNotification")] + [DllImport(Lib.User32, SetLastError = false, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool RegisterForTooltipDismissNotification(HWND hWnd, TOOLTIP_DISMISS_FLAGS tdFlags); + /// /// Sets the last-error code. /// Currently, this function is identical to the SetLastError function. The second parameter is ignored. diff --git a/PInvoke/WinHTTP/WinHTTP.Funcs2.cs b/PInvoke/WinHTTP/WinHTTP.Funcs2.cs index 9a7817ac..d5b8af15 100644 --- a/PInvoke/WinHTTP/WinHTTP.Funcs2.cs +++ b/PInvoke/WinHTTP/WinHTTP.Funcs2.cs @@ -2,2458 +2,2642 @@ 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 +namespace Vanara.PInvoke; + +/// Items from the WinHTTP.dll. +public static partial class WinHTTP { - /// Items from the WinHTTP.dll. - public static partial class WinHTTP + /// Represents an application-defined proxy change callback function. + /// + /// Type: _In_ ULONGLONG + /// The flag passed to the WinHttpRegisterProxyChangeNotification function (for example, WINHTTP_PROXY_NOTIFY_CHANGE). + /// + /// + /// Type: _In_ PVOID + /// The context object pointer passed to the WinHttpRegisterProxyChangeNotification function. + /// + /// None + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nc-winhttp-winhttp_proxy_change_callback WINHTTP_PROXY_CHANGE_CALLBACK + // WinhttpProxyChangeCallback; void WinhttpProxyChangeCallback( ULONGLONG ullFlags, PVOID pvContext ) {...} + [PInvokeData("winhttp.h", MSDNShortId = "NC:winhttp.WINHTTP_PROXY_CHANGE_CALLBACK")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate void WINHTTP_PROXY_CHANGE_CALLBACK(ulong ullFlags, IntPtr pvContext); + + /// Frees the data retrieved from a previous call to WinHttpGetProxySettingsResultEx. + /// + /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE + /// A proxy settings type. + /// + /// + /// Type: _In_ PVOID + /// A pointer to a WINHTTP_PROXY_SETTINGS_EX structure that was retrieved from a previous call to WinHttpGetProxySettingsResultEx. + /// + /// This function does not return a value. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpfreeproxysettingsex WINHTTPAPI DWORD + // WinHttpFreeProxySettingsEx( WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PVOID pProxySettingsEx ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpFreeProxySettingsEx")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpFreeProxySettingsEx(WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, + IntPtr pProxySettingsEx); + + /// Retrieves extended proxy settings. + /// + /// Type: _In_ HINTERNET + /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. + /// + /// + /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE + /// A proxy settings type. + /// + /// + /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM + /// An optional pointer to a WINHTTP_PROXY_SETTINGS_PARAM. + /// + /// + /// Type: _In_opt_ DWORD_PTR + /// An optional pointer to a DWORD containing context data that will be passed to the completion callback function. + /// + /// + /// + /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). + /// + /// + /// + /// Code + /// Description + /// + /// + /// ERROR_IO_PENDING + /// The operation is continuing asynchronously. + /// + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsex WINHTTPAPI DWORD + // WinHttpGetProxySettingsEx( HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PWINHTTP_PROXY_SETTINGS_PARAM + // pProxySettingsParam, DWORD_PTR pContext ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsEx")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, + in WINHTTP_PROXY_SETTINGS_PARAM pProxySettingsParam, IntPtr pContext); + + /// Retrieves extended proxy settings. + /// + /// Type: _In_ HINTERNET + /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. + /// + /// + /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE + /// A proxy settings type. + /// + /// + /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM + /// An optional pointer to a WINHTTP_PROXY_SETTINGS_PARAM. + /// + /// + /// Type: _In_opt_ DWORD_PTR + /// An optional pointer to a DWORD containing context data that will be passed to the completion callback function. + /// + /// + /// + /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). + /// + /// + /// + /// Code + /// Description + /// + /// + /// ERROR_IO_PENDING + /// The operation is continuing asynchronously. + /// + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsex WINHTTPAPI DWORD + // WinHttpGetProxySettingsEx( HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, PWINHTTP_PROXY_SETTINGS_PARAM + // pProxySettingsParam, DWORD_PTR pContext ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsEx")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, + [In, Optional] IntPtr pProxySettingsParam, IntPtr pContext); + + /// Retrieves the results of a call to WinHttpGetProxySettingsEx. + /// + /// Type: _In_ HINTERNET + /// The WinHTTP resolver handle returned by the WinHttpCreateProxyResolver function. + /// + /// + /// Type: _In_ WINHTTP_PROXY_SETTINGS_TYPE + /// A proxy settings type. + /// + /// + /// Type: _In_opt_ PWINHTTP_PROXY_SETTINGS_PARAM + /// An optional WINHTTP_PROXY_SETTINGS_PARAM. + /// + /// A WINHTTP_PROXY_SETTINGS_EX structure. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsresultex WINHTTPAPI DWORD + // WinHttpGetProxySettingsResultEx( HINTERNET hResolver, PVOID pProxySettingsEx ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsResultEx")] + public static Win32Error WinHttpGetProxySettingsEx(HINTERNET hResolver, WINHTTP_PROXY_SETTINGS_TYPE ProxySettingsType, + WINHTTP_PROXY_SETTINGS_PARAM? pProxySettingsParam, out WINHTTP_PROXY_SETTINGS_EX_MGD pProxySettingsEx) { - /// 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); - - /// Also see WinHttpReadDataEx. - /// - /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable - /// must have been called for this handle and must have completed before WinHttpReadData is called. Although calling - /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing - /// so requires that the application use a fixed-length buffer for reading. - /// - /// - /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. - /// - /// Unsigned long integer value that contains the number of bytes to read. - /// - /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to - /// zero before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and - /// retrieve the information in the callback function; not doing so can cause a memory fault. - /// - /// - /// - /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following - /// table identifies the error codes that are returned. - /// - /// - /// - /// Error Code - /// Description - /// - /// - /// ERROR_WINHTTP_CONNECTION_ERROR - /// - /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, - /// WinHTTP 5.1 does not support SSL2 unless the client specifically enables it. - /// - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE - /// The requested operation cannot be carried out because the handle supplied is not in the correct state. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE - /// The type of handle supplied is incorrect for this operation. - /// - /// - /// ERROR_WINHTTP_INTERNAL_ERROR - /// An internal error has occurred. - /// - /// - /// ERROR_WINHTTP_OPERATION_CANCELLED - /// - /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. - /// - /// - /// - /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW - /// Returned when an incoming response exceeds an internal WinHTTP size limit. - /// - /// - /// ERROR_WINHTTP_TIMEOUT - /// The request has timed out. - /// - /// - /// ERROR_NOT_ENOUGH_MEMORY - /// Not enough memory was available to complete the requested operation. (Windows error code) - /// - /// - /// - /// - /// - /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent - /// to the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking - /// information before giving the data to the application. - /// - /// - /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this - /// function can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you - /// can call GetLastError to get extended error information. If this function returns TRUE, use the - /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion to determine whether this function was successful and the value of the - /// parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. - /// - /// - /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL - /// and retrieve the bytes read in the callback function; otherwise, a memory fault can occur. - /// - /// - /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the - /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion triggers another call to WinHttpReadData, the situation can result in a - /// stack overflow. In general, it is best to use a read buffer that is comparable in size, or larger than the internal read buffer - /// used by WinHTTP, which is 8 KB. - /// - /// - /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, - /// the transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a - /// local file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the - /// dwStatusInformationLength parameter set to zero when the end of a response is found. - /// - /// - /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the - /// response. If sufficient data has not arrived from the server, the buffer is not filled. - /// - /// - /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse - /// must be made on the handle before WinHttpReadData can be used. - /// - /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. - /// - /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the - /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow - /// can result. It is best to use a read buffer that is 8 Kilobytes or larger in size. - /// - /// - /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by - /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML - /// encoded directory entries, it must be large enough to hold at least one complete entry. - /// - /// - /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications - /// that have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking - /// for available data: - /// - /// - /// - /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE - /// - /// - /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED - /// - /// - /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED - /// - /// - /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE - /// - /// - /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. - /// Examples - /// - /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer - /// Protocol (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS - /// server, then opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to - /// determine how much data is available for download, then WinHttpReadData is used to read that data. This process repeats - /// until the entire document has been retrieved and displayed. - /// - /// - /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET - // hRequest, [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); - [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] - [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, out int lpdwNumberOfBytesRead); - - /// Reads data from a handle opened by the WinHttpOpenRequest function. - /// - /// Type: IN HINTERNET - /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. - /// - /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before - /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of - /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length - /// buffer for reading. - /// - /// - /// - /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID - /// - /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. - /// - /// - /// - /// Type: IN DWORD - /// Unsigned long integer value that contains the number of bytes to read. - /// - /// - /// Type: OUT LPDWORD - /// - /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to - /// zero before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and - /// retrieve the information in the callback function; not doing so can cause a memory fault. - /// - /// - /// - /// Type: IN ULONGLONG - /// - /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until - /// the provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API - /// equivalent to that of WinHttpReadData. - /// - /// - /// - /// Type: IN DWORD - /// Reserved. Pass 0. - /// - /// - /// Type: _In_reads_bytes_opt_(cbProperty) PVOID - /// Reserved. Pass NULL. - /// - /// - /// A status code indicating the result of the operation. Among the error codes returned are the following. - /// - /// - /// Error Code - /// Description - /// - /// - /// ERROR_WINHTTP_CONNECTION_ERROR - /// - /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, - /// WinHTTP 5.1 does not support SSL2 unless the client specifically enables it. - /// - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE - /// The requested operation cannot be carried out because the handle supplied is not in the correct state. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE - /// The type of handle supplied is incorrect for this operation. - /// - /// - /// ERROR_WINHTTP_INTERNAL_ERROR - /// An internal error has occurred. - /// - /// - /// ERROR_WINHTTP_OPERATION_CANCELLED - /// - /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. - /// - /// - /// - /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW - /// Returned when an incoming response exceeds an internal WinHTTP size limit. - /// - /// - /// ERROR_WINHTTP_TIMEOUT - /// The request has timed out. - /// - /// - /// ERROR_NOT_ENOUGH_MEMORY - /// Not enough memory was available to complete the requested operation. (Windows error code) - /// - /// - /// - /// - /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the - /// function won't always completely fill the buffer that you provide). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( - // HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD - // cbProperty, PVOID pvProperty ); - [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] - [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] - public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, - out uint lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); - - /// Reads data from a handle opened by the WinHttpOpenRequest function. - /// - /// Type: IN HINTERNET - /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. - /// - /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before - /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of - /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length - /// buffer for reading. - /// - /// - /// - /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID - /// - /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. - /// - /// - /// - /// Type: IN DWORD - /// Unsigned long integer value that contains the number of bytes to read. - /// - /// - /// Type: OUT LPDWORD - /// - /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to - /// zero before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and - /// retrieve the information in the callback function; not doing so can cause a memory fault. - /// - /// - /// - /// Type: IN ULONGLONG - /// - /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until - /// the provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API - /// equivalent to that of WinHttpReadData. - /// - /// - /// - /// Type: IN DWORD - /// Reserved. Pass 0. - /// - /// - /// Type: _In_reads_bytes_opt_(cbProperty) PVOID - /// Reserved. Pass NULL. - /// - /// - /// A status code indicating the result of the operation. Among the error codes returned are the following. - /// - /// - /// Error Code - /// Description - /// - /// - /// ERROR_WINHTTP_CONNECTION_ERROR - /// - /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, - /// WinHTTP 5.1 does not support SSL2 unless the client specifically enables it. - /// - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE - /// The requested operation cannot be carried out because the handle supplied is not in the correct state. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE - /// The type of handle supplied is incorrect for this operation. - /// - /// - /// ERROR_WINHTTP_INTERNAL_ERROR - /// An internal error has occurred. - /// - /// - /// ERROR_WINHTTP_OPERATION_CANCELLED - /// - /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. - /// - /// - /// - /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW - /// Returned when an incoming response exceeds an internal WinHTTP size limit. - /// - /// - /// ERROR_WINHTTP_TIMEOUT - /// The request has timed out. - /// - /// - /// ERROR_NOT_ENOUGH_MEMORY - /// Not enough memory was available to complete the requested operation. (Windows error code) - /// - /// - /// - /// - /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the - /// function won't always completely fill the buffer that you provide). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( - // HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD - // cbProperty, PVOID pvProperty ); - [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] - [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] - public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, - out int lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); - - /// - /// The WinHttpReceiveResponse function waits to receive the response to an HTTP request initiated by WinHttpSendRequest. When - /// WinHttpReceiveResponse completes successfully, the status code and response headers have been received and are available - /// for the application to inspect using WinHttpQueryHeaders. An application must call WinHttpReceiveResponse before it can - /// use WinHttpQueryDataAvailable and WinHttpReadData to access the response entity body (if any). - /// - /// - /// HINTERNET handle returned by WinHttpOpenRequest and sent by WinHttpSendRequest. Wait until WinHttpSendRequest has - /// completed for this handle before calling WinHttpReceiveResponse. - /// - /// This parameter is reserved and must be NULL. - /// - /// - /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error - /// codes returned are the following. - /// - /// - /// - /// Error Code - /// Description - /// - /// - /// ERROR_WINHTTP_CANNOT_CONNECT - /// Returned if connection to the server failed. - /// - /// - /// ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW - /// Returned when an overflow condition is encountered in the course of parsing chunked encoding. - /// - /// - /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED - /// Returned when the server requests client authentication. - /// - /// - /// ERROR_WINHTTP_CONNECTION_ERROR - /// - /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, - /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. - /// - /// - /// - /// ERROR_WINHTTP_HEADER_COUNT_EXCEEDED - /// Returned when a larger number of headers were present in a response than WinHTTP could receive. - /// - /// - /// ERROR_WINHTTP_HEADER_SIZE_OVERFLOW - /// Returned by WinHttpReceiveResponse when the size of headers received exceeds the limit for the request handle. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE - /// The requested operation cannot be carried out because the handle supplied is not in the correct state. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE - /// The type of handle supplied is incorrect for this operation. - /// - /// - /// ERROR_WINHTTP_INTERNAL_ERROR - /// An internal error has occurred. - /// - /// - /// ERROR_WINHTTP_INVALID_SERVER_RESPONSE - /// The server response could not be parsed. - /// - /// - /// ERROR_WINHTTP_INVALID_URL - /// The URL is invalid. - /// - /// - /// ERROR_WINHTTP_LOGIN_FAILURE - /// - /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new - /// request handle must be created before retrying the function that originally produced this error. - /// - /// - /// - /// ERROR_WINHTTP_NAME_NOT_RESOLVED - /// The server name could not be resolved. - /// - /// - /// ERROR_WINHTTP_OPERATION_CANCELLED - /// - /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. - /// - /// - /// - /// ERROR_WINHTTP_REDIRECT_FAILED - /// The redirection failed because either the scheme changed or all attempts made to redirect failed (default is five attempts). - /// - /// - /// ERROR_WINHTTP_RESEND_REQUEST - /// The WinHTTP function failed. The desired function can be retried on the same request handle. - /// - /// - /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW - /// Returned when an incoming response exceeds an internal WinHTTP size limit. - /// - /// - /// ERROR_WINHTTP_SECURE_FAILURE - /// - /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error - /// was encountered, check for a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more - /// information, see WINHTTP_STATUS_CALLBACK. - /// - /// - /// - /// ERROR_WINHTTP_TIMEOUT - /// The request has timed out. - /// - /// - /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME - /// The URL specified a scheme other than "http:" or "https:". - /// - /// - /// ERROR_NOT_ENOUGH_MEMORY - /// Not enough memory was available to complete the requested operation. (Windows error code) - /// - /// - /// - /// - /// - /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this - /// function can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you - /// can call GetLastError to get extended error information. If this function returns TRUE, the application should expect - /// either the WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE completion callback, indicating success, or the - /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion callback, indicating that the operation completed asynchronously, but failed. - /// - /// - /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that - /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in receiving the response: - /// - /// - /// - /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE - /// - /// - /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED - /// - /// - /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE - /// - /// - /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE - /// - /// - /// WINHTTP_CALLBACK_STATUS_REDIRECT - /// - /// - /// - /// If the server closes the connection, the following notifications will also be reported, provided that they have been set in the - /// dwNotificationFlags parameter of WinHttpSetStatusCallback: - /// - /// - /// - /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION - /// - /// - /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED - /// - /// - /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. - /// Examples - /// - /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is - /// fictitious and must be replaced with the name of a server for which you have write access. - /// - /// - /// LPSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreceiveresponse WINHTTPAPI BOOL - // WinHttpReceiveResponse( [in] HINTERNET hRequest, [in] LPVOID lpReserved ); - [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] - [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReceiveResponse")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool WinHttpReceiveResponse(HINTERNET hRequest, [In, Optional] IntPtr lpReserved); - - /// 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, in 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); - - /// The WinHttpWriteData function writes request data to an HTTP server. - /// - /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. - /// - /// - /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after - /// WinHttpWriteData completes. - /// - /// Unsigned long integer value that contains the number of bytes to be written to the file. - /// - /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData - /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must - /// be set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. - /// - /// - /// - /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error - /// codes returned are: - /// - /// - /// - /// Error Code - /// Description - /// - /// - /// ERROR_WINHTTP_CONNECTION_ERROR - /// - /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, - /// WinHTTP version 5.1 does not support SSL2 unless the client specifically enables it. - /// - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE - /// The requested operation cannot be carried out because the handle supplied is not in the correct state. - /// - /// - /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE - /// The type of handle supplied is incorrect for this operation. - /// - /// - /// ERROR_WINHTTP_INTERNAL_ERROR - /// An internal error has occurred. - /// - /// - /// ERROR_WINHTTP_OPERATION_CANCELLED - /// - /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. - /// - /// - /// - /// ERROR_WINHTTP_TIMEOUT - /// The request has timed out. - /// - /// - /// ERROR_NOT_ENOUGH_MEMORY - /// Not enough memory was available to complete the requested operation. (Windows error code) - /// - /// - /// - /// - /// - /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this - /// function can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to - /// get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion - /// to determine whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR - /// completion indicates that the operation completed asynchronously, but failed. - /// - /// - /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and - /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. - /// - /// - /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is - /// called, then the data transfer is aborted. - /// - /// - /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that - /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to - /// the server: - /// - /// - /// - /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE - /// - /// - /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED - /// - /// - /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN - /// - /// - /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST - /// - /// - /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT - /// - /// - /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE - /// - /// - /// - /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate - /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be - /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. - /// NTLM and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails - /// if the connection is broken prematurely. - /// - /// - /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for - /// each authentication legs. This can be very inefficient for large data uploads. - /// - /// - /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir - /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is - /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. - /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the - /// same socket as long as the socket is not pooled with concurrent requests competing for it. - /// - /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. - /// Examples - /// - /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is - /// fictitious and must be replaced with the name of a server for which you have write access. - /// - /// - /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET - // hRequest, [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); - [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] - [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] byte[] lpBuffer, int dwNumberOfBytesToWrite, out int lpdwNumberOfBytesWritten); + pProxySettingsEx = default; + using var pParam = pProxySettingsParam.HasValue ? new SafeCoTaskMemStruct(pProxySettingsParam.Value) : SafeCoTaskMemStruct.Null; + var ret = WinHttpGetProxySettingsEx(hResolver, ProxySettingsType, pParam, default); + if (ret.Failed) + return ret; + IntPtr ptr = default; + ret = WinHttpGetProxySettingsResultEx(hResolver, ptr); + if (ret.Failed) + return ret; + pProxySettingsEx = ptr.ToStructure(); + WinHttpFreeProxySettingsEx(ProxySettingsType, ptr); + return ret; } + + /// Retrieves the results of a call to WinHttpGetProxySettingsEx. + /// + /// Type: _In_ HINTERNET + /// The resolver handle used to issue a previously completed call to WinHttpGetProxySettingsEx. + /// + /// + /// A pointer to a WINHTTP_PROXY_SETTINGS_EX structure. The memory occupied by the structure is allocated by + /// WinHttpGetProxySettingsResultEx, so you need to free that memory by passing this pointer to WinHttpFreeProxySettingsEx. + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpgetproxysettingsresultex + // WINHTTPAPI DWORD WinHttpGetProxySettingsResultEx( HINTERNET hResolver, PVOID pProxySettingsEx ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpGetProxySettingsResultEx")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpGetProxySettingsResultEx(HINTERNET hResolver, IntPtr pProxySettingsEx); + + /// The WinHttpQueryOption function queries an Internet option on the specified handle. + /// + /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, + /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying a + /// particular option. + /// + /// + /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. + /// + /// + /// A pointer to a buffer that receives the option setting. Strings returned by the WinHttpQueryOption function are globally + /// allocated, so the calling application must globally free the string when it finishes using it. Setting this parameter to NULL + /// causes this function to return FALSE. Calling GetLastError then returns ERROR_INSUFFICIENT_BUFFER and lpdwBufferLength + /// contains the number of bytes required to hold the requested information. + /// + /// + /// A pointer to an unsigned long integer variable that contains the length of lpBuffer, in bytes. When the function returns, the + /// variable receives the length of the data placed into lpBuffer. If GetLastError returns ERROR_INSUFFICIENT_BUFFER, this + /// parameter receives the number of bytes required to hold the requested information. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get a specific error message, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// An invalid option value was specified. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// GetLastError returns the ERROR_INVALID_PARAMETER if an option flag that is invalid for the specified handle type is passed to the + /// dwOption parameter. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// This example demonstrates retrieving the connection time-out value: + /// + /// DWORD data; DWORD dwSize = sizeof(DWORD); // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpQueryOption to retrieve internet options. if (WinHttpQueryOption( hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &data, &dwSize)) { printf("Connection timeout: %u ms\n\n",data); } else { printf( "Error %u in WinHttpQueryOption.\n", GetLastError()); } // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [Out, Optional] IntPtr lpBuffer, ref uint lpdwBufferLength); + + /// The WinHttpQueryOption function queries an Internet option on the specified handle. + /// The type of the option. + /// + /// An HINTERNET handle on which to query information. Note that this can be either a Session handle or a Request handle, + /// depending on what option is being queried; see the Option Flags topic to determine which handle is appropriate to use in querying a + /// particular option. + /// + /// + /// An unsigned long integer value that contains the Internet option to query. This can be one of the Option Flags values. + /// + /// The option setting. + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpqueryoption BOOL WinHttpQueryOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [out] LPVOID lpBuffer, [in, out] LPDWORD lpdwBufferLength ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpQueryOption")] + public static T WinHttpQueryOption(HINTERNET hInternet, WINHTTP_OPTION dwOption) + { + Type rType = CorrespondingTypeAttribute.GetCorrespondingTypes(dwOption, CorrespondingAction.Get).FirstOrDefault() ?? typeof(T); + if (typeof(T) != typeof(object)) + { + rType = typeof(T); + } + + uint sz = 0; + WinHttpQueryOption(hInternet, dwOption, default, ref sz); + Win32Error.ThrowLastErrorUnless(Win32Error.ERROR_INSUFFICIENT_BUFFER); + using SafeHGlobalHandle buffer = new(sz); + Win32Error.ThrowLastErrorIfFalse(WinHttpQueryOption(hInternet, dwOption, buffer, ref sz)); + return (T)buffer.DangerousGetHandle().Convert(sz, rType, CharSet.Unicode); + } + + /// Also see WinHttpReadDataEx. + /// + /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable must + /// have been called for this handle and must have completed before WinHttpReadData is called. Although calling + /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing so + /// requires that the application use a fixed-length buffer for reading. + /// + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. + /// + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to zero + /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the + /// information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table + /// identifies the error codes that are returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to + /// the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking + /// information before giving the data to the application. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call + /// GetLastError to get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// completion to determine whether this function was successful and the value of the parameters. The + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. + /// + /// + /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL and + /// retrieve the bytes read in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// completion triggers another call to WinHttpReadData, the situation can result in a stack overflow. In general, it is best to + /// use a read buffer that is comparable in size, or larger than the internal read buffer used by WinHTTP, which is 8 KB. + /// + /// + /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, the + /// transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a local + /// file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the + /// dwStatusInformationLength parameter set to zero when the end of a response is found. + /// + /// + /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the + /// response. If sufficient data has not arrived from the server, the buffer is not filled. + /// + /// + /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse + /// must be made on the handle before WinHttpReadData can be used. + /// + /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. + /// + /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow can + /// result. It is best to use a read buffer that is 8 Kilobytes or larger in size. + /// + /// + /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by + /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML encoded + /// directory entries, it must be large enough to hold at least one complete entry. + /// + /// + /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for + /// available data: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer Protocol + /// (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS server, then + /// opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much + /// data is available for download, then WinHttpReadData is used to read that data. This process repeats until the entire document + /// has been retrieved and displayed. + /// + /// + /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET hRequest, + // [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, out uint lpdwNumberOfBytesRead); + + /// Also see WinHttpReadDataEx. + /// + /// Valid HINTERNET handle returned from a previous call to WinHttpOpenRequest. WinHttpReceiveResponse or WinHttpQueryDataAvailable must + /// have been called for this handle and must have completed before WinHttpReadData is called. Although calling + /// WinHttpReadData immediately after completion of WinHttpReceiveResponse avoids the expense of a buffer copy, doing so + /// requires that the application use a fixed-length buffer for reading. + /// + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadData has completed. + /// + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadData sets this value to zero + /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the + /// information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table + /// identifies the error codes that are returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to + /// the server. When the Transfer-Encoding header is present on the WinHttp response, WinHttpReadData strips the chunking + /// information before giving the data to the application. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call + /// GetLastError to get extended error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// completion to determine whether this function was successful and the value of the parameters. The + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. + /// + /// + /// Warning When WinHTTP is used in asynchronous mode, always set the lpdwNumberOfBytesRead parameter to NULL and + /// retrieve the bytes read in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the read buffer is very small, WinHttpReadData might complete synchronously. If the WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// completion triggers another call to WinHttpReadData, the situation can result in a stack overflow. In general, it is best to + /// use a read buffer that is comparable in size, or larger than the internal read buffer used by WinHTTP, which is 8 KB. + /// + /// + /// If you are using WinHttpReadData synchronously, and the return value is TRUE and the number of bytes read is zero, the + /// transfer has been completed and there are no more bytes to read on the handle. This is analogous to reaching end-of-file in a local + /// file. If you are using the function asynchronously, the WINHTTP_CALLBACK_STATUS_READ_COMPLETE callback is called with the + /// dwStatusInformationLength parameter set to zero when the end of a response is found. + /// + /// + /// WinHttpReadData tries to fill the buffer pointed to by lpBuffer until there is no more data available from the + /// response. If sufficient data has not arrived from the server, the buffer is not filled. + /// + /// + /// For HINTERNET handles created by the WinHttpOpenRequest function and sent by WinHttpSendRequest, a call to WinHttpReceiveResponse + /// must be made on the handle before WinHttpReadData can be used. + /// + /// Single byte characters retrieved with WinHttpReadData are not converted to multi-byte characters. + /// + /// When the read buffer is very small, WinHttpReadData may complete synchronously, and if the + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE completion then triggers another call to WinHttpReadData, a stack overflow can + /// result. It is best to use a read buffer that is 8 Kilobytes or larger in size. + /// + /// + /// If sufficient data has not arrived from the server, WinHttpReadData does not entirely fill the buffer pointed to by + /// lpBuffer. The buffer must be large enough at least to hold the HTTP headers on the first read, and when reading HTML encoded + /// directory entries, it must be large enough to hold at least one complete entry. + /// + /// + /// If a status callback function has been installed by using WinHttpSetStatusCallback, then those of the following notifications that + /// have been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in checking for + /// available data: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// WINHTTP_CALLBACK_STATUS_READ_COMPLETE + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to use secure transaction semantics to download a resource from an Secure Hypertext Transfer Protocol + /// (HTTPS) server. The sample code initializes the WinHTTP application programming interface (API), selects a target HTTPS server, then + /// opens and sends a request for this secure resource. WinHttpQueryDataAvailable is used with the request handle to determine how much + /// data is available for download, then WinHttpReadData is used to read that data. This process repeats until the entire document + /// has been retrieved and displayed. + /// + /// + /// DWORD dwSize = 0; DWORD dwDownloaded = 0; LPSTR pszOutBuffer; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"WinHTTP Example/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.microsoft.com", INTERNET_DEFAULT_HTTPS_PORT, 0); // Create an HTTP request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"GET", NULL, NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_SECURE); // Send a request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Keep checking for data until there is nothing left. if (bResults) { do { // Check for available data. dwSize = 0; if (!WinHttpQueryDataAvailable( hRequest, &dwSize)) { printf( "Error %u in WinHttpQueryDataAvailable.\n", GetLastError()); break; } // No more available data. if (!dwSize) break; // Allocate space for the buffer. pszOutBuffer = new char[dwSize+1]; if (!pszOutBuffer) { printf("Out of memory\n"); break; } // Read the Data. ZeroMemory(pszOutBuffer, dwSize+1); if (!WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded)) { printf( "Error %u in WinHttpReadData.\n", GetLastError()); } else { printf("%s", pszOutBuffer); } // Free the memory allocated to the buffer. delete [] pszOutBuffer; // This condition should never be reached since WinHttpQueryDataAvailable // reported that there are bits to read. if (!dwDownloaded) break; } while (dwSize > 0); } else { // Report any errors. printf( "Error %d has occurred.\n", GetLastError() ); } // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddata BOOL WinHttpReadData( [in] HINTERNET hRequest, + // [out] LPVOID lpBuffer, [in] DWORD dwNumberOfBytesToRead, [out] LPDWORD lpdwNumberOfBytesRead ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpReadData(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, out int lpdwNumberOfBytesRead); + + /// Reads data from a handle opened by the WinHttpOpenRequest function. + /// + /// Type: IN HINTERNET + /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. + /// + /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before + /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of + /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length buffer + /// for reading. + /// + /// + /// + /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. + /// + /// + /// + /// Type: IN DWORD + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// + /// Type: OUT LPDWORD + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to zero + /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the + /// information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Type: IN ULONGLONG + /// + /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until the + /// provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API equivalent to + /// that of WinHttpReadData. + /// + /// + /// + /// Type: IN DWORD + /// Reserved. Pass 0. + /// + /// + /// Type: _In_reads_bytes_opt_(cbProperty) PVOID + /// Reserved. Pass NULL. + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the function + /// won't always completely fill the buffer that you provide). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( HINTERNET + // hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD cbProperty, PVOID + // pvProperty ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] + public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] IntPtr lpBuffer, uint dwNumberOfBytesToRead, + out uint lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); + + /// Reads data from a handle opened by the WinHttpOpenRequest function. + /// + /// Type: IN HINTERNET + /// An HINTERNET handle returned from a previous call to WinHttpOpenRequest. + /// + /// WinHttpReceiveResponse or WinHttpQueryDataAvailable must have been called for this handle and must have completed before + /// WinHttpReadDataEx is called. Although calling WinHttpReadDataEx immediately after completion of + /// WinHttpReceiveResponse avoids the expense of a buffer copy, doing so requires that your application use a fixed-length buffer + /// for reading. + /// + /// + /// + /// Type: _Out_writes_bytes_to_(dwNumberOfBytesToRead, *lpdwNumberOfBytesRead) __out_data_source(NETWORK) LPVOID + /// + /// Pointer to a buffer that receives the data read. Make sure that this buffer remains valid until WinHttpReadDataEx has completed. + /// + /// + /// + /// Type: IN DWORD + /// Unsigned long integer value that contains the number of bytes to read. + /// + /// + /// Type: OUT LPDWORD + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes read. WinHttpReadDataEx sets this value to zero + /// before doing any work or error checking. When using WinHTTP asynchronously, always set this parameter to NULL and retrieve the + /// information in the callback function; not doing so can cause a memory fault. + /// + /// + /// + /// Type: IN ULONGLONG + /// + /// If you pass WINHTTP_READ_DATA_EX_FLAG_FILL_BUFFER, then WinHttp won't complete the call to WinHttpReadDataEx until the + /// provided data buffer has been filled, or the response is complete. Passing this flag makes the behavior of this API equivalent to + /// that of WinHttpReadData. + /// + /// + /// + /// Type: IN DWORD + /// Reserved. Pass 0. + /// + /// + /// Type: _In_reads_bytes_opt_(cbProperty) PVOID + /// Reserved. Pass NULL. + /// + /// + /// A status code indicating the result of the operation. Among the error codes returned are the following. + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// By default, WinHttpReadDataEx returns after any amount of data has been written to the buffer that you provide (the function + /// won't always completely fill the buffer that you provide). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreaddataex WINHTTPAPI DWORD WinHttpReadDataEx( HINTERNET + // hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead, ULONGLONG ullFlags, DWORD cbProperty, PVOID + // pvProperty ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReadDataEx")] + public static extern Win32Error WinHttpReadDataEx(HINTERNET hRequest, [Out] byte[] lpBuffer, int dwNumberOfBytesToRead, + out int lpdwNumberOfBytesRead, [Optional] WINHTTP_READ_DATA_EX_FLAG ullFlags, [Optional] uint cbProperty, [Optional] IntPtr pvProperty); + + /// + /// The WinHttpReceiveResponse function waits to receive the response to an HTTP request initiated by WinHttpSendRequest. When + /// WinHttpReceiveResponse completes successfully, the status code and response headers have been received and are available for + /// the application to inspect using WinHttpQueryHeaders. An application must call WinHttpReceiveResponse before it can use + /// WinHttpQueryDataAvailable and WinHttpReadData to access the response entity body (if any). + /// + /// + /// HINTERNET handle returned by WinHttpOpenRequest and sent by WinHttpSendRequest. Wait until WinHttpSendRequest has completed + /// for this handle before calling WinHttpReceiveResponse. + /// + /// This parameter is reserved and must be NULL. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CANNOT_CONNECT + /// Returned if connection to the server failed. + /// + /// + /// ERROR_WINHTTP_CHUNKED_ENCODING_HEADER_SIZE_OVERFLOW + /// Returned when an overflow condition is encountered in the course of parsing chunked encoding. + /// + /// + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED + /// Returned when the server requests client authentication. + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_HEADER_COUNT_EXCEEDED + /// Returned when a larger number of headers were present in a response than WinHTTP could receive. + /// + /// + /// ERROR_WINHTTP_HEADER_SIZE_OVERFLOW + /// Returned by WinHttpReceiveResponse when the size of headers received exceeds the limit for the request handle. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_SERVER_RESPONSE + /// The server response could not be parsed. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_LOGIN_FAILURE + /// + /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new request + /// handle must be created before retrying the function that originally produced this error. + /// + /// + /// + /// ERROR_WINHTTP_NAME_NOT_RESOLVED + /// The server name could not be resolved. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_REDIRECT_FAILED + /// The redirection failed because either the scheme changed or all attempts made to redirect failed (default is five attempts). + /// + /// + /// ERROR_WINHTTP_RESEND_REQUEST + /// The WinHTTP function failed. The desired function can be retried on the same request handle. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_SECURE_FAILURE + /// + /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error was + /// encountered, check for a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more information, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// can operate either synchronously or asynchronously. If this function returns FALSE, this function failed and you can call + /// GetLastError to get extended error information. If this function returns TRUE, the application should expect either the + /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE completion callback, indicating success, or the + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion callback, indicating that the operation completed asynchronously, but failed. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have + /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in receiving the response: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE + /// + /// + /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_REDIRECT + /// + /// + /// + /// If the server closes the connection, the following notifications will also be reported, provided that they have been set in the + /// dwNotificationFlags parameter of WinHttpSetStatusCallback: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is + /// fictitious and must be replaced with the name of a server for which you have write access. + /// + /// + /// LPSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpreceiveresponse WINHTTPAPI BOOL WinHttpReceiveResponse( + // [in] HINTERNET hRequest, [in] LPVOID lpReserved ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpReceiveResponse")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpReceiveResponse(HINTERNET hRequest, [In, Optional] IntPtr lpReserved); + + /// Registers a callback function that WinHTTP calls when the effective proxy settings change. + /// + /// Type: _In_ ULONGLONG + /// The flag to pass to the callback (for example, WINHTTP_PROXY_NOTIFY_CHANGE). + /// + /// + /// Type: _In_ WINHTTP_PROXY_CHANGE_CALLBACK + /// A pointer to the callback function that should be called when the effective proxy settings change. + /// + /// + /// Type: _In_ PVOID + /// A pointer to a context object to pass to the callback. + /// + /// + /// Type: _Out_ WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE* + /// + /// A handle that identifies the registration of the callback function. To unregister, pass this value to + /// WinHttpUnregisterProxyChangeNotification. WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE is equivalent to PVOID. + /// + /// + /// + /// + /// A DWORD containing a status code indicating the result of the operation. The following codes can be returned (the list is not exhaustive). + /// + /// + /// + /// Code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The operation succeeded. + /// + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpregisterproxychangenotification WINHTTPAPI DWORD + // WinHttpRegisterProxyChangeNotification( ULONGLONG ullFlags, WINHTTP_PROXY_CHANGE_CALLBACK pfnCallback, PVOID pvContext, + // WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE *hRegistration ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpRegisterProxyChangeNotification")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpRegisterProxyChangeNotification(ulong ullFlags, + WINHTTP_PROXY_CHANGE_CALLBACK pfnCallback, IntPtr pvContext, + ref WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration); + + /// The WinHttpResetAutoProxy function resets the auto-proxy. + /// A valid HINTERNET WinHTTP session handle returned by a previous call to the WinHttpOpen function. + /// + /// A set of flags that affects the reset operation. + /// The following flags are supported as defined in the Winhttp.h header file. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_RESET_STATE 0x00000001 + /// Forces a flush and retry of non-persistent proxy information on the current network. + /// + /// + /// WINHTTP_RESET_SWPAD_CURRENT_NETWORK 0x00000002 + /// Flush the PAD information for the current network. + /// + /// + /// WINHTTP_RESET_SWPAD_ALL 0x00000004 + /// Flush the PAD information for all networks. + /// + /// + /// WINHTTP_RESET_SCRIPT_CACHE 0x00000008 + /// Flush the persistent HTTP cache of proxy scripts. + /// + /// + /// WINHTTP_RESET_ALL 0x0000FFFF + /// Forces a flush and retry of all proxy information on the current network. + /// + /// + /// WINHTTP_RESET_NOTIFY_NETWORK_CHANGED 0x00010000 + /// Flush the current proxy information and notify that the network changed. + /// + /// + /// WINHTTP_RESET_OUT_OF_PROC 0x00020000 + /// + /// Act on the autoproxy service instead of the current process. Applications that use the WinHttpGetProxyForUrl function to purge + /// in-process caching should close the hInternet handle and open a new handle for future calls. + /// + /// + /// + /// + /// + /// A code indicating the success or failure of the operation. + /// + /// + /// Return code + /// Description + /// + /// + /// ERROR_SUCCESS + /// The operation was successful. + /// + /// + /// ERROR_INVALID_HANDLE + /// The hSession parameter is not a valid handle. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE TYPE + /// The hSession parameter is not the product of a call to WinHttpOpen. + /// + /// + /// + /// + /// To reset everything, set the dwFlags parameter to include WINHTTP_RESET_ALL and WINHTTP_RESET_OUT_OF_PROC. + /// + /// Note If you make subsequent calls to the WinHttpResetAutoProxy function, there must be at least 30 seconds delay + /// between calls to reset the state of the auto-proxy. If there is less than 30 seconds, the WinHttpResetAutoProxy function call + /// may return ERROR_SUCCESS but the reset won't happen. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpresetautoproxy WINHTTPAPI DWORD WinHttpResetAutoProxy( + // [in] HINTERNET hSession, [in] DWORD dwFlags ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpResetAutoProxy")] + public static extern Win32Error WinHttpResetAutoProxy(HINTERNET hSession, WINHTTP_RESET dwFlags); + + /// The WinHttpSendRequest function sends the specified request to the HTTP server. + /// An HINTERNET handle returned by WinHttpOpenRequest. + /// + /// A pointer to a string that contains the additional headers to append to the request. This parameter can be + /// WINHTTP_NO_ADDITIONAL_HEADERS if there are no additional headers to append. + /// + /// + /// An unsigned long integer value that contains the length, in characters, of the additional headers. If this parameter is -1L + /// and pwszHeaders is not NULL, this function assumes that pwszHeaders is null-terminated, and the length is calculated. + /// + /// + /// + /// A pointer to a buffer that contains any optional data to send immediately after the request headers. This parameter is generally used + /// for POST and PUT operations. The optional data can be the resource or data posted to the server. This parameter can be + /// WINHTTP_NO_REQUEST_DATA if there is no optional data to send. + /// + /// If the dwOptionalLength parameter is 0, this parameter is ignored and set to NULL. + /// This buffer must remain available until the request handle is closed or the call to WinHttpReceiveResponse has completed. + /// + /// + /// + /// An unsigned long integer value that contains the length, in bytes, of the optional data. This parameter can be zero if there is no + /// optional data to send. + /// + /// + /// This parameter must contain a valid length when the lpOptional parameter is not NULL. Otherwise, lpOptional is + /// ignored and set to NULL. + /// + /// + /// + /// + /// An unsigned long integer value that contains the length, in bytes, of the total data sent. This parameter specifies the + /// Content-Length header of the request. If the value of this parameter is greater than the length specified by dwOptionalLength, + /// then WinHttpWriteData can be used to send additional data. + /// + /// + /// dwTotalLength must not change between calls to WinHttpSendRequest for the same request. If dwTotalLength needs + /// to be changed, the caller should create a new request. + /// + /// + /// + /// A pointer to a pointer-sized variable that contains an application-defined value that is passed, with the request handle, to any + /// callback functions. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Error codes are + /// listed in the following table. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CANNOT_CONNECT + /// Returned if connection to the server failed. + /// + /// + /// ERROR_WINHTTP_CLIENT_AUTH_CERT_NEEDED + /// + /// The secure HTTP server requires a client certificate. The application retrieves the list of certificate issuers by calling + /// WinHttpQueryOption with the WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST option. If the server requests the client certificate, but + /// does not require it, the application can alternately call WinHttpSetOption with the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. + /// In this case, the application specifies the WINHTTP_NO_CLIENT_CERT_CONTEXT macro in the lpBuffer parameter of + /// WinHttpSetOption. For more information, see the WINHTTP_OPTION_CLIENT_CERT_CONTEXT option. Windows Server 2003 with + /// SP1, Windows XP with SP2 and Windows 2000: This error is not supported. + /// + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_URL + /// The URL is invalid. + /// + /// + /// ERROR_WINHTTP_LOGIN_FAILURE + /// + /// The login attempt failed. When this error is encountered, the request handle should be closed with WinHttpCloseHandle. A new request + /// handle must be created before retrying the function that originally produced this error. + /// + /// + /// + /// ERROR_WINHTTP_NAME_NOT_RESOLVED + /// The server name cannot be resolved. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_RESPONSE_DRAIN_OVERFLOW + /// Returned when an incoming response exceeds an internal WinHTTP size limit. + /// + /// + /// ERROR_WINHTTP_SECURE_FAILURE + /// + /// One or more errors were found in the Secure Sockets Layer (SSL) certificate sent by the server. To determine what type of error was + /// encountered, verify through a WINHTTP_CALLBACK_STATUS_SECURE_FAILURE notification in a status callback function. For more + /// information, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// + /// ERROR_WINHTTP_SHUTDOWN + /// The WinHTTP function support is shut down or unloaded. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request timed out. + /// + /// + /// ERROR_WINHTTP_UNRECOGNIZED_SCHEME + /// The URL specified a scheme other than "http:" or "https:". + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// + /// Not enough memory was available to complete the requested operation. (Windows error code) Windows Server 2003, Windows XP and + /// Windows 2000: The TCP reservation range set with the WINHTTP_OPTION_PORT_RESERVATION option is not large enough to send + /// this request. + /// + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// The content length specified in the dwTotalLength parameter does not match the length specified in the Content-Length header. + /// The lpOptional parameter must be NULL and the dwOptionalLength parameter must be zero when the Transfer-Encoding + /// header is present. The Content-Length header cannot be present when the Transfer-Encoding header is present. + /// + /// + /// + /// ERROR_WINHTTP_RESEND_REQUEST + /// + /// The application must call WinHttpSendRequest again due to a redirect or authentication challenge. Windows Server 2003 with SP1, + /// Windows XP with SP2 and Windows 2000: This error is not supported. + /// + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode, that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen, this function + /// can operate either synchronously or asynchronously. In either case, if the request is sent successfully, the application is called + /// back with the completion status set to WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. The + /// WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates that the operation completed asynchronously, but failed. Upon + /// receiving the WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE status callback, the application can start to receive a response + /// from the server with WinHttpReceiveResponse. Before then, no other asynchronous functions can be called, otherwise, + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE is returned. + /// + /// + /// An application must not delete or alter the buffer pointed to by lpOptional until the request handle is closed or the call to + /// WinHttpReceiveResponse has completed, because an authentication challenge or redirect that required the optional data could be + /// encountered in the course of receiving the response. If the operation must be aborted with WinHttpCloseHandle, the application must + /// keep the buffer valid until it receives the callback WINHTTP_CALLBACK_STATUS_REQUEST_ERROR with an + /// ERROR_WINHTTP_OPERATION_CANCELLED error code. + /// + /// + /// If WinHTTP is used synchronously, that is, when WINHTP_FLAG_ASYNC was not set in WinHttpOpen, an application is not called + /// with a completion status even if a callback function is registered. While in this mode, the application can call + /// WinHttpReceiveResponse when WinHttpSendRequest returns. + /// + /// + /// The WinHttpSendRequest function sends the specified request to the HTTP server and allows the client to specify additional + /// headers to send along with the request. + /// + /// + /// This function also lets the client specify optional data to send to the HTTP server immediately following the request headers. This + /// feature is generally used for write operations such as PUT and POST. + /// + /// + /// An application can use the same HTTP request handle in multiple calls to WinHttpSendRequest to re-send the same request, but + /// the application must read all data returned from the previous call before calling this function again. + /// + /// + /// The name and value of request headers added with this function are validated. Headers must be well formed. For more information about + /// valid HTTP headers, see RFC 2616. If an invalid header is used, this function fails and GetLastError returns ERROR_INVALID_PARAMETER. + /// The invalid header is not added. + /// + /// Windows 2000: When sending requests from multiple threads, there may be a significant decrease in network and CPU performance. + /// Windows XP and Windows 2000: See Run-Time Requirements. + /// WinHttpSetStatusCallback + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have + /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate the progress in sending the request: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_DETECTING_PROXY (not implemented) + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE (only in asynchronous mode) + /// + /// + /// WINHTTP_CALLBACK_STATUS_REDIRECT + /// + /// + /// WINHTTP_CALLBACK_STATUS_SECURE_FAILURE + /// + /// + /// WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE + /// + /// + /// Note On Windows 7 and Windows Server 2008 R2, all of the following notifications are deprecated. + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESOLVING_NAME + /// + /// + /// WINHTTP_CALLBACK_STATUS_NAME_RESOLVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// + /// If the server closes the connection, the following notifications are also sent, provided that they have been set in the + /// dwNotificationFlags parameter of WinHttpSetStatusCallback: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION + /// + /// + /// WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED + /// + /// + /// Support for Greater Than 4-GB Upload + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp supports uploading files up to the size of a LARGE_INTEGER (2^64 + /// bytes) using the Content-Length header. Payload lengths specified in the call to WinHttpSendRequest are limited to the size of + /// a DWORD (2^32 bytes). To upload data to a URL larger than a DWORD, the application must provide the length in the + /// Content-Length header of the request. In this case, the WinHttp client application calls WinHttpSendRequest with the + /// dwTotalLength parameter set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH. + /// + /// + /// If the Content-Length header specifies a length less than a 2^32, the application must also specify the content length in the call to + /// WinHttpSendRequest. If the dwTotalLength parameter does not match the length specified in the Content-Length header, + /// the call fails and returns ERROR_INVALID_PARAMETER. + /// + /// + /// The Content-Length header can be added in the call to WinHttpAddRequestHeaders, or it can be specified in the lpszHeader + /// parameter of WinHttpSendRequest as shown in the following code example. + /// + /// + /// BOOL fRet = WinHttpSendRequest( hReq, L"Content-Length: 68719476735\r\n", -1L, WINHTTP_NO_REQUEST_DATA, 0, WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH, pMyContent); + /// + /// Transfer-Encoding Header + /// + /// Starting in Windows Vista and Windows Server 2008, WinHttp enables applications to perform chunked transfer encoding on data sent to + /// the server. When the Transfer-Encoding header is present on the WinHttp request, the dwTotalLength parameter in the call to + /// WinHttpSendRequest is set to WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH and the application sends the entity body in one or + /// more calls to WinHttpWriteData. The lpOptional parameter of WinHttpSendRequest must be NULL and the + /// dwOptionLength parameter must be zero, otherwise an ERROR_WINHTTP_INVALID_PARAMETER error is returned. To terminate the + /// chunked data transfer, the application generates a zero length chunk and sends it in the last call to WinHttpWriteData. + /// + /// Examples + /// + /// The following code example shows how to obtain an HINTERNET handle, open an HTTP session, create a request header, and send that + /// header to the server. + /// + /// + /// BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); // Place additional code here. // Report errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsendrequest BOOL WinHttpSendRequest( [in] HINTERNET + // hRequest, [in, optional] LPCWSTR lpszHeaders, [in] DWORD dwHeadersLength, [in, optional] LPVOID lpOptional, [in] DWORD + // dwOptionalLength, [in] DWORD dwTotalLength, [in] DWORD_PTR dwContext ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSendRequest")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSendRequest(HINTERNET hRequest, [Optional, MarshalAs(UnmanagedType.LPWStr)] string lpszHeaders, + [Optional] int dwHeadersLength, [In, Optional] IntPtr lpOptional, [Optional] uint dwOptionalLength, [Optional] uint dwTotalLength, + [In, Optional] IntPtr dwContext); + + /// The WinHttpSetCredentials function passes the required authorization credentials to the server. + /// Valid HINTERNET handle returned by WinHttpOpenRequest. + /// + /// + /// An unsigned integer that specifies a flag that contains the authentication target. Can be one of the values in the following table. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_TARGET_SERVER + /// Credentials are passed to a server. + /// + /// + /// WINHTTP_AUTH_TARGET_PROXY + /// Credentials are passed to a proxy. + /// + /// + /// + /// + /// + /// An unsigned integer that specifies a flag that contains the authentication scheme. Must be one of the supported authentication + /// schemes returned from WinHttpQueryAuthSchemes. The following table identifies the possible values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_AUTH_SCHEME_BASIC + /// Use basic authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NTLM + /// Use NTLM authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_PASSPORT + /// Use passport authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_DIGEST + /// Use digest authentication. + /// + /// + /// WINHTTP_AUTH_SCHEME_NEGOTIATE + /// Selects between NTLM and Kerberos authentication. + /// + /// + /// + /// Pointer to a string that contains a valid user name. + /// Pointer to a string that contains a valid password. The password can be blank. + /// This parameter is reserved and must be NULL. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. The following table + /// identifies the error codes returned. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation (Windows error code). + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// The credentials set by WinHttpSetCredentials are only used for a single request; WinHTTP does not cache these credentials for + /// use in subsequent requests. As a result, applications must be written so that they can respond to multiple challenges. If an + /// authenticated connection is re-used, subsequent requests cannot be challenged, but your code should be able to respond to a challenge + /// at any point. + /// + /// For sample code that illustrates the use of WinHttpSetCredentials, see Authentication in WinHTTP. + /// + /// When using Passport authentication and responding to a 407 status code, a WinHTTP application must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials, because WinHttpSetOption is less secure. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetcredentials BOOL WinHttpSetCredentials( [in] HINTERNET + // hRequest, [in] DWORD AuthTargets, [in] DWORD AuthScheme, [in] LPCWSTR pwszUserName, [in] LPCWSTR pwszPassword, [in] LPVOID pAuthParams ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetCredentials")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetCredentials(HINTERNET hRequest, WINHTTP_AUTH_TARGET AuthTargets, WINHTTP_AUTH_SCHEME AuthScheme, + [MarshalAs(UnmanagedType.LPWStr)] string pwszUserName, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwszPassword, IntPtr pAuthParams = default); + + /// The WinHttpSetDefaultProxyConfiguration function sets the default WinHTTP proxy configuration in the registry. + /// A pointer to a variable of type WINHTTP_PROXY_INFO that specifies the default proxy configuration. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// The default proxy configuration set by WinHttpSetDefaultProxyConfiguration can be overridden for an existing WinHTTP session + /// by calling WinHttpSetOption and specifying the WINHTTP_OPTION_PROXY flag. The default proxy configuration can be overridden for a new + /// session by specifying the configuration with the WinHttpOpen function. + /// + /// + /// The dwAccessType member of the WINHTTP_PROXY_INFO structure pointed to by pProxyInfo should be set to + /// WINHTTP_ACCESS_TYPE_NAMED_PROXY if a proxy is specified. Otherwise, it should be set to WINHTTP_ACCESS_TYPE_DEFAULT_PROXY. + /// + /// Any new sessions created after calling this function use the new default proxy configuration. + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetdefaultproxyconfiguration WINHTTPAPI BOOL + // WinHttpSetDefaultProxyConfiguration( [in] WINHTTP_PROXY_INFO *pProxyInfo ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetDefaultProxyConfiguration")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetDefaultProxyConfiguration(in WINHTTP_PROXY_INFO pProxyInfo); + + /// The WinHttpSetOption function sets an Internet option. + /// + /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on what + /// option is being set. For more information about how to determine which handle is appropriate to use in setting a particular option, + /// see the Option Flags. + /// + /// + /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. + /// + /// A pointer to a buffer that contains the option setting. + /// + /// Unsigned long integer value that contains the length of the lpBuffer buffer. The length of the buffer is specified in + /// characters for the following options; for all other options, the length is specified in bytes. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower + /// than 15000. + /// + /// + /// + /// ERROR_WINHTTP_OPTION_NOT_SETTABLE + /// The requested option cannot be set, only queried. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower + /// than 15000. + /// + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use + /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. + /// + /// + /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. + /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, [In] IntPtr lpBuffer, uint dwBufferLength); + + /// The WinHttpSetOption function sets an Internet option. + /// + /// The HINTERNET handle on which to set data. Be aware that this can be either a Session handle or a Request handle, depending on what + /// option is being set. For more information about how to determine which handle is appropriate to use in setting a particular option, + /// see the Option Flags. + /// + /// + /// An unsigned long integer value that contains the Internet option to set. This can be one of the Option Flags values. + /// + /// The option setting. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_INVALID_OPTION + /// A request to WinHttpQueryOption or WinHttpSetOption specified an invalid option value. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower + /// than 15000. + /// + /// + /// + /// ERROR_WINHTTP_OPTION_NOT_SETTABLE + /// The requested option cannot be set, only queried. + /// + /// + /// ERROR_INVALID_PARAMETER + /// + /// A parameter is not valid. This value will be returned if WINHTTP_OPTION_WEB_SOCKET_KEEPALIVE_INTERVAL is set to a value lower + /// than 15000. + /// + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Credentials passed to WinHttpSetOption could be unexpectedly sent in plaintext. It is strongly recommended that you use + /// WinHttpQueryAuthSchemes and WinHttpSetCredentials instead of WinHttpSetOption for setting credentials. + /// + /// + /// When using Passport authentication, however, a WinHTTP application responding to a 407 status code must use + /// WinHttpSetOption to provide proxy credentials rather than WinHttpSetCredentials. This is only true when using Passport + /// authentication; in all other circumstances, use WinHttpSetCredentials. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// GetLastError returns the error ERROR_INVALID_PARAMETER if an option flag is specified that cannot be set. + /// For more information and code examples that show the use of WinHttpSetOption, see Authentication in WinHTTP. + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetoption BOOL WinHttpSetOption( [in] HINTERNET + // hInternet, [in] DWORD dwOption, [in] LPVOID lpBuffer, [in] DWORD dwBufferLength ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetOption")] + public static bool WinHttpSetOption(HINTERNET hInternet, WINHTTP_OPTION dwOption, in T value) where T : struct + { + using SafeHGlobalHandle mem = SafeHGlobalHandle.CreateFromStructure(value); + return WinHttpSetOption(hInternet, dwOption, mem, mem.Size); + } + + /// + /// The WinHttpSetStatusCallback function sets up a callback function that WinHTTP can call as progress is made during an operation. + /// + /// HINTERNET handle for which the callback is to be set. + /// + /// Pointer to the callback function to call when progress is made. Set this to NULL to remove the existing callback function. For + /// more information about the callback function, see WINHTTP_STATUS_CALLBACK. + /// + /// + /// Unsigned long integer value that specifies flags to indicate which events activate the callback function. + /// The possible values are as follows. + /// + /// + /// Value + /// Meaning + /// + /// + /// WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS + /// + /// Activates upon any completion notification. This flag specifies that all notifications required for read or write operations are + /// used. See WINHTTP_STATUS_CALLBACK for a list of completions. + /// + /// + /// + /// WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS + /// Activates upon any status change notification including completions. See WINHTTP_STATUS_CALLBACK for a list of notifications. + /// + /// + /// WINHTTP_CALLBACK_FLAG_RESOLVE_NAME + /// Activates upon beginning and completing name resolution. + /// + /// + /// WINHTTP_CALLBACK_FLAG_CONNECT_TO_SERVER + /// Activates upon beginning and completing connection to the server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_DETECTING_PROXY + /// Activates when detecting the proxy server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_DATA_AVAILABLE + /// Activates when completing a query for data. + /// + /// + /// WINHTTP_CALLBACK_FLAG_HEADERS_AVAILABLE + /// Activates when the response headers are available for retrieval. + /// + /// + /// WINHTTP_CALLBACK_FLAG_READ_COMPLETE + /// Activates upon completion of a data-read operation. + /// + /// + /// WINHTTP_CALLBACK_FLAG_REQUEST_ERROR + /// Activates when an asynchronous error occurs. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SEND_REQUEST + /// Activates upon beginning and completing the sending of a request header with WinHttpSendRequest. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SENDREQUEST_COMPLETE + /// Activates when a request header has been sent with WinHttpSendRequest. + /// + /// + /// WINHTTP_CALLBACK_FLAG_WRITE_COMPLETE + /// Activates upon completion of a data-post operation. + /// + /// + /// WINHTTP_CALLBACK_FLAG_RECEIVE_RESPONSE + /// Activates upon beginning and completing the receipt of a resource from the HTTP server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_CLOSE_CONNECTION + /// Activates when beginning and completing the closing of an HTTP connection. + /// + /// + /// WINHTTP_CALLBACK_FLAG_HANDLES + /// Activates when an HINTERNET handle is created or closed. + /// + /// + /// WINHTTP_CALLBACK_FLAG_REDIRECT + /// Activates when the request is redirected. + /// + /// + /// WINHTTP_CALLBACK_FLAG_INTERMEDIATE_RESPONSE + /// Activates when receiving an intermediate (100 level) status code message from the server. + /// + /// + /// WINHTTP_CALLBACK_FLAG_SECURE_FAILURE + /// Activates upon a secure connection failure. + /// + /// + /// + /// This parameter is reserved and must be NULL. + /// + /// + /// If successful, returns a pointer to the previously defined status callback function or NULL if there was no previously defined + /// status callback function. Returns WINHTTP_INVALID_STATUS_CALLBACK if the callback function could not be installed. For + /// extended error information, call GetLastError. Among the error codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// If you set the callback on the session handle before creating the request handle, the request handle inherits the callback function + /// pointer from its parent session. + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// Both synchronous and asynchronous functions use the callback function to indicate the progress of the request, such as resolving a + /// name, connecting to a server, and so on. The callback function is required for an asynchronous operation. + /// + /// + /// A callback function can be set on any handle and is inherited by derived handles. A callback function can be changed using + /// WinHttpSetStatusCallback, provided there are no pending requests that need to use the previous callback value. However, + /// changing the callback function on a handle does not change the callbacks on derived handles, such as that returned by WinHttpConnect. + /// You must change the callback function at each level. + /// + /// Many WinHTTP functions perform several operations on the network. Each operation can take time to complete and each can fail. + /// + /// After initiating the WinHttpSetStatusCallback function, the callback function can be accessed from within WinHTTP for + /// monitoring time-intensive network operations. + /// + /// + /// At the end of asynchronous processing, the application may set the callback function to NULL. This prevents the client + /// application from receiving additional notifications. + /// + /// The following code snippet shows the recommended method for setting the callback function to NULL. + /// WinHttpSetStatusCallback( hOpen, NULL, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL ); + /// + /// Note, however, that WinHTTP does not synchronize WinHttpSetStatusCallback with worker threads. If a callback originating in + /// another thread is in progress when an application calls WinHttpSetStatusCallback, the application still receives a callback + /// notification even after WinHttpSetStatusCallback successfully sets the callback function to NULL and returns. + /// + /// For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// + /// The following example shows how to install a callback function for asynchronous WinHTTP functions. The example assumes that a + /// WINHTTP_STATUS_CALLBACK function named "AsyncCallback( )" has been previously implemented: + /// + /// + /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Install the status callback function. WINHTTP_STATUS_CALLBACK isCallback = WinHttpSetStatusCallback( hSession, (WINHTTP_STATUS_CALLBACK)AsyncCallback, WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS, NULL); // Place additional code here. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsetstatuscallback WINHTTPAPI WINHTTP_STATUS_CALLBACK + // WinHttpSetStatusCallback( [in] HINTERNET hInternet, [in] WINHTTP_STATUS_CALLBACK lpfnInternetCallback, [in] DWORD dwNotificationFlags, + // [in] DWORD_PTR dwReserved ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetStatusCallback")] + public static extern IntPtr WinHttpSetStatusCallback(HINTERNET hInternet, WINHTTP_STATUS_CALLBACK lpfnInternetCallback, + WINHTTP_CALLBACK_FLAG dwNotificationFlags, IntPtr dwReserved = default); + + /// The WinHttpSetTimeouts function sets time-outs involved with HTTP transactions. + /// The HINTERNET handle returned by WinHttpOpen or WinHttpOpenRequest. + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for name resolution. If resolution takes longer + /// than this time-out value, the action is canceled. The initial value is zero, meaning no time-out (infinite). + /// + /// + /// Windows Vista and Windows XP: If DNS timeout is specified using NAME_RESOLUTION_TIMEOUT, there is an overhead of one thread + /// per request. + /// + /// + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for server connection requests. If a connection + /// request takes longer than this time-out value, the request is canceled. The initial value is 60,000 (60 seconds). + /// + /// TCP/IP can time out while setting up the socket during the three leg SYN/ACK exchange, regardless of the value of this parameter. + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to use for sending requests. If sending a request takes + /// longer than this time-out value, the send is canceled. The initial value is 30,000 (30 seconds). + /// + /// + /// A value of type integer that specifies the time-out value, in milliseconds, to receive a response to a request. If a response takes + /// longer than this time-out value, the request is canceled. The initial value is 30,000 (30 seconds). + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// ERROR_INVALID_PARAMETER + /// One or more of the timeout parameters has a negative value other than -1. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// + /// A value of 0 or -1 sets a time-out to wait infinitely. A value greater than 0 sets the time-out value in milliseconds. For example, + /// 30,000 would set the time-out to 30 seconds. All negative values other than -1 cause the function to fail with ERROR_INVALID_PARAMETER. + /// + /// + /// Important If a small timeout is set using WinHttpSetOption and WINHTTP_OPTION_RECEIVE_TIMEOUT, it can override the value set + /// with the dwReceiveTimeout parameter, causing a response to terminate earlier than expected. To avoid this, do not set a + /// timeout with the WINHTTP_OPTION_RECEIVE_TIMEOUT option that is smaller than the value set using dwReceiveTimeout. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// Examples + /// This example shows how to set new time-out values using WinHttpSetTimeouts. + /// + /// // Use WinHttpOpen to obtain an HINTERNET handle. HINTERNET hSession = WinHttpOpen(L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (hSession) { // Use WinHttpSetTimeouts to set a new time-out values. if (!WinHttpSetTimeouts( hSession, 10000, 10000, 10000, 10000)) printf( "Error %u in WinHttpSetTimeouts.\n", GetLastError()); // PLACE ADDITIONAL CODE HERE. // When finished, release the HINTERNET handle. WinHttpCloseHandle(hSession); } else { printf("Error %u in WinHttpOpen.\n", GetLastError()); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpsettimeouts BOOL WinHttpSetTimeouts( [in] HINTERNET + // hInternet, [in] int nResolveTimeout, [in] int nConnectTimeout, [in] int nSendTimeout, [in] int nReceiveTimeout ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpSetTimeouts")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpSetTimeouts(HINTERNET hInternet, int nResolveTimeout = 0, int nConnectTimeout = 60000, int nSendTimeout = 30000, int nReceiveTimeout = 30000); + + /// The WinHttpTimeFromSystemTime function formats a date and time according to the HTTP version 1.0 specification. + /// A pointer to a SYSTEMTIME structure that contains the date and time to format. + /// + /// A pointer to a string buffer that receives the formatted date and time. The buffer should equal to the size, in bytes, of WINHTTP_TIME_FORMAT_BUFSIZE. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. To get extended error information, call GetLastError. Error codes + /// include the following. + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP Start Page. + /// Examples + /// The following code example code shows how to convert a SYSTEMTIME structure to a string that contains the time in HTTP format. + /// + /// SYSTEMTIME sTime; LPWSTR pwszTimeStr; // Get the current time. GetSystemTime(&sTime); // Allocate memory for the string. // Note: WINHTTP_TIME_FORMAT_BUFSIZE is a byte count. // Therefore, you must divide the array by // sizeof WCHAR to get the proper string length. pwszTimeStr = new WCHAR[WINHTTP_TIME_FORMAT_BUFSIZE/sizeof(WCHAR)]; // Convert the current time to HTTP format. if(!WinHttpTimeFromSystemTime( &sTime, pwszTimeStr)) { printf( "Error %u in WinHttpTimeFromSystemTime.\n", GetLastError()); } else { // Print the time. printf("Current time is (%S)\n", pwszTimeStr); } // Free the memory. delete [] pwszTimeStr; + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimefromsystemtime BOOL WinHttpTimeFromSystemTime( [in] + // const SYSTEMTIME *pst, [out] LPWSTR pwszTime ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeFromSystemTime")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpTimeFromSystemTime(in SYSTEMTIME pst, [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszTime); + + /// The WinHttpTimeToSystemTime function takes an HTTP time/date string and converts it to a SYSTEMTIME structure. + /// + /// Pointer to a null-terminated date/time string to convert. This value must use the format defined in section 3.3 of the RFC2616. + /// + /// Pointer to the SYSTEMTIME structure that receives the converted time. + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned is: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// operates synchronously. The return value indicates success or failure. To get extended error information, call GetLastError. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHttp start page. + /// Examples + /// This example shows how to convert an HTTP formatted date to a SYSTEMTIME structure. + /// + /// SYSTEMTIME sTime; LPCWSTR pwszTimeStr = L"Tue, 21 Nov 2000 01:06:53 GMT"; // Convert the HTTP string to a SYSTEMTIME structure. if (!WinHttpTimeToSystemTime( pwszTimeStr, &sTime)) { printf( "Error %u in WinHttpTimeToSystemTime.\n", GetLastError()); } else { // Print the date. printf( "The U.S. formatted date is (%u/%u/%u)\n", sTime.wMonth, sTime.wDay, sTime.wYear); } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttptimetosystemtime BOOL WinHttpTimeToSystemTime( [in] + // LPCWSTR pwszTime, [out] SYSTEMTIME *pst ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpTimeToSystemTime")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpTimeToSystemTime([MarshalAs(UnmanagedType.LPWStr)] string pwszTime, out SYSTEMTIME pst); + + /// Unregisters a callback function that was registered by calling WinHttpRegisterProxyChangeNotification. + /// + /// Type: _In_ WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE* + /// The handle that was returned from WinHttpRegisterProxyChangeNotification. + /// + /// A DWORD containing a status code indicating the result of the operation. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpunregisterproxychangenotification WINHTTPAPI DWORD + // WinHttpUnregisterProxyChangeNotification( WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration ); + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpUnregisterProxyChangeNotification")] + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + public static extern Win32Error WinHttpUnregisterProxyChangeNotification(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE hRegistration); + + /// The WinHttpWebSocketClose function closes a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: USHORT + /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A detailed reason for the close. + /// + /// + /// Type: DWORD + /// The length of pvReason, in bytes. + /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. + /// + /// + /// Type: DWORD + /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// ERROR_INVALID_SERVER_RESPONSE + /// Invalid data was received from the server. + /// + /// + /// + /// + /// + /// WinHttpWebSocketClose completely closes a WebSocket connection. To close the send channel while still leaving the receive + /// channel open, use WinHttpWebSocketShutdown. + /// + /// + /// It is possible to receive a close frame during regular receive operations. In this case, WinHttpWebSocketClose will also send + /// a close frame. + /// + /// The close timer can be set by the property WINHTTP_OPTION_WEB_SOCKET_CLOSE_TIMEOUT. The default is 10 seconds. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketclose WINHTTPAPI DWORD WinHttpWebSocketClose( + // [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD dwReasonLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketClose")] + public static extern Win32Error WinHttpWebSocketClose(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, + [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); + + /// The WinHttpWebSocketCompleteUpgrade function completes a WebSocket handshake started by WinHttpSendRequest. + /// + /// Type: HINTERNET + /// HTTP request handle used to send a WebSocket handshake. + /// + /// + /// Type: DWORD_PTR + /// Context to be associated with the new handle. + /// + /// + /// Type: HINTERNET + /// A new WebSocket handle. If NULL, call GetLastError to determine the cause of failure. + /// + /// + /// + /// WinHttpWebSocketCompleteUpgrade can be called on an open HTTP request to get a WebSocket handle for performing other WebSocket operations. + /// + /// + /// The request handle must be marked as a WebSocket upgrade by calling WinHttpSetOption with WINHTTP_OPTION_UPGRADE_TO_WEB_SOCKET + /// before sending the request. + /// + /// + /// The caller should check the HTTP status code returned by the server and call this function only if the status code was 101. Calling + /// it with any other status code will result in a failure. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketcompleteupgrade WINHTTPAPI HINTERNET + // WinHttpWebSocketCompleteUpgrade( [in] HINTERNET hRequest, [in, optional] DWORD_PTR pContext ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketCompleteUpgrade")] + public static extern SafeHINTERNET WinHttpWebSocketCompleteUpgrade(HINTERNET hRequest, [In, Optional] IntPtr pContext); + + /// The WinHttpWebSocketQueryCloseStatus function retrieves the close status sent by a server. + /// + /// Type: HINTERNET + /// Handle to a WebSocket + /// + /// + /// Type: USHORT* + /// A pointer to a close status code that will be filled upon return. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A pointer to a buffer that will receive a close reason on return. + /// + /// + /// Type: DWORD + /// The length of the pvReason buffer, in bytes. + /// + /// + /// Type: DWORD* + /// + /// The number of bytes consumed. If pvReason is NULL and dwReasonLength is 0, pdwReasonLengthConsumed will + /// contain the size of the buffer that needs to be allocated by the calling application. + /// + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INSUFFICIENT_BUFFER + /// There is not enough space in pvReason to write the whole close reason. + /// + /// + /// ERROR_INVALID_OPERATION + /// No close frame has been received yet. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// + /// + /// + /// Call WinHttpWebSocketQueryCloseStatus only after WinHttpWebSocketClose succeeds or if WinHttpWebSocketReceive returns WINHTTP_WEB_SOCKET_CLOSE_BUFFER_TYPE. + /// + /// + /// pdwReasonLengthConsumed will never be greater than 123, so allocating buffer with at least 123 will guarantee that + /// ERROR_INSUFFICIENT_BUFFER will never be returned. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketqueryclosestatus WINHTTPAPI DWORD + // WinHttpWebSocketQueryCloseStatus( [in] HINTERNET hWebSocket, [out] USHORT *pusStatus, [out] PVOID pvReason, [in] DWORD dwReasonLength, + // [out] DWORD *pdwReasonLengthConsumed ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketQueryCloseStatus")] + public static extern Win32Error WinHttpWebSocketQueryCloseStatus(HINTERNET hWebSocket, out WINHTTP_WEB_SOCKET_CLOSE_STATUS pusStatus, [Out] IntPtr pvReason, + uint dwReasonLength, out uint pdwReasonLengthConsumed); + + /// The WinHttpWebSocketReceive function receives data from a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: PVOID + /// Pointer to a buffer to receive the data. + /// + /// + /// Type: DWORD + /// Length of pvBuffer, in bytes. + /// + /// + /// Type: DWORD* + /// + /// Pointer to a DWORD that receives the number of bytes read from the connection at the end of the operation. This is set only if + /// WinHttpWebSocketReceive returns NO_ERROR and the handle was opened in synchronous mode. + /// + /// + /// + /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE* + /// + /// The type of a returned buffer. This is only set if WinHttpWebSocketReceive returns NO_ERROR and the handle was opened + /// in synchronous mode. + /// + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending, or the receive channel has already been closed. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// ERROR_INVALID_SERVER_RESPONSE + /// Invalid data was received from the server. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was cancelled because WinHttpWebSocketClose was called to close the connection. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketreceive WINHTTPAPI DWORD + // WinHttpWebSocketReceive( [in] HINTERNET hWebSocket, [out] PVOID pvBuffer, [in] DWORD dwBufferLength, [out] DWORD *pdwBytesRead, [out] + // WINHTTP_WEB_SOCKET_BUFFER_TYPE *peBufferType ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketReceive")] + public static extern Win32Error WinHttpWebSocketReceive(HINTERNET hWebSocket, [Out] IntPtr pvBuffer, uint dwBufferLength, + out uint pdwBytesRead, out WINHTTP_WEB_SOCKET_BUFFER_TYPE peBufferType); + + /// The WinHttpWebSocketSend function sends data over a WebSocket connection. + /// + /// Type: HINTERNET + /// Handle to a websocket. + /// + /// + /// Type: WINHTTP_WEB_SOCKET_BUFFER_TYPE + /// Type of buffer. + /// + /// + /// Type: PVOID + /// Pointer to a buffer containing the data to send. Can be NULL only if dwBufferLength is 0. + /// + /// + /// Type: DWORD + /// Length of pvBuffer. + /// + /// + /// Type: DWORD + /// NO_ERROR on success. Otherwise an error code. + /// + /// + /// + /// Description + /// + /// + /// ERROR_INVALID_OPERATION + /// A close or send is pending, or the send channel has already been closed. + /// + /// + /// ERROR_INVALID_PARAMETER + /// A parameter is invalid. + /// + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketsend WINHTTPAPI DWORD WinHttpWebSocketSend( [in] + // HINTERNET hWebSocket, [in] WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, [in] PVOID pvBuffer, [in] DWORD dwBufferLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketSend")] + public static extern Win32Error WinHttpWebSocketSend(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_BUFFER_TYPE eBufferType, + [In, Optional] IntPtr pvBuffer, [In, Optional] uint dwBufferLength); + + /// + /// The WinHttpWebSocketShutdown function sends a close frame to a WebSocket server to close the send channel, but leaves the + /// receive channel open. + /// + /// + /// Type: HINTERNET + /// Handle to a WebSocket. + /// + /// + /// Type: USHORT + /// A close status code. See WINHTTP_WEB_SOCKET_CLOSE_STATUS for possible values. + /// + /// + /// Type: PVOID + /// A detailed reason for the close. + /// + /// + /// Type: DWORD + /// The length of pvReason, in bytes. + /// If pvReason is NULL, this must be 0. This value must be within the range of 0 to 123. + /// + /// + /// Type: DWORD + /// With the following exception, all error codes indicate that the underlying TCP connection has been aborted. + /// + /// + /// + /// Description + /// + /// + /// ERROR_IO_PENDING + /// The operation will complete asynchronously. + /// + /// + /// + /// + /// + /// WinHttpWebSocketShutdown sends a close frame and prevents additional data from being sent over the WebSocket connection. It + /// does not close the receive channel. Use WinHttpWebSocketClose when you want to completely close the connection and prevent any + /// subsequent receive operations. + /// + /// The application is responsible for receiving the close frame from the server (through regular receive operations). + /// + /// After WinHttpWebSocketShutdown is called, the application can call WinHttpWebSocketClose if it does not want to receive a + /// close frame on its own and delegate it to the stack. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwebsocketshutdown WINHTTPAPI DWORD + // WinHttpWebSocketShutdown( [in] HINTERNET hWebSocket, [in] USHORT usStatus, [in, optional] PVOID pvReason, [in] DWORD dwReasonLength ); + [DllImport(Lib_Winhttp, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWebSocketShutdown")] + public static extern Win32Error WinHttpWebSocketShutdown(HINTERNET hWebSocket, WINHTTP_WEB_SOCKET_CLOSE_STATUS usStatus, + [In, Optional] IntPtr pvReason, [In, Optional] uint dwReasonLength); + + /// The WinHttpWriteData function writes request data to an HTTP server. + /// + /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. + /// + /// + /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after + /// WinHttpWriteData completes. + /// + /// Unsigned long integer value that contains the number of bytes to be written to the file. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData + /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must be + /// set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to get extended + /// error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion to determine + /// whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates + /// that the operation completed asynchronously, but failed. + /// + /// + /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and + /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is called, + /// then the data transfer is aborted. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have + /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// + /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + /// + /// + /// + /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate + /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be + /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. NTLM + /// and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails if the + /// connection is broken prematurely. + /// + /// + /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for + /// each authentication legs. This can be very inefficient for large data uploads. + /// + /// + /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir + /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is + /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. + /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the same + /// socket as long as the socket is not pooled with concurrent requests competing for it. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// Examples + /// + /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is + /// fictitious and must be replaced with the name of a server for which you have write access. + /// + /// + /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET hRequest, + // [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] IntPtr lpBuffer, uint dwNumberOfBytesToWrite, out uint lpdwNumberOfBytesWritten); + + /// The WinHttpWriteData function writes request data to an HTTP server. + /// + /// Valid HINTERNET handle returned by WinHttpOpenRequest. Wait until WinHttpSendRequest has completed before calling this function. + /// + /// + /// Pointer to a buffer that contains the data to be sent to the server. Be sure that this buffer remains valid until after + /// WinHttpWriteData completes. + /// + /// Unsigned long integer value that contains the number of bytes to be written to the file. + /// + /// Pointer to an unsigned long integer variable that receives the number of bytes written to the buffer. The WinHttpWriteData + /// function sets this value to zero before doing any work or error checking. When using WinHTTP asynchronously, this parameter must be + /// set to NULL and retrieve the information in the callback function. Not doing so can cause a memory fault. + /// + /// + /// + /// Returns TRUE if successful, or FALSE otherwise. For extended error information, call GetLastError. Among the error + /// codes returned are: + /// + /// + /// + /// Error Code + /// Description + /// + /// + /// ERROR_WINHTTP_CONNECTION_ERROR + /// + /// The connection with the server has been reset or terminated, or an incompatible SSL protocol was encountered. For example, WinHTTP + /// version 5.1 does not support SSL2 unless the client specifically enables it. + /// + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_STATE + /// The requested operation cannot be carried out because the handle supplied is not in the correct state. + /// + /// + /// ERROR_WINHTTP_INCORRECT_HANDLE_TYPE + /// The type of handle supplied is incorrect for this operation. + /// + /// + /// ERROR_WINHTTP_INTERNAL_ERROR + /// An internal error has occurred. + /// + /// + /// ERROR_WINHTTP_OPERATION_CANCELLED + /// The operation was canceled, usually because the handle on which the request was operating was closed before the operation completed. + /// + /// + /// ERROR_WINHTTP_TIMEOUT + /// The request has timed out. + /// + /// + /// ERROR_NOT_ENOUGH_MEMORY + /// Not enough memory was available to complete the requested operation. (Windows error code) + /// + /// + /// + /// + /// + /// Even when WinHTTP is used in asynchronous mode (that is, when WINHTTP_FLAG_ASYNC has been set in WinHttpOpen), this function + /// can operate either synchronously or asynchronously. If this function returns FALSE, you can call GetLastError to get extended + /// error information. If this function returns TRUE, use the WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE completion to determine + /// whether this function was successful and the value of the parameters. The WINHTTP_CALLBACK_STATUS_REQUEST_ERROR completion indicates + /// that the operation completed asynchronously, but failed. + /// + /// + /// Warning When using WinHTTP asynchronously, always set the lpdwNumberOfBytesWritten parameter to NULL and + /// retrieve the bytes written in the callback function; otherwise, a memory fault can occur. + /// + /// + /// When the application is sending data, it can call WinHttpReceiveResponse to end the data transfer. If WinHttpCloseHandle is called, + /// then the data transfer is aborted. + /// + /// + /// If a status callback function has been installed with WinHttpSetStatusCallback, then those of the following notifications that have + /// been set in the dwNotificationFlags parameter of WinHttpSetStatusCallback indicate progress in sending data to the server: + /// + /// + /// + /// WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE + /// + /// + /// WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED + /// + /// + /// WINHTTP_CALLBACK_STATUS_DATA_WRITTEN + /// + /// + /// WINHTTP_CALLBACK_STATUS_SENDING_REQUEST + /// + /// + /// WINHTTP_CALLBACK_STATUS_REQUEST_SENT + /// + /// + /// WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE + /// + /// + /// + /// Two issues can arise when attempting to POST (or PUT) data to proxies or servers that challenge using NTLM or Negotiate + /// authentication. First, these proxies or servers may send 401/407 challenges and close the connection before all the data can be + /// POST'ed, in which case not only does WinHttpWriteData fail, but also WinHTTP cannot handle the authentication challenges. NTLM + /// and Negotiate require that all authentication handshakes be exchanged on the same socket connection, so authentication fails if the + /// connection is broken prematurely. + /// + /// + /// Secondly, NTLM and Negotiate may require multiple handshakes to complete authentication, which requires data to be re-POST'ed for + /// each authentication legs. This can be very inefficient for large data uploads. + /// + /// + /// To work around these two issues, one solution is to send an idempotent warm-up request such as HEAD to the authenticating v-dir + /// first, handle the authentication challenges associated with this request, and only then POST data. As long as the same socket is + /// re-used to handle the POST'ing, no further authentication challenges should be encountered and all data can be uploaded at once. + /// Since an authenticated socket can only be reused for subsequent requests within the same session, the POST should go out in the same + /// socket as long as the socket is not pooled with concurrent requests competing for it. + /// + /// Note For Windows XP and Windows 2000, see the Run-Time Requirements section of the WinHTTP start page. + /// Examples + /// + /// This example shows code that writes data to an HTTP server. The server name supplied in the example, www.wingtiptoys.com, is + /// fictitious and must be replaced with the name of a server for which you have write access. + /// + /// + /// PCSTR pszData = "WinHttpWriteData Example"; DWORD dwBytesWritten = 0; BOOL bResults = FALSE; HINTERNET hSession = NULL, hConnect = NULL, hRequest = NULL; // Use WinHttpOpen to obtain a session handle. hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); // Specify an HTTP server. if (hSession) hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com", INTERNET_DEFAULT_HTTP_PORT, 0); // Create an HTTP Request handle. if (hConnect) hRequest = WinHttpOpenRequest( hConnect, L"PUT", L"/writetst.txt", NULL, WINHTTP_NO_REFERER, WINHTTP_DEFAULT_ACCEPT_TYPES, 0); // Send a Request. if (hRequest) bResults = WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, (DWORD)strlen(pszData), 0); // Write data to the server. if (bResults) bResults = WinHttpWriteData( hRequest, pszData, (DWORD)strlen(pszData), &dwBytesWritten); // End the request. if (bResults) bResults = WinHttpReceiveResponse( hRequest, NULL); // Report any errors. if (!bResults) printf("Error %d has occurred.\n",GetLastError()); // Close any open handles. if (hRequest) WinHttpCloseHandle(hRequest); if (hConnect) WinHttpCloseHandle(hConnect); if (hSession) WinHttpCloseHandle(hSession); + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winhttp/nf-winhttp-winhttpwritedata BOOL WinHttpWriteData( [in] HINTERNET hRequest, + // [in] LPCVOID lpBuffer, [in] DWORD dwNumberOfBytesToWrite, [out] LPDWORD lpdwNumberOfBytesWritten ); + [DllImport(Lib_Winhttp, SetLastError = true, ExactSpelling = true)] + [PInvokeData("winhttp.h", MSDNShortId = "NF:winhttp.WinHttpWriteData")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool WinHttpWriteData(HINTERNET hRequest, [In] byte[] lpBuffer, int dwNumberOfBytesToWrite, out int lpdwNumberOfBytesWritten); } \ No newline at end of file diff --git a/PInvoke/WinHTTP/WinHTTP.Structs.cs b/PInvoke/WinHTTP/WinHTTP.Structs.cs index b7c0ed8a..58a7ea07 100644 --- a/PInvoke/WinHTTP/WinHTTP.Structs.cs +++ b/PInvoke/WinHTTP/WinHTTP.Structs.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; @@ -7,1325 +8,1541 @@ using static Vanara.PInvoke.Ws2_32; using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME; using INTERNET_PORT = System.UInt16; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +/// Items from the WinHTTP.dll. +public static partial class WinHTTP { - /// Items from the WinHTTP.dll. - public static partial class WinHTTP + /// Provides a handle to an internet connection. + [StructLayout(LayoutKind.Sequential)] + public struct HINTERNET : IHandle { - /// Provides a handle to an internet connection. - [StructLayout(LayoutKind.Sequential)] - public struct HINTERNET : IHandle - { - private readonly IntPtr handle; + 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; + /// 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; + /// 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; + /// 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 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); + /// 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; - /// 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 bool Equals(object obj) => obj is IHandle h && handle == h.DangerousGetHandle() || obj is IntPtr p && handle == p; - /// - public override int GetHashCode() => handle.GetHashCode(); + /// + public override int GetHashCode() => handle.GetHashCode(); - /// - public IntPtr DangerousGetHandle() => handle; - } + /// + 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; + /// 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; - } + /// 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; /// - /// 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. + /// + /// 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. + /// + /// /// - /// 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; + public ASYNC_RESULT dwResult => (ASYNC_RESULT)_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; /// - /// 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. + /// + /// 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. + /// + /// /// - // 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; - } + public WINHTTP_AUTO_DETECT_TYPE dwAutoDetectFlags; /// - /// The WINHTTP_CERTIFICATE_INFO structure contains certificate information returned from the server. This structure is used - /// by the WinHttpQueryOption function. + /// + /// 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. /// - /// - /// - /// 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; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszAutoConfigUrl; - /// A FILETIME structure that contains the date the certificate becomes valid. - public FILETIME ftStart; + /// Reserved for future use; must be NULL. + public IntPtr lpvReserved; - /// - /// 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; - } + /// Reserved for future use; must be zero. + public uint dwReserved; /// - /// The WINHTTP_CONNECTION_INFO structure contains the source and destination IP address of the request that generated the response. + /// + /// 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. + /// /// - /// - /// - /// 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; + [MarshalAs(UnmanagedType.Bool)] + public bool fAutoLogonIfChallenged; + } - /// A SOCKADDR_STORAGE structure that contains the local IP address and port of the original request. - public SOCKADDR_STORAGE LocalAddress; + /// + /// 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 SOCKADDR_STORAGE structure that contains the remote IP address and port of the original request. - public SOCKADDR_STORAGE RemoteAddress; - } + /// A FILETIME structure that contains the date the certificate becomes valid. + public FILETIME ftStart; /// - /// 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. + /// A pointer to a buffer that contains the name of the organization, site, and server for which the certificate was issued. /// - /// - /// - /// 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; + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszSubjectInfo; - /// 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". - /// - public StrPtrUni 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". - /// - public StrPtrUni lpszProxy; - - /// Pointer to a null-terminated Unicode string that contains the optional proxy by-pass server list. - public StrPtrUni lpszProxyBypass; - - /// Frees the memory tied to the strings in this structure. - public void FreeMemory() - { - Marshal.FreeHGlobal((IntPtr)lpszAutoConfigUrl); - Marshal.FreeHGlobal((IntPtr)lpszProxy); - Marshal.FreeHGlobal((IntPtr)lpszProxyBypass); - lpszAutoConfigUrl = lpszProxy = lpszProxyBypass = default; - } - } - - /// 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); - } + /// 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; /// - /// See the option flag WINHTTP_OPTION_MATCH_CONNECTION_GUID. That option takes as input a - /// WINHTTP_MATCH_CONNECTION_GUID value. + /// A pointer to a buffer that contains the name of the protocol used to provide the secure connection. This member is not current used. /// - // 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_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_IN - { - /// - /// 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. - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszProxy; - - /// Pointer to a string value that contains the proxy bypass list. - [MarshalAs(UnmanagedType.LPWStr)] - public string lpszProxyBypass; - } - - /// 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; - } + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProtocolName; /// - /// The URL_COMPONENTS structure contains the constituent parts of a URL. This structure is used with the WinHttpCrackUrl and - /// WinHttpCreateUrl functions. + /// A pointer to a buffer that contains the name of the algorithm used to sign the certificate. This member is not current used. /// - /// - /// - /// 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); - } - } + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszSignatureAlgName; /// - /// The URL_COMPONENTS structure contains the constituent parts of a URL. This structure is used with the WinHttpCrackUrl and - /// WinHttpCreateUrl functions. + /// 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. /// - /// - /// - /// 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 + [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". + /// + public StrPtrUni 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". + /// + public StrPtrUni lpszProxy; + + /// Pointer to a null-terminated Unicode string that contains the optional proxy by-pass server list. + public StrPtrUni lpszProxyBypass; + + /// Frees the memory tied to the strings in this structure. + public void FreeMemory() { - /// - /// 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); + Marshal.FreeHGlobal((IntPtr)lpszAutoConfigUrl); + Marshal.FreeHGlobal((IntPtr)lpszProxy); + Marshal.FreeHGlobal((IntPtr)lpszProxyBypass); + lpszAutoConfigUrl = lpszProxy = lpszProxyBypass = default; } } + + /// 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; + } + + /// Provides a handle that identifies the registration of the callback function. + [StructLayout(LayoutKind.Sequential)] + public struct WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE : IHandle + { + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// + /// Returns an invalid handle by instantiating a object with . + /// + public static WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE NULL => new(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + public bool IsNull => handle == IntPtr.Zero; + + /// Implements the operator !. + /// The handle. + /// The result of the operator. + public static bool operator !(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h1) => h1.IsNull; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE(IntPtr h) => new(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h1, WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h1, WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is WINHTTP_PROXY_CHANGE_REGISTRATION_HANDLE h && handle == h.handle; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// 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_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_IN + { + /// + /// 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. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProxy; + + /// Pointer to a string value that contains the proxy bypass list. + [MarshalAs(UnmanagedType.LPWStr)] + public string lpszProxyBypass; + } + + /// + public struct WINHTTP_PROXY_NETWORKING_KEY + { + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] + public byte[] pbBuffer; + } + + /// 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; + } + + /// Represents extended proxy settings. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_settings_ex typedef struct + // _WINHTTP_PROXY_SETTINGS_EX { ULONGLONG ullGenerationId; ULONGLONG ullFlags; PCWSTR pcwszAutoconfigUrl; PCWSTR pcwszProxy; PCWSTR + // pcwszSecureProxy; DWORD cProxyBypasses; PCWSTR *rgpcwszProxyBypasses; DWORD dwInterfaceIndex; PCWSTR pcwszConnectionName; } + // WINHTTP_PROXY_SETTINGS_EX, *PWINHTTP_PROXY_SETTINGS_EX; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_SETTINGS_EX")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_PROXY_SETTINGS_EX + { + /// + /// Type: ULONGLONG + /// The current network generation (incremented each time the configuration is changed). + /// + public ulong ullGenerationId; + + /// + /// Type: ULONGLONG + /// Flags for the proxy settings (for example, WINHTTP_PROXY_TYPE_DIRECT). + /// + public WINHTTP_PROXY_TYPE ullFlags; + + /// + /// Type: PCWSTR + /// The PAC URL for the network (for example, L"http://proxy.contoso.com/wpad.dat"). + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszAutoconfigUrl; + + /// + /// Type: PCWSTR + /// The proxy address and port for HTTP traffic (for example, L"http://192.168.1.1:8888"). + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszProxy; + + /// + /// Type: PCWSTR + /// The proxy address and port for HTTPS traffic (for example, L"http://192.168.1.1:8888"). + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszSecureProxy; + + /// + /// Type: DWORD + /// The number of entries in the proxy bypass list (rgpcwszProxyBypasses). + /// + public int cProxyBypasses; + + private readonly IntPtr _rgpcwszProxyBypasses; + + /// + /// Type: PCWSTR* + /// An array of strings containing each site in the proxy bypass list. (for example, L"contoso.com"). + /// + public string[] rgpcwszProxyBypasses => _rgpcwszProxyBypasses.ToStringEnum(cProxyBypasses, CharSet.Unicode).ToArray(); + + /// + /// Type: DWORD + /// The interface index for which settings were retrieved. + /// + public uint dwInterfaceIndex; + + /// + /// Type: PCWSTR + /// The WCM connection name for which settings were retrieved. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszConnectionName; + } + + /// Represents extended proxy settings. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_settings_ex typedef struct + // _WINHTTP_PROXY_SETTINGS_EX { ULONGLONG ullGenerationId; ULONGLONG ullFlags; PCWSTR pcwszAutoconfigUrl; PCWSTR pcwszProxy; PCWSTR + // pcwszSecureProxy; DWORD cProxyBypasses; PCWSTR *rgpcwszProxyBypasses; DWORD dwInterfaceIndex; PCWSTR pcwszConnectionName; } + // WINHTTP_PROXY_SETTINGS_EX, *PWINHTTP_PROXY_SETTINGS_EX; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_SETTINGS_EX")] + public struct WINHTTP_PROXY_SETTINGS_EX_MGD + { + /// + /// Type: ULONGLONG + /// The current network generation (incremented each time the configuration is changed). + /// + public ulong ullGenerationId; + + /// + /// Type: ULONGLONG + /// Flags for the proxy settings (for example, WINHTTP_PROXY_TYPE_DIRECT). + /// + public WINHTTP_PROXY_TYPE ullFlags; + + /// + /// Type: PCWSTR + /// The PAC URL for the network (for example, L"http://proxy.contoso.com/wpad.dat"). + /// + public string pcwszAutoconfigUrl; + + /// + /// Type: PCWSTR + /// The proxy address and port for HTTP traffic (for example, L"http://192.168.1.1:8888"). + /// + public string pcwszProxy; + + /// + /// Type: PCWSTR + /// The proxy address and port for HTTPS traffic (for example, L"http://192.168.1.1:8888"). + /// + public string pcwszSecureProxy; + + /// + /// Type: PCWSTR* + /// An array of strings containing each site in the proxy bypass list. (for example, L"contoso.com"). + /// + public string[] rgpcwszProxyBypasses; + + /// + /// Type: DWORD + /// The interface index for which settings were retrieved. + /// + public uint dwInterfaceIndex; + + /// + /// Type: PCWSTR + /// The WCM connection name for which settings were retrieved. + /// + public string pcwszConnectionName; + + /// Performs an implicit conversion from to . + /// The WINHTTP_PROXY_SETTINGS_EX instance. + /// The result of the conversion. + public static implicit operator WINHTTP_PROXY_SETTINGS_EX_MGD(in WINHTTP_PROXY_SETTINGS_EX s) => + new() { ullGenerationId = s.ullGenerationId, ullFlags = s.ullFlags, pcwszAutoconfigUrl = s.pcwszAutoconfigUrl, pcwszProxy = s.pcwszProxy, + pcwszSecureProxy = s.pcwszSecureProxy, rgpcwszProxyBypasses = s.rgpcwszProxyBypasses, dwInterfaceIndex = s.dwInterfaceIndex, pcwszConnectionName = s.pcwszConnectionName }; + } + + /// Represents extended proxy settings. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ns-winhttp-winhttp_proxy_settings_param typedef struct + // _WINHTTP_PROXY_SETTINGS_PARAM { ULONGLONG ullFlags; PCWSTR pcwszConnectionName; PCWSTR pcwszProbeHost; } WINHTTP_PROXY_SETTINGS_PARAM, *PWINHTTP_PROXY_SETTINGS_PARAM; + [PInvokeData("winhttp.h", MSDNShortId = "NS:winhttp._WINHTTP_PROXY_SETTINGS_PARAM")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WINHTTP_PROXY_SETTINGS_PARAM + { + /// + /// Type: ULONGLONG + /// Flags. + /// + public ulong ullFlags; + + /// + /// Type: PCWSTR + /// The WCM connection name for which settings were retrieved. + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszConnectionName; + + /// + /// Type: PCWSTR + /// TBD + /// + [MarshalAs(UnmanagedType.LPWStr)] + public string pcwszProbeHost; + } + + /// 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 index 14decf22..b5a7ffa8 100644 --- a/PInvoke/WinHTTP/WinHTTP.cs +++ b/PInvoke/WinHTTP/WinHTTP.cs @@ -1800,6 +1800,40 @@ namespace Vanara.PInvoke WINHTTP_PROTOCOL_FLAG_HTTP3 = 0x2, } + /// Defines constants that specify proxy settings types for extended proxy settings APIs. + // https://learn.microsoft.com/en-us/windows/win32/api/winhttp/ne-winhttp-winhttp_proxy_settings_type typedef enum + // _WINHTTP_PROXY_SETTINGS_TYPE { WinHttpProxySettingsTypeUnknown, WinHttpProxySettingsTypeWsl, WinHttpProxySettingsTypeWsa } + // WINHTTP_PROXY_SETTINGS_TYPE, *PWINHTTP_PROXY_SETTINGS_TYPE; + [PInvokeData("winhttp.h", MSDNShortId = "NE:winhttp._WINHTTP_PROXY_SETTINGS_TYPE")] + public enum WINHTTP_PROXY_SETTINGS_TYPE + { + /// Specifies an unknown type. + WinHttpProxySettingsTypeUnknown, + + /// Specifies settings for Windows Subsystem for Linux (WSL). + WinHttpProxySettingsTypeWsl, + + /// Specifies settings for Windows Subsystem for Android (WSA). + WinHttpProxySettingsTypeWsa, + } + + /// + [Flags] + public enum WINHTTP_PROXY_TYPE : ulong + { + /// Direct to net + WINHTTP_PROXY_TYPE_DIRECT = 0x00000001, + + /// Via named proxy + WINHTTP_PROXY_TYPE_PROXY = 0x00000002, + + /// Autoproxy URL + WINHTTP_PROXY_TYPE_AUTO_PROXY_URL = 0x00000004, + + /// Use autoproxy detection + WINHTTP_PROXY_TYPE_AUTO_DETECT = 0x00000008, + } + /// /// These attributes and modifiers are used by WinHttpQueryHeaders. ///