Winsock 协议与名称空间 Provider 目录
Winsock 协议与名称空间 Provider 目录文章所述功能来自KswordARK项目开源地址 https://github.com/KSwordDEV/KSword要取得当前进程可见的 Winsock 目录分为四步本篇要得到当前进程可见的 Winsock 协议目录和名称空间目录并读出每个条目的身份、类型和活动状态。这个过程只读取目录不安装、删除或调整提供程序。要完成这项读取分为四步认识目录中的对象并初始化 Winsock测量缓冲区并读取 Protocol Catalog测量缓冲区并读取 Name Space Catalog解读条目、记录查询范围并归还 Winsock 引用Windows SocketsWinsock是 Windows 程序访问网络的公共接口。应用程序调用socket、connect、send、recv或名称查询函数时调用不会直接面对网卡驱动。Winsock 根据目录中的提供程序信息选择实现再由协议栈、网络设备和远端系统完成通信。目录是系统网络配置的一部分读取目录能够说明当前进程看见哪些提供程序不能单独证明某个程序已经使用某一项。Winsock 有两类目录。协议目录Protocol Catalog回答“某种地址族、套接字类型和协议如何收发数据”。名称空间目录Name Space Catalog回答“某类名称如何解析为地址或服务”。两类条目都带 GUID 和显示名却处在不同调用链。排查网络异常时先分清这两个角色再检查条目的位数、目录 ID 与返回错误。创建套接字应用参数 - Protocol Catalog - 协议 Provider - 网络栈名称查询查询参数 - Name Space Catalog - 名称空间 Provider - 地址结果只读检查WSAStartup - 测量所需字节数 - 分配缓冲区 - 枚举条目 - WSAcCleanup一、第一步认识目录中的对象并初始化 Winsock协议目录条目用WSAPROTOCOL_INFOW描述。条目中的iAddressFamily表示地址族例如AF_INET和AF_INET6。iSocketType表示SOCK_STREAM、SOCK_DGRAM等套接字语义。iProtocol是IPPROTO_TCP、IPPROTO_UDP等协议号。GUIDGlobally Unique Identifier全局唯一标识符是 Windows 用 128 位值标识对象的格式ProviderId用它标识提供程序。dwCatalogEntryId是当前目录中的条目身份。链式提供程序还会由多个目录项共同组成。名称空间目录条目用WSANAMESPACE_INFOW描述。dwNameSpace表示名称空间类别例如NS_DNS代表 DNSNS_NLA与网络位置感知有关。NSProviderId表示提供程序身份fActive表示条目当前活动状态lpszIdentifier是显示文本。名称空间条目参与主机名、服务名或服务发现查询它不承担 TCP 字节发送。调用socket地址族、套接字类型和协议 - Protocol Catalog - 协议 Provider - 连接、收发和套接字选项调用getaddrinfo名称查询 - Name Space Catalog - DNS、NLA 或其它 Provider - 候选地址同名条目不能仅凭显示文本合并。目录 ID 与 GUID 才能帮助识别条目。地址族、进程位数和目录种类决定其语义。一个网络程序可以只使用协议提供程序也可以先经过名称解析后再创建套接字。初始化是当前进程的前置条件在调用大多数 Winsock API 前当前进程要先调用WSAStartup。函数的返回值为0表示成功非零值直接就是 Winsock 错误码。成功调用一次就要在同一进程中调用一次WSACleanup归还初始化计数。WSADATA由调用方提供存储空间函数在其中写入协商后的版本和实现信息。// 作用初始化当前进程的 Winsock 使用计数并协商 API 版本。// 返回0 成功。非零值是 Winsock 错误码不依赖 WSAGetLastError。intWSAStartup(WORD wVersionRequired,// 请求版本例如 MAKEWORD(2, 2)LPWSADATA lpWSAData// 输出版本、描述和实现信息。调用方拥有此结构);// 作用与一次成功的 WSAStartup 配对减少当前进程的初始化计数。// 返回0 成功。SOCKET_ERROR 失败失败时可调用 WSAGetLastError。intWSACleanup(void);WSADATA data{};intresultWSAStartup(MAKEWORD(2,2),data);if(result0){// 在这里读取目录。完成后必须调用 WSACleanup()。}初始化只影响当前进程不会修复、安装或重排系统目录。WSASYSNOTREADY通常表示网络子系统未准备好。版本协商失败说明请求版本不被实现支持。访问限制也应和“目录为空”分开记录。完成第一步后当前进程已经取得可用的 Winsock 引用也能区分协议目录和名称空间目录的用途。接下来读取 Protocol Catalog才能把“支持哪些网络通信组合”变成可核对的条目。二、第二步测量缓冲区并读取 Protocol CatalogWSCEnumProtocols读取协议目录。该 SPI 函数的结构类型固定为WSAPROTOCOL_INFOW因此函数名称本身没有W后缀。首次调用将lpBuffer设为nullptr。典型结果是SOCKET_ERROR同时lpErrno写入WSAENOBUFSlpdwBufferLength写入所需容量。容量的单位是字节。分配该容量后重复调用函数返回的非负数才是有效WSAPROTOCOL_INFOW条目数。// 作用枚举当前进程可见的协议目录条目。// 返回非负数为条目数。SOCKET_ERROR 失败lpErrno 接收扩展错误。INT WSAAPIWSCEnumProtocols(LPINT lpiProtocols,// 可选协议号过滤数组。nullptr 表示全部LPWSAPROTOCOL_INFOW lpBuffer,// 输出连续条目缓冲区。首次测量可为 nullptrLPDWORD lpdwBufferLength,// 输入容量、输出所需或实际容量单位为字节LPINT lpErrno// 输出WSAENOBUFS 等扩展错误码);DWORD bytes0;interror0;intcountWSCEnumProtocols(nullptr,nullptr,bytes,error);if(countSOCKET_ERRORerrorWSAENOBUFSbytes!0){std::vectorBYTEraw(bytes);DWORD capacitybytes;countWSCEnumProtocols(nullptr,reinterpret_castLPWSAPROTOCOL_INFOW(raw.data()),capacity,error);// count 才是元素数量capacity 仍然是字节数。}目录可能在两次调用间被安装程序或网络维护操作改写。第二次仍返回WSAENOBUFS时应采用有限次数的重新分配和重试。容量没有增长、错误码为非WSAENOBUFS值、或超出合理上限时停止。把bytes / sizeof(WSAPROTOCOL_INFOW)当成条目数是错误的因为bytes是容量返回结构中也可能带有不同版本字段。错误示例DWORD bytes4096;std::vectorBYTEraw(bytes);intassumedstatic_castint(bytes/sizeof(WSAPROTOCOL_INFOW));// 错误assumed 只是可能容纳的结构数量并非 API 实际写入的条目数。枚举结果应保存条目数、目录 ID、Provider GUID、地址族、套接字类型、协议号、链长度和显示名。iProtocol是数字协议标识不能当作 DLL 文件路径。Provider GUID 是身份标识DLL 定位属于更深一层安装信息。完成第二步后已经得到当前进程可用于建连和收发数据的协议条目。名称解析仍由另一套目录负责接下来读取 Name Space Catalog才能知道名称会交给哪些解析实现处理。三、第三步测量缓冲区并读取 Name Space CatalogWSCEnumNameSpaceProvidersW提供当前进程可见的名称空间条目。它的lpdwBufferLength同样以字节计量成功返回条目数量失败返回SOCKET_ERROR错误通过WSAGetLastError取得。首次测量后再调用时也可能遇到目录变化。// 作用枚举名称空间 Provider 目录。// 返回非负数为条目数。SOCKET_ERROR 失败使用 WSAGetLastError 获取错误。INT WSAAPIWSCEnumNameSpaceProvidersW(LPDWORD lpdwBufferLength,// 输入容量、输出所需容量单位为字节LPWSANAMESPACE_INFOW lpnspBuffer// 输出连续条目。测量阶段可为 nullptr);DWORD bytes0;intcountWSCEnumNameSpaceProvidersW(bytes,nullptr);if(countSOCKET_ERRORbytes!0){std::vectorBYTEraw(bytes);DWORD capacitybytes;countWSCEnumNameSpaceProvidersW(capacity,reinterpret_castLPWSANAMESPACE_INFOW(raw.data()));}lpszIdentifier可能为空未知dwNameSpace数值也可能在新系统或第三方提供程序上出现。读取工具应保留原始数字和 GUID而非因显示文本为空自动删除条目。名称空间不存在、条目不活动、缓冲区不足、网络子系统未准备好和访问遭拒是不同的诊断结论。完成第三步后两个目录都已读入内存。接下来要结合进程位数、条目字段和错误状态解释这些记录再在读取结束时归还 Winsock 初始化引用。四、第四步解读条目、记录查询范围并归还 Winsock 引用32 位与 64 位目录视图Winsock 目录按进程位数区分。64 位进程查询到的目录可与 32 位进程不同。安装器、兼容层和提供程序架构都会影响可见条目。记录结果时至少包含操作系统架构、查询进程位数、Protocol Catalog 或 Name Space Catalog 类别、目录 ID、Provider GUID 和查询时的错误码。目录安装、删除和顺序调整影响系统范围内的网络程序。遇到异常时先进行只读枚举并保留快照再使用受支持的网络维护接口或供应商安装程序处理。直接删除注册表字符串可能留下引用、顺序和跨位数目录不一致的问题。从进程初始化到目录记录的完整流程这一流程的输入是当前进程请求的 Winsock 版本输出是该进程可见的协议目录和名称空间目录快照。Winsock DLL 维护每个进程的初始化计数。WSAStartup成功后创建一次可用引用WSACleanup归还一次引用。WSADATA是调用方在栈或其他可用存储中分配的结构Winsock 在初始化成功时写入协商版本。目录缓冲区由调用方分配API 只在调用期间借用它缓冲区销毁后其中的结构指针随之失效。请求 Winsock 2.2 - WSAStartup 写入 WSADATA - 空缓冲区测量 Protocol Catalog 的字节数 - 分配字节缓冲区 - 重复查询 - 用返回条目数遍历 - 空缓冲区测量 Name Space Catalog - 同样读取 - 记录目录 ID、GUID、类型、进程位数和错误状态 - WSACleanup 归还初始化引用WSAGetLastError只适用于返回SOCKET_ERROR且文档要求通过 Winsock 错误槽取得原因的 API。WSCEnumProtocols把扩展错误写入其lpErrno参数读取该输出参数。名称空间枚举没有该参数才在失败后立即调用WSAGetLastError。错误码要在日志格式化或 GUID 转换前保存因为后续 API 可能覆盖线程错误状态。// 作用返回当前线程最近一次失败的 Winsock API 错误码。// 返回WSA* 错误整数。没有参数、没有资源所有权和长度单位。intWSAGetLastError(void);下面的正确示范完整枚举协议目录。它先处理“首次调用预期容量不足”的状态再处理第二次调用期间目录变动导致的重复不足。count是可访问结构数capacity是字节数二者不能混用。#ifndefWIN32_LEAN_AND_MEAN#defineWIN32_LEAN_AND_MEAN#endif#includewinsock2.h#includews2spi.h#includevectorintEnumerateProtocolCatalog(){WSADATA startupData{};intstartupWSAStartup(MAKEWORD(2,2),startupData);if(startup!0)returnstartup;// 返回值直接是错误码。尚未产生清理责任DWORD requiredBytes0;intcatalogError0;intcountWSCEnumProtocols(nullptr,// 输入nullptr 表示不按协议号过滤nullptr,// 输出测量阶段没有接收缓冲区requiredBytes,// 输出需要的容量单位为字节catalogError);// 输出函数失败时写入 WSAENOBUFS 等错误if(count!SOCKET_ERROR||catalogError!WSAENOBUFS||requiredBytes0){WSACleanup();returncatalogError;}for(intretry0;retry!3;retry){std::vectorBYTEbytes(requiredBytes);// vector 拥有缓冲区并在循环最后释放DWORD capacityrequiredBytes;countWSCEnumProtocols(nullptr,reinterpret_castLPWSAPROTOCOL_INFOW(bytes.data()),// 输出连续结构起始地址capacity,catalogError);if(count!SOCKET_ERROR){constauto*entriesreinterpret_castconstWSAPROTOCOL_INFOW*(bytes.data());for(intindex0;indexcount;index){constWSAPROTOCOL_INFOWitementries[index];// item 只在 bytes 存活期间可读。这里记录 item.dwCatalogEntryId 和 item.ProviderId。}WSACleanup();return0;}if(catalogError!WSAENOBUFS||capacityrequiredBytes)break;requiredBytescapacity;// 目录在两次调用间增大使用新字节容量重试}WSACleanup();returncatalogError;}名称空间目录的标准流程相同只是错误传递方式不同。lpnspBuffer接收WSANAMESPACE_INFOW数组条目中的lpszIdentifier是 API 管理的指针仅在调用方提供的缓冲区仍然存活时使用。保存结果时复制文本和 GUID。DWORD bytes0;intcountWSCEnumNameSpaceProvidersW(bytes,// 输出测量阶段返回所需容量单位为字节不能为 nullptrnullptr);// 输出测量阶段不接收结构if(countSOCKET_ERRORbytes!0){constintmeasureErrorWSAGetLastError();// 立即读取失败原因std::vectorBYTEraw(bytes);DWORD capacitybytes;countWSCEnumNameSpaceProvidersW(capacity,// 输入可用字节数输出实际/所需字节数reinterpret_castLPWSANAMESPACE_INFOW(raw.data()));if(countSOCKET_ERROR){constintreadErrorWSAGetLastError();// readError WSAENOBUFS 时可在有限次数内扩容并重试。}}错误做法是在没有调用WSAStartup时直接读取目录或在WSAStartup成功后遗漏WSACleanup。前者可能得到WSASYSNOTREADY或其他初始化失败状态后者使进程内引用计数不能按预期归还。另一个错误是保留WSAPROTOCOL_INFOW*或lpszIdentifier指针到std::vectorBYTE离开作用域之后。那时底层缓冲区已释放指针不再有效。完整可运行程序在附件https://wangweicm.lanzouu.com/icGmw3yz8e5a

