diff --git a/PInvoke/IpHlpApi/IpHlpApi.cs b/PInvoke/IpHlpApi/IpHlpApi.cs index 1a3e6c80..2b3c9c1b 100644 --- a/PInvoke/IpHlpApi/IpHlpApi.cs +++ b/PInvoke/IpHlpApi/IpHlpApi.cs @@ -57,6 +57,27 @@ namespace Vanara.PInvoke /// public const int TCPIP_OWNING_MODULE_SIZE = 16; + /// + /// + /// A callback function that you implement in your app in order to be notified of changes to the timestamp capabilities of a network + /// adapter. Pass a pointer to your implementation when you call RegisterInterfaceTimestampConfigChange. + /// + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// Type: _In_ PVOID + /// + /// The caller-allocated context that you passed to RegisterInterfaceTimestampConfigChange, or NULL if you didn't pass + /// a context. + /// + /// + /// None + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nc-iphlpapi-interface_timestamp_config_change_callback + // INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK InterfaceTimestampConfigChangeCallback; void InterfaceTimestampConfigChangeCallback( PVOID CallerContext ) {...} + [PInvokeData("iphlpapi.h", MSDNShortId = "NC:iphlpapi.INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK", MinClient = PInvokeClient.Windows11)] + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + public delegate void INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK(IntPtr CallerContext); + /// The type of addresses to retrieve in . [PInvokeData("iptypes.h")] [Flags] @@ -3632,6 +3653,36 @@ namespace Vanara.PInvoke [PInvokeData("iphlpapi.h", MSDNShortId = "6a46c1df-b274-415e-b842-fc1adf6fa206")] public static MIB_IFTABLE GetIfTable(bool sorted = false) => GetTable((IntPtr p, ref uint len) => GetIfTable(p, ref len, sorted), len => new MIB_IFTABLE(len)); + /// + /// Retrieves the currently enabled timestamp capabilities of a network adapter. + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// Type: _In_ CONST NET_LUID* + /// + /// The network locally unique identifier (LUID) of the network adapter for which currently enabled timestamp capabilities are to be retrieved. + /// + /// + /// + /// Type: _Out_ PINTERFACE_TIMESTAMP_CAPABILITIES + /// + /// If the function succeeds, then TimestampCapabilites returns a structure that describes the currently enabled timestamp capabilities. + /// + /// + /// + /// Type: DWORD + /// + /// If the function succeeds, then it returns NO_ERROR. If the network card corresponding to InterfaceLuid isn't + /// timestamp-aware, then the function returns ERROR_NOT_SUPPORTED. If the network card driver advertises an unsupported + /// timestamp configuration, then the function returns ERROR_BAD_DRIVER. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getinterfaceactivetimestampcapabilities + // IPHLPAPI_DLL_LINKAGE DWORD GetInterfaceActiveTimestampCapabilities( const NET_LUID *InterfaceLuid, PINTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites ); + [DllImport(Lib.IpHlpApi, SetLastError = false, ExactSpelling = true)] + [PInvokeData("iphlpapi.h", MSDNShortId = "NF:iphlpapi.GetInterfaceActiveTimestampCapabilities", MinClient = PInvokeClient.Windows11)] + public static extern Win32Error GetInterfaceActiveTimestampCapabilities(in NET_LUID InterfaceLuid, out INTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites); + /// /// /// The GetInterfaceInfo function obtains the list of the network interface adapters with IPv4 enabled on the local system. @@ -3741,6 +3792,33 @@ namespace Vanara.PInvoke [PInvokeData("iphlpapi.h", MSDNShortId = "efc0d175-2c6d-4608-b385-1623a9e0375c")] public static IP_INTERFACE_INFO GetInterfaceInfo() => GetTable((IntPtr p, ref uint len) => GetInterfaceInfo(p, ref len), len => new IP_INTERFACE_INFO(len)); + /// + /// Retrieves the supported timestamp capabilities of a network adapter. + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// Type: _In_ CONST NET_LUID* + /// + /// The network locally unique identifier (LUID) of the network adapter for which supported timestamp capabilities are to be retrieved. + /// + /// + /// + /// Type: _Out_ PINTERFACE_TIMESTAMP_CAPABILITIES + /// If the function succeeds, then TimestampCapabilites returns a structure that describes the supported timestamp capabilities. + /// + /// + /// Type: DWORD + /// + /// If the function succeeds, then it returns NO_ERROR. If the network card corresponding to InterfaceLuid isn't + /// timestamp-aware, then the function returns ERROR_NOT_SUPPORTED. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getinterfacesupportedtimestampcapabilities + // IPHLPAPI_DLL_LINKAGE DWORD GetInterfaceSupportedTimestampCapabilities( const NET_LUID *InterfaceLuid, PINTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites ); + [DllImport(Lib.IpHlpApi, SetLastError = false, ExactSpelling = true)] + [PInvokeData("iphlpapi.h", MSDNShortId = "NF:iphlpapi.GetInterfaceSupportedTimestampCapabilities", MinClient = PInvokeClient.Windows11)] + public static extern Win32Error GetInterfaceSupportedTimestampCapabilities(in NET_LUID InterfaceLuid, out INTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites); + /// /// The GetIpAddrTable function retrieves the interface–to–IPv4 address mapping table. /// @@ -7804,6 +7882,37 @@ namespace Vanara.PInvoke /// public static unsafe string PhysicalAddressToString(byte* physAddr) => $"{physAddr[0]:X}-{physAddr[1]:X}-{physAddr[2]:X}-{physAddr[3]:X}-{physAddr[4]:X}-{physAddr[5]:X}"; + /// + /// + /// Registers a user-implemented callback function, which the system calls to notify you of a timestamp capability change. You can + /// cancel the registration by calling UnregisterInterfaceTimestampConfigChange. + /// + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// Type: _In_ PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK + /// Your callback function, to be invoked when a timestamp capability change happens. + /// + /// + /// Type: _In_opt_ PVOID + /// An optional caller-allocated context. + /// + /// + /// Type: _Out_ HIFTIMESTAMPCHANGE + /// A handle, returned by the function, that identifies the registration. + /// + /// + /// Type: DWORD + /// A DWORD return code indicating success or failure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-registerinterfacetimestampconfigchange + // IPHLPAPI_DLL_LINKAGE DWORD RegisterInterfaceTimestampConfigChange( PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK Callback, PVOID + // CallerContext, HIFTIMESTAMPCHANGE *NotificationHandle ); + [DllImport(Lib.IpHlpApi, SetLastError = false, ExactSpelling = true)] + [PInvokeData("iphlpapi.h", MSDNShortId = "NF:iphlpapi.RegisterInterfaceTimestampConfigChange", MinClient = PInvokeClient.Windows11)] + public static extern Win32Error RegisterInterfaceTimestampConfigChange([In] INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK Callback, + IntPtr CallerContext, out HIFTIMESTAMPCHANGE NotificationHandle); + /// /// The RestoreMediaSense function restores the media sensing capability of the TCP/IP stack on a local computer on which the /// DisableMediaSense function was previously called. @@ -9554,6 +9663,36 @@ namespace Vanara.PInvoke [PInvokeData("iphlpapi.h", MSDNShortId = "95f0387f-24e8-4382-b78e-e59bcec0f2ed")] public static extern unsafe Win32Error UnenableRouter(System.Threading.NativeOverlapped* pOverlapped, out uint lpdwEnableCount); + /// + /// + /// Cancels notifications about timestamp capability changes by unregistering the callback function you registered in a call to RegisterInterfaceTimestampConfigChange. + /// + /// + /// To avoid deadlock, you shouldn't call UnregisterInterfaceTimestampConfigChange in the context of the thread that's + /// executing a callback that was specified to RegisterInterfaceTimestampConfigChange. This is because + /// UnregisterInterfaceTimestampConfigChange waits for outstanding notification callbacks to complete before it returns. + /// Consequently, UnregisterInterfaceTimestampConfigChange mustn't be called in a way that prevents an outstanding + /// notification callback from completing. No further callbacks will take place after + /// UnregisterInterfaceTimestampConfigChange returns. + /// + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// Type: _In_ HIFTIMESTAMPCHANGE + /// + /// The handle that was returned by RegisterInterfaceTimestampConfigChange. This identifies the registration to be canceled. + /// + /// + /// + /// Type: DWORD + /// A DWORD return code indicating success or failure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-unregisterinterfacetimestampconfigchange + // IPHLPAPI_DLL_LINKAGE VOID UnregisterInterfaceTimestampConfigChange( HIFTIMESTAMPCHANGE NotificationHandle ); + [DllImport(Lib.IpHlpApi, SetLastError = false, ExactSpelling = true)] + [PInvokeData("iphlpapi.h", MSDNShortId = "NF:iphlpapi.UnregisterInterfaceTimestampConfigChange", MinClient = PInvokeClient.Windows11)] + public static extern void UnregisterInterfaceTimestampConfigChange([In] HIFTIMESTAMPCHANGE NotificationHandle); + private static TRet GetTable(FunctionHelper.PtrFunc func, Func make, uint memErr = Win32Error.ERROR_INSUFFICIENT_BUFFER) where TRet : SafeHandle { uint len = 0; @@ -9566,6 +9705,289 @@ namespace Vanara.PInvoke return mem; } + /// Provides a handle to a notification registration for a timestamp capability change. + [StructLayout(LayoutKind.Sequential)] + public struct HIFTIMESTAMPCHANGE : IHandle + { + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public HIFTIMESTAMPCHANGE(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Returns an invalid handle by instantiating a object with . + public static HIFTIMESTAMPCHANGE NULL => new(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(HIFTIMESTAMPCHANGE h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator HIFTIMESTAMPCHANGE(IntPtr h) => new(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(HIFTIMESTAMPCHANGE h1, HIFTIMESTAMPCHANGE h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(HIFTIMESTAMPCHANGE h1, HIFTIMESTAMPCHANGE h2) => h1.Equals(h2); + + /// + public override bool Equals(object obj) => obj is HIFTIMESTAMPCHANGE h && handle == h.handle; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// + /// Describes the timestamping capabilities of a network interface card's (NIC's) hardware. + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// + /// All of the INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES structure's members represent hardware timestamp capabilities. The + /// hardware timestamps are generated using the NIC's hardware clock. + /// + /// Having both hardware and software timestamps enabled together isn't supported. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/ns-iphlpapi-interface_hardware_timestamp_capabilities typedef struct + // _INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES { BOOLEAN PtpV2OverUdpIPv4EventMessageReceive; BOOLEAN + // PtpV2OverUdpIPv4AllMessageReceive; BOOLEAN PtpV2OverUdpIPv4EventMessageTransmit; BOOLEAN PtpV2OverUdpIPv4AllMessageTransmit; + // BOOLEAN PtpV2OverUdpIPv6EventMessageReceive; BOOLEAN PtpV2OverUdpIPv6AllMessageReceive; BOOLEAN + // PtpV2OverUdpIPv6EventMessageTransmit; BOOLEAN PtpV2OverUdpIPv6AllMessageTransmit; BOOLEAN AllReceive; BOOLEAN AllTransmit; + // BOOLEAN TaggedTransmit; } INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES, *PINTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES; + [PInvokeData("iphlpapi.h", MSDNShortId = "NS:iphlpapi._INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES", MinClient = PInvokeClient.Windows11)] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES + { + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that, during packet reception, the NIC can recognize in hardware a PTP version 2 event message + /// contained in an IPv4 UDP packet, and can generate a timestamp in hardware corresponding to when such a packet was received. + /// A value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv4EventMessageReceive; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that, during packet reception, the NIC can recognize in hardware any PTP version 2 message (not just + /// PTP event messages) contained in an IPv4 UDP packet, and can generate a timestamp in hardware corresponding to when such a + /// packet was received. A value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv4AllMessageReceive; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that, during packet transmission, the NIC can recognize in hardware a PTP version 2 event message + /// contained in an IPv4 UDP packet, and can generate a timestamp in hardware corresponding to when such a packet was + /// transmitted. A value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv4EventMessageTransmit; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that, during packet transmission, the NIC can recognize in hardware any PTP version 2 message (not + /// just PTP event messages) contained in an IPv4 UDP packet, and can generate a timestamp in hardware corresponding to when + /// such a packet was transmitted. A value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv4AllMessageTransmit; + + /// + /// Type: BOOLEAN + /// The same as PtpV2OverUdpIPv4EventMsgReceiveHw, except that it applies to IPv6. + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv6EventMessageReceive; + + /// + /// Type: BOOLEAN + /// The same as PtpV2OverUdpIPv4AllMsgReceiveHw, except that it applies to IPv6. + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv6AllMessageReceive; + + /// + /// Type: BOOLEAN + /// The same as PtpV2OverUdpIPv4EventMsgTransmitHw, except that it applies to IPv6. + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv6EventMessageTransmit; + + /// + /// Type: BOOLEAN + /// The same as PtpV2OverUdpIPv4AllMsgTransmitHw, except that it applies to IPv6. + /// + [MarshalAs(UnmanagedType.U1)] + public bool PtpV2OverUdpIPv6AllMessageTransmit; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that the NIC can generate a hardware timestamp for all received packets (that is, not just PTP). A + /// value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool AllReceive; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that the NIC can generate a hardware timestamp for all transmitted packets (that is, not just PTP). A + /// value of FALSE indicates that the hardware is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool AllTransmit; + + /// + /// Type: BOOLEAN + /// + /// TRUE indicates that the NIC can generate a hardware timestamp for any specific transmitted packet when indicated to + /// do so by the application. A value of FALSE indicates that the hardware is not capable of this. See + /// TIMESTAMPING_CONFIG (and TIMESTAMPING_FLAG_TX) to determine how to request a timestamp when sending UDP + /// packets through Windows Sockets. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool TaggedTransmit; + } + + /// + /// Describes the software timestamping capabilities of a NIC's miniport driver. + /// For more info, and code examples, see Packet timestamping. + /// + /// + /// + /// All of the INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES structure's members represent software timestamp capabilities. The + /// software timestamp generated by the NIC driver corresponds to a counter value obtained by calling QueryPerformanceCounter. + /// + /// Having both hardware and software timestamps enabled together isn't supported. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/ns-iphlpapi-interface_software_timestamp_capabilities typedef struct + // _INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES { BOOLEAN AllReceive; BOOLEAN AllTransmit; BOOLEAN TaggedTransmit; } + // INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES, *PINTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES; + [PInvokeData("iphlpapi.h", MSDNShortId = "NS:iphlpapi._INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES", MinClient = PInvokeClient.Windows11)] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES + { + /// + /// Type: BOOLEAN + /// + /// Also contains members that describe the software timestamping capabilities of a NIC's miniport driver. Not a hardware + /// capability. TRUE indicates that the NIC's miniport driver can generate a software timestamp for all received packets. + /// A value of FALSE indicates that the software is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool AllReceive; + + /// + /// Type: BOOLEAN + /// + /// Not a hardware capability. Analogous to AllReceiveSw, except it applies to the transmit direction. TRUE indicates + /// that the NIC's miniport driver can generate a software timestamp for all transmitted packets. A value of FALSE + /// indicates that the software is not capable of this. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool AllTransmit; + + /// + /// Type: BOOLEAN + /// + /// Not a hardware capability. TRUE indicates that the NIC's miniport driver can generate a software timestamp for any + /// specific transmitted packet when indicated to do so by the application. A value of FALSE indicates that the software + /// is not capable of this. See TIMESTAMPING_CONFIG (and TIMESTAMPING_FLAG_TX) to determine how to request a + /// timestamp when sending UDP packets through Windows Sockets. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool TaggedTransmit; + } + + /// + /// Describes the exact timestamp capabilities that a network adapter supports. + /// + /// To retrieve the supported timestamp capabilities of a network adapter, call the + /// GetInterfaceSupportedTimestampCapabilities function. That function returns the supported timestamping capabilities in the + /// form of an INTERFACE_TIMESTAMP_CAPABILITIES object. + /// + /// For more info, and code examples, see Packet timestamping. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/ns-iphlpapi-interface_timestamp_capabilities + // typedef struct _INTERFACE_TIMESTAMP_CAPABILITIES { ULONG64 HardwareClockFrequencyHz; BOOLEAN SupportsCrossTimestamp; INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES HardwareCapabilities; INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES SoftwareCapabilities; } INTERFACE_TIMESTAMP_CAPABILITIES, *PINTERFACE_TIMESTAMP_CAPABILITIES; + [PInvokeData("iphlpapi.h", MSDNShortId = "NS:iphlpapi._INTERFACE_TIMESTAMP_CAPABILITIES", MinClient = PInvokeClient.Windows11)] + [StructLayout(LayoutKind.Sequential)] + public struct INTERFACE_TIMESTAMP_CAPABILITIES + { + /// + /// Type: ULONG64 + /// + /// Contains the frequency of the network adapter's hardware clock, rounded off to the nearest integer in Hertz units. Note this + /// is the nominal frequency, and the actual frequency might not be the same as this. This data could be used to display the + /// nominal clock frequency to end users for informational purposes. It's possible for HardwareClockFrequencyHz to contain the + /// value 0. + /// + /// + public ulong HardwareClockFrequencyHz; + + /// + /// Type: BOOLEAN + /// + /// A value of TRUE indicates that the network adapter driver is capable of generating a hardware cross timestamp. A + /// cross timestamp refers to a set of network interface card (NIC) hardware timestamp and system timestamp(s) obtained very + /// close to one another. A value of FALSE indicates that this capability doesn't exist. + /// + /// + [MarshalAs(UnmanagedType.U1)] + public bool SupportsCrossTimestamp; + + /// + /// Type: INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES + /// + /// Describes the timestamping capabilities of the network interface card's (NIC's) hardware. Having both hardware and software + /// timestamps enabled together isn't supported. + /// + /// + public INTERFACE_HARDWARE_TIMESTAMP_CAPABILITIES HardwareCapabilities; + + /// + /// Type: INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES + /// + /// Describes the software timestamping capabilities of a network interface card's (NIC's) miniport driver. Having both hardware + /// and software timestamps enabled together isn't supported. + /// + /// + public INTERFACE_SOFTWARE_TIMESTAMP_CAPABILITIES SoftwareCapabilities; + } + /// Describes a network address. // typedef struct NET_ADDRESS_INFO_ { NET_ADDRESS_FORMAT Format; union { struct { WCHAR Address[DNS_MAX_NAME_BUFFER_LENGTH]; WCHAR // Port[6]; } NamedAddress; SOCKADDR_IN Ipv4Address; SOCKADDR_IN6 Ipv6Address; SOCKADDR IpAddress; };} NET_ADDRESS_INFO,