WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析11
上一篇:WindowsAPI|每天了解几个winAPI接口之网络配置相关文档Iphlpapi.h详细分析10
如果有错误欢迎指正批评,在此只作为科普和参考。
C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\iphlpapi.h
文章目录
- GetInterfaceActiveTimestampCapabilities:某个网络接口当前生效的时间戳能力
- 作用
- 调用条件
- 典型代码
- 常见错误
- 一句话总结
- GetInterfaceSupportedTimestampCapabilities:检索指定网络适配器支持的时间戳功能
- 函数原型
- 参数
- 返回值
- 使用场景
- 示例代码
- 注意事项
- 与 `GetInterfaceActiveTimestampCapabilities` 的区别
- CaptureInterfaceHardwareCrossTimestamp:从指定的网络接口(如以太网卡)中捕获 **硬件时间戳** 与 **系统时间戳** 的对应关系
- 1️⃣ 所在位置与用途
- 2️⃣ 函数作用
- 3️⃣ 参数解释
- 🔹 `InterfaceLuid`
- 🔹 `CrossTimestamp`
- 4️⃣ 返回值
- 5️⃣ 使用示例
- 6️⃣ 实际应用场景
- ✅ 小结
- INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK:在网络接口的**硬件时间戳配置发生变化**时通知上层
- 🧩 拆解逐行说明
- 1️⃣ `typedef ... CALLBACK ...`
- 2️⃣ 函数原型展开后是这样:
- 3️⃣ 第二个 typedef
- 🔧 用途与上下文
- 举个例子:
- 📄 参数说明
- 🔁 常见使用场景
- ✅ 总结
- RegisterInterfaceTimestampConfigChange:用于 **注册一个回调函数**,当系统中任何网络接口的 **时间戳配置(timestamp configuration)发生变化** 时,系统就会自动调用你注册的回调。
- 🧭 一、函数总体说明
- 📘 功能概述
- 🧩 二、函数原型解析
- 定义展开
- 🔹 参数解释
- 🔹 返回值
- ⚙️ 三、配套的注销函数
- 📄 四、使用流程
- 🔧 五、实际用途
- 📘 六、关联结构与概念
- ✅ 七、总结
- UnregisterInterfaceTimestampConfigChange:取消之前通过 `RegisterInterfaceTimestampConfigChange()` 注册的**时间戳配置变化回调通知**
- 📘 核心作用
- ⚙️ 参数说明
- 🧩 使用示例
GetInterfaceActiveTimestampCapabilities:某个网络接口当前生效的时间戳能力
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
GetInterfaceActiveTimestampCapabilities(_In_ CONST NET_LUID *InterfaceLuid,_Out_ PINTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites);
这个函数是 Windows 10 20H1(NTDDI_WIN10_FE)以后才公开的 “运行时能力” 接口:
GetInterfaceActiveTimestampCapabilities
它用来把 某个网络接口当前生效的时间戳能力 一次性取回来,区别于 GetAdaptersAddresses
返回的 “静态”能力(硬件具备什么)。
下面给你一份 5 秒钟能看懂的速查卡。
作用
- 输入
NET_LUID
(唯一标识一张网卡) - 输出
INTERFACE_TIMESTAMP_CAPABILITIES
(见前面贴的结构体) - 返回
ERROR_SUCCESS
或标准 Win32 错误码(ERROR_NOT_FOUND
、ERROR_NOT_SUPPORTED
…)
调用条件
- 编译期
#if NTDDI_VERSION >= NTDDI_WIN10_FE
- 运行期
- 要求 ≥ Win10 20H1
- 驱动必须实现 NDIS 6.83 的 Hardware Timestamping 小端口接口,否则返回全 0/False。
典型代码
#include <winsock2.h>
#include <iphlpapi.h>
#include <iostream>#pragma comment(lib, "iphlpapi.lib")int main() {NET_LUID luid{};// 实际场景:先 GetAdaptersAddresses 拿到 Luidluid.Value = 0x80000000000005; // 示例INTERFACE_TIMESTAMP_CAPABILITIES caps{};DWORD err = GetInterfaceActiveTimestampCapabilities(&luid, &caps);if (err == ERROR_SUCCESS) {printf("NIC clock %llu Hz\n", caps.HardwareClockFrequencyHz);printf("Cross-timestamp %s\n", caps.SupportsCrossTimestamp ? "yes" : "no");printf("HW PTPv2/UDP/IPv4 RX event %s\n",caps.HardwareCapabilities.PtpV2OverUdpIPv4EventMessageReceive ? "yes" : "no");} else {printf("err=%u\n", err);}
}
常见错误
错误码 | 含义 |
---|---|
ERROR_NOT_FOUND | LUID 不存在 |
ERROR_NOT_SUPPORTED | 系统版本过低或驱动不支持 |
ERROR_INVALID_PARAMETER | 指针为空 |
一句话总结
GetInterfaceActiveTimestampCapabilities
就是 “把网卡此刻真正能用的硬件时间戳能力搬回来” 的 runtime API;做高精度 PTP、纳秒级打时戳前先调用它,就能知道能不能用、能用到什么程度。
GetInterfaceSupportedTimestampCapabilities:检索指定网络适配器支持的时间戳功能
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
GetInterfaceSupportedTimestampCapabilities(_In_ CONST NET_LUID *InterfaceLuid,_Out_ PINTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites);
GetInterfaceSupportedTimestampCapabilities
是 Windows 提供的一个网络编程接口,用于检索指定网络适配器支持的时间戳功能。
函数原型
IPHLPAPI_DLL_LINKAGE DWORD GetInterfaceSupportedTimestampCapabilities(const NET_LUID *InterfaceLuid,PINTERFACE_TIMESTAMP_CAPABILITIES TimestampCapabilites
);
参数
- InterfaceLuid:指向
NET_LUID
结构的指针,表示要查询的网络适配器的本地唯一标识符(LUID)。 - TimestampCapabilites:指向
INTERFACE_TIMESTAMP_CAPABILITIES
结构的指针,用于接收查询到的时间戳功能信息。
返回值
- NO_ERROR:表示函数成功,时间戳功能信息已通过
TimestampCapabilites
参数返回。 - ERROR_NOT_SUPPORTED:表示指定的网络卡不支持时间戳功能。
- ERROR_BAD_DRIVER:表示网络卡驱动程序报告了不受支持的时间戳配置。
使用场景
该接口常用于网络编程中,特别是在需要了解网络适配器支持的时间戳功能时。通过查询网络适配器支持的时间戳功能,开发者可以决定是否启用特定的时间戳功能,从而优化网络数据包的处理。
示例代码
NET_LUID interfaceLuid;
INTERFACE_TIMESTAMP_CAPABILITIES timestampCapabilities;// 假设已获取到 interfaceLuid
DWORD result = GetInterfaceSupportedTimestampCapabilities(&interfaceLuid, ×tampCapabilities);
if (result == NO_ERROR)
{// 使用 timestampCapabilities 中的信息
}
else
{// 处理错误
}
注意事项
- 该接口的最低支持版本为 Windows 10 Build 20348。
- 在使用该接口之前,需要确保网络适配器已正确安装并支持时间戳功能。
与 GetInterfaceActiveTimestampCapabilities
的区别
GetInterfaceActiveTimestampCapabilities
:查询当前启用的时间戳功能。GetInterfaceSupportedTimestampCapabilities
:查询网络适配器支持的所有时间戳功能,无论当前是否启用。
CaptureInterfaceHardwareCrossTimestamp:从指定的网络接口(如以太网卡)中捕获 硬件时间戳 与 系统时间戳 的对应关系
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
CaptureInterfaceHardwareCrossTimestamp(_In_ CONST NET_LUID *InterfaceLuid,_Inout_ PINTERFACE_HARDWARE_CROSSTIMESTAMP CrossTimestamp);
1️⃣ 所在位置与用途
-
头文件:
<netioapi.h>
-
库文件:
Iphlpapi.lib
-
DLL 实现:
Iphlpapi.dll
-
引入方式:
#include <netioapi.h> #pragma comment(lib, "Iphlpapi.lib")
此函数是 Windows 网络时间同步机制 (Cross Timestamping) 的一部分。
它用于从指定的网络接口(如以太网卡)中捕获 硬件时间戳 与 系统时间戳 的对应关系。
2️⃣ 函数作用
CaptureInterfaceHardwareCrossTimestamp()
👉 用来从指定的网络接口中获取一个 交叉时间戳(cross timestamp),即:
在同一时刻,系统时钟(系统时间)与网卡硬件时钟(hardware clock)分别是多少?
这个函数通常用于:
- PTP(Precision Time Protocol,精确时间协议)同步;
- 网络时间同步 (NTS) 调试;
- 高精度延迟测量与时延补偿;
- 硬件时间戳 NIC 驱动验证。
3️⃣ 参数解释
🔹 InterfaceLuid
_In_ CONST NET_LUID *InterfaceLuid
- 指定要从中获取时间戳的 网络接口 LUID。
NET_LUID
是 Windows 中网络接口的唯一标识符,比接口索引 (ifIndex
) 更底层。- 你可以通过
ConvertInterfaceIndexToLuid()
或ConvertInterfaceGuidToLuid()
获取。
例如:
NET_LUID luid = {0};
ConvertInterfaceIndexToLuid(ifIndex, &luid);
🔹 CrossTimestamp
_Inout_ PINTERFACE_HARDWARE_CROSSTIMESTAMP CrossTimestamp
- 指向一个结构体,用来接收系统与硬件时间戳。
- 结构体定义如下:
typedef struct _INTERFACE_HARDWARE_CROSSTIMESTAMP {ULONG64 HardwareClockFrequencyHz;ULONG64 SystemTimestamp1;ULONG64 HardwareTimestamp;ULONG64 SystemTimestamp2;
} INTERFACE_HARDWARE_CROSSTIMESTAMP, *PINTERFACE_HARDWARE_CROSSTIMESTAMP;
各字段含义:
字段 | 类型 | 说明 |
---|---|---|
HardwareClockFrequencyHz | ULONG64 | 网卡硬件时钟的频率(Hz) |
SystemTimestamp1 | ULONG64 | 系统时间戳(QueryPerformanceCounter 计数)在测量前的值 |
HardwareTimestamp | ULONG64 | 同一时刻的网卡硬件时钟值 |
SystemTimestamp2 | ULONG64 | 系统时间戳在测量后的值(可用于估算捕获延迟) |
通过 (SystemTimestamp1 + SystemTimestamp2)/2
可近似获得系统时间与硬件时间的中点匹配。
4️⃣ 返回值
返回值 | 说明 |
---|---|
NO_ERROR (0) | 成功 |
ERROR_INVALID_PARAMETER | 参数错误 |
ERROR_NOT_FOUND | 接口不存在或不支持硬件时间戳 |
ERROR_NOT_SUPPORTED | 网卡或驱动不支持该操作 |
ERROR_GEN_FAILURE | 设备内部错误 |
5️⃣ 使用示例
#include <Windows.h>
#include <netioapi.h>
#include <iostream>#pragma comment(lib, "Iphlpapi.lib")int main()
{NET_LUID luid = {0};INTERFACE_HARDWARE_CROSSTIMESTAMP ts = {0};// 获取第一个接口的 LUID(例如索引为 12)if (ConvertInterfaceIndexToLuid(12, &luid) == NO_ERROR){DWORD ret = CaptureInterfaceHardwareCrossTimestamp(&luid, &ts);if (ret == NO_ERROR){std::cout << "HW Clock Hz: " << ts.HardwareClockFrequencyHz << "\n";std::cout << "System T1 : " << ts.SystemTimestamp1 << "\n";std::cout << "HW Time : " << ts.HardwareTimestamp << "\n";std::cout << "System T2 : " << ts.SystemTimestamp2 << "\n";}else{std::cerr << "Failed, error = " << ret << "\n";}}
}
6️⃣ 实际应用场景
- 在高精度网络同步中,配合
GetInterfaceHardwareTimestampCapabilities()
、GetInterfaceHardwareTimestampSettings()
使用; - Windows PTP 客户端、NDIS 驱动开发;
- 校准系统时钟与 NIC 时间基准(用于 5G/工业时钟同步)。
✅ 小结
项目 | 内容 |
---|---|
函数名 | CaptureInterfaceHardwareCrossTimestamp |
所属模块 | Iphlpapi.dll |
功能 | 获取系统与硬件时钟的交叉时间戳 |
参数 | 网络接口 LUID + 输出时间戳结构 |
返回值 | NO_ERROR 成功,否则错误码 |
场景 | 精确时间同步、PTP 校准、延迟测量 |
注:Windows PTP 客户端和NDIS驱动开发
INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK:在网络接口的硬件时间戳配置发生变化时通知上层
typedef
VOID
CALLBACK
INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK(_In_ PVOID CallerContext);typedef
INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK *PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK;
这是一个 Windows 网络接口时间戳配置变更回调函数(callback) 的类型声明,属于 NETIOAPI / NDIS 的一部分,用于在网络接口的硬件时间戳配置发生变化时通知上层。
🧩 拆解逐行说明
1️⃣ typedef ... CALLBACK ...
CALLBACK
是一个调用约定(宏),在 Windows 下通常等价于:
__stdcall
它指定函数在调用时使用 stdcall 调用约定(参数从右到左入栈,由被调用者清理栈)。
这是 Windows API 常见的约定,常用于事件回调函数。
2️⃣ 函数原型展开后是这样:
VOID __stdcall INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK(_In_ PVOID CallerContext
);
也就是说,这个函数:
-
返回类型:
VOID
(无返回值) -
调用方式:
__stdcall
-
参数:
PVOID CallerContext
:一个指向调用者自定义上下文数据的指针。
3️⃣ 第二个 typedef
typedef INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK *PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK;
定义了一个指针类型,方便传递函数指针:
PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK pfnCallback;
这就是“指向该回调函数的指针类型”。
🔧 用途与上下文
这个回调类型用于 注册接口时间戳配置变化事件通知。
当你调用某个 API 注册此回调后,如果网卡的硬件时间戳设置被修改(启用/禁用、PTP 模式变化等),系统就会调用你提供的回调函数。
举个例子:
假设有一个函数:
DWORD RegisterInterfaceTimestampConfigChangeCallback(NET_LUID *InterfaceLuid,PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK Callback,PVOID CallerContext
);
你可以这样使用:
VOID CALLBACK OnTimestampConfigChanged(PVOID CallerContext)
{printf("Interface timestamp configuration changed!\n");
}int main()
{NET_LUID luid = {0};ConvertInterfaceIndexToLuid(12, &luid);RegisterInterfaceTimestampConfigChangeCallback(&luid,OnTimestampConfigChanged,NULL // 可传入自定义上下文);
}
当系统检测到该网络接口的 PTP 或硬件时间戳配置变化 时,
它就会自动调用:
OnTimestampConfigChanged()
📄 参数说明
参数名 | 类型 | 说明 |
---|---|---|
CallerContext | PVOID | 用户传入的上下文指针。可以是任意结构体、对象等。系统调用回调时原样传回。常用于多接口或多模块区分来源。 |
🔁 常见使用场景
- 驱动或服务监听网卡时间戳能力启用/禁用;
- Windows PTP 客户端检测硬件支持变化;
- 调试工具实时更新 UI;
- 高精度时间同步守护进程中监测配置变化。
✅ 总结
项目 | 内容 |
---|---|
名称 | INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK |
类型 | 回调函数类型 |
调用方式 | __stdcall (CALLBACK ) |
参数 | PVOID CallerContext |
返回值 | VOID |
功能 | 当网卡时间戳配置变化时被调用 |
常见用途 | 注册监听接口时间戳配置变化事件 |
RegisterInterfaceTimestampConfigChange:用于 注册一个回调函数,当系统中任何网络接口的 时间戳配置(timestamp configuration)发生变化 时,系统就会自动调用你注册的回调。
IPHLPAPI_DLL_LINKAGE
DWORD
WINAPI
RegisterInterfaceTimestampConfigChange(_In_ PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK Callback,_In_opt_ PVOID CallerContext,_Out_ HIFTIMESTAMPCHANGE *NotificationHandle);
正是我们刚才提到的那个 “注册接口时间戳配置变化通知” 的 Windows API。
它与刚刚分析的 INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK
配合使用。
下面是完整、深入的解析👇
🧭 一、函数总体说明
📘 功能概述
RegisterInterfaceTimestampConfigChange()
用于 注册一个回调函数,当系统中任何网络接口的 时间戳配置(timestamp configuration)发生变化 时,
系统就会自动调用你注册的回调。
简单说:
✅ 当网卡硬件时间戳启用/禁用、PTP 支持状态改变时,你会收到通知。
🧩 二、函数原型解析
定义展开
DWORD WINAPI RegisterInterfaceTimestampConfigChange(PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK Callback,PVOID CallerContext,HIFTIMESTAMPCHANGE *NotificationHandle
);
🔹 参数解释
参数 | 类型 | 方向 | 说明 |
---|---|---|---|
Callback | PINTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK | In | 指向你定义的回调函数指针。当检测到接口时间戳配置变化时调用。 |
CallerContext | PVOID | In_opt | (可选)上下文指针,会原样传回回调函数,用于区分调用来源或携带用户数据。 |
NotificationHandle | HIFTIMESTAMPCHANGE* | Out | 返回一个句柄,用于之后注销通知(通过 UnregisterInterfaceTimestampConfigChange )。 |
🔹 返回值
返回值 | 说明 |
---|---|
NO_ERROR (0) | 成功 |
ERROR_INVALID_PARAMETER | 参数错误 |
ERROR_NOT_ENOUGH_MEMORY | 资源不足 |
ERROR_GEN_FAILURE | 注册失败或系统不支持 |
⚙️ 三、配套的注销函数
注册后若不再需要监听,应主动注销:
DWORD WINAPI UnregisterInterfaceTimestampConfigChange(_In_ HIFTIMESTAMPCHANGE NotificationHandle
);
📄 四、使用流程
1️⃣ 定义回调函数
VOID CALLBACK OnTimestampConfigChanged(PVOID CallerContext)
{printf("Timestamp configuration changed!\n");
}
2️⃣ 注册回调
#include <Windows.h>
#include <netioapi.h>
#include <iostream>#pragma comment(lib, "Iphlpapi.lib")int main()
{HIFTIMESTAMPCHANGE hChange = NULL;DWORD result = RegisterInterfaceTimestampConfigChange(OnTimestampConfigChanged, // 回调函数NULL, // 用户上下文&hChange // 输出句柄);if (result == NO_ERROR){std::cout << "Registered timestamp config change callback successfully.\n";std::cout << "Waiting for configuration change...\n";}else{std::cerr << "Register failed, error = " << result << std::endl;}// 通常这里会进入事件循环或等待Sleep(INFINITE);// 程序退出前应注销UnregisterInterfaceTimestampConfigChange(hChange);
}
3️⃣ 当网卡的 PTP/时间戳功能被启用或禁用时,系统会自动调用:
OnTimestampConfigChanged()
🔧 五、实际用途
场景 | 说明 |
---|---|
🕰️ PTP 客户端服务 | 当某个接口启用了硬件时间戳,重新初始化时间同步逻辑。 |
🧩 诊断或调试工具 | 监听所有网卡的时间戳配置变化,用于更新 GUI 或日志。 |
⚙️ 驱动/中间层服务 | 自动响应系统或用户配置更改(例如通过 PowerShell 修改)。 |
📘 六、关联结构与概念
名称 | 类型 | 作用 |
---|---|---|
INTERFACE_TIMESTAMP_CONFIG_CHANGE_CALLBACK | 回调类型 | 注册时传入的回调函数 |
HIFTIMESTAMPCHANGE | 句柄类型 | 系统内部注册实例标识 |
RegisterInterfaceTimestampConfigChange | 函数 | 注册回调通知 |
UnregisterInterfaceTimestampConfigChange | 函数 | 注销通知 |
CaptureInterfaceHardwareCrossTimestamp | 函数 | 获取硬件/系统时间戳映射,用于同步 |
✅ 七、总结
项目 | 内容 |
---|---|
函数名 | RegisterInterfaceTimestampConfigChange |
所属模块 | Iphlpapi.dll / <netioapi.h> |
功能 | 注册回调以监听网卡时间戳配置变化 |
调用方式 | WINAPI (__stdcall ) |
返回值 | DWORD 错误码 |
典型配对函数 | UnregisterInterfaceTimestampConfigChange() |
使用场景 | PTP 客户端、网卡驱动监控、时间同步调试工具 |
UnregisterInterfaceTimestampConfigChange:取消之前通过 RegisterInterfaceTimestampConfigChange()
注册的时间戳配置变化回调通知
IPHLPAPI_DLL_LINKAGE
VOID
WINAPI
UnregisterInterfaceTimestampConfigChange(_In_ HIFTIMESTAMPCHANGE NotificationHandle);
📘 核心作用
取消之前通过 RegisterInterfaceTimestampConfigChange()
注册的时间戳配置变化回调通知,
释放系统资源,停止事件回调。
⚙️ 参数说明
参数名 | 类型 | 说明 |
---|---|---|
NotificationHandle | HIFTIMESTAMPCHANGE | 注册时获得的句柄,用于标识要注销的回调监听。 |
🧩 使用示例
#include <Windows.h>
#include <netioapi.h>
#include <iostream>#pragma comment(lib, "Iphlpapi.lib")// 回调函数
VOID CALLBACK OnTimestampConfigChanged(PVOID Context)
{std::cout << "Timestamp config changed!" << std::endl;
}int main()
{HIFTIMESTAMPCHANGE handle = NULL;// 注册回调if (RegisterInterfaceTimestampConfigChange(OnTimestampConfigChanged, NULL, &handle) == NO_ERROR){std::cout << "Registered callback. Waiting...\n";Sleep(10000); // 模拟等待事件// 注销回调UnregisterInterfaceTimestampConfigChange(handle);std::cout << "Unregistered callback.\n";}else{std::cerr << "Register failed.\n";}
}
✅ 总结:
- 功能:取消监听时间戳配置变化事件。
- 参数:注册时返回的句柄。
- 返回值:无。