相关新闻

Qlib量化投资平台实战指南:3步构建你的AI投资策略

Qlib量化投资平台实战指南:3步构建你的AI投资策略

Qlib量化投资平台实战指南:3步构建你的AI投资策略 【免费下载链接】qlib Qlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML m…

2026/10/17 3:20:28 阅读更多 →
数以轻舟Agent V4发布:底层重构 + 语义自定义

数以轻舟Agent V4发布:底层重构 + 语义自定义

你有没有这种经历:你说的话,AI听不懂"重点""帮我看看这份数据有没有问题。"你以为AI会像资深同事一样,先问清楚"什么数据、看什么指标、按什么口径",再动手。结果大模型二话不说,按它自…

2026/10/16 7:37:17 阅读更多 →
seckill项目单元测试实践:确保秒杀功能的稳定性与可靠性

seckill项目单元测试实践:确保秒杀功能的稳定性与可靠性

seckill项目单元测试实践:确保秒杀功能的稳定性与可靠性 【免费下载链接】seckill Java高并发秒杀API(慕课网) 项目地址: https://gitcode.com/gh_mirrors/secki/seckill 在高并发场景下,秒杀系统的稳定性与可靠性至关重要…

2026/10/16 7:37:52 阅读更多 →

最新新闻

SMOG可读性公式实战:从音节计数到工程实现避坑指南

SMOG可读性公式实战:从音节计数到工程实现避坑指南

简介:smog-formula 是一份基于 1969 年 SMOG(Gobbledygook 的简单度量)公式实现文本阅读难易程度检测的 JavaScript 工具包,面向需要评估英文文本可读性等级的前端开发者、教育技术研究者与内容编辑。它通过统计句子数与多音节词数…

2026/10/17 3:19:47 阅读更多 →
企业微信AI自动回复实战:意图识别到仿人化话术

企业微信AI自动回复实战:意图识别到仿人化话术

1. 项目概述与需求拆解先聊聊我为什么会对这个项目产生兴趣。做过企业微信(以下简称企微)运营的朋友应该都有同感:客户消息回慢了,人跑去别家下单了;回快了,话术生硬得像机器人,客户反而觉得被敷…

2026/10/17 3:19:47 阅读更多 →
法律AI落地实践:自进化与协作的智能体框架设计

法律AI落地实践:自进化与协作的智能体框架设计

我最早接触到这个需求,是一位做非诉业务的律师朋友。他每天的工作有一大半时间耗在合同审查、法条检索和尽调清单初稿上,而这些活儿的共同特点是:重复、结构化但细节繁杂、跨法域知识要求高。市面上通用的法律AI工具他也试过不少,…

2026/10/17 3:19:47 阅读更多 →
YOLOv8改进实现鱼眼检测与毫米级测量分析

YOLOv8改进实现鱼眼检测与毫米级测量分析

1. 为什么盯上鱼眼:水产养殖与鱼类生物学里的刚需场景前一阵子帮一个做水产监测的团队整理图像数据,遇到一个绕不开的问题:鱼体状态评估里,眼径是一个关键指标,和体长、体重、发育阶段相关性很高,但过去全靠…

2026/10/17 3:19:47 阅读更多 →
Ubuntu服务器部署OpenClaw:从零到常驻后台的完整指南

Ubuntu服务器部署OpenClaw:从零到常驻后台的完整指南

本地部署openclaw这件事,我前前后后折腾了两天。第一天照着网上一些零散的教程去试,结果不是权限报错就是端口冲突,折腾到半夜服务都没起来。第二天干脆推倒重来,从裸系统开始一步步捋,把每个环节都记下来,…

2026/10/17 3:19:47 阅读更多 →
CH340G USB转TTL原理图设计:从选型到打板避坑指南

CH340G USB转TTL原理图设计:从选型到打板避坑指南

简介:这份资源是CH340G USB转TTL模块的完整硬件设计包,面向嵌入式开发者、电子爱好者及需要为Cortex-M3等MCU搭建调试下载链路的工程师。它解决的是从USB协议到TTL串口电平转换的电路实现问题,可直接用于打板制作实物。压缩包共7个文件&#…

2026/10/17 3:18:47 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →