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/7/27 18:40:56 阅读更多 →
数以轻舟Agent V4发布:底层重构 + 语义自定义

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

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

2026/7/27 18:40:56 阅读更多 →
seckill项目单元测试实践:确保秒杀功能的稳定性与可靠性

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

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

2026/7/27 18:40:56 阅读更多 →

最新新闻

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络

3分钟快速上手PyTorch Geometric:构建你的第一个图神经网络 【免费下载链接】pytorch_geometric Graph Neural Network Library for PyTorch 项目地址: https://gitcode.com/GitHub_Trending/py/pytorch_geometric 你是否曾被复杂的图神经网络(GN…

2026/7/27 18:48:59 阅读更多 →
如何在React表单中集成Turnstile:提升安全性的完整指南

如何在React表单中集成Turnstile:提升安全性的完整指南

如何在React表单中集成Turnstile:提升安全性的完整指南 【免费下载链接】react-turnstile Cloudflare Turnstile integration for React. 项目地址: https://gitcode.com/gh_mirrors/re/react-turnstile React Turnstile是Cloudflare Turnstile在React应用中…

2026/7/27 18:48:59 阅读更多 →
Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验

Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验

Redis-Search终极指南:高性能实时前缀搜索如何革新Rails应用体验 【免费下载链接】redis-search Deprecated! High performance real-time prefix search, indexes store in Redis for Rails application 项目地址: https://gitcode.com/gh_mirrors/re/redis-sear…

2026/7/27 18:48:59 阅读更多 →
外贸网站内容怎么写才符合GEO?给AI看的“说明书”写作法

外贸网站内容怎么写才符合GEO?给AI看的“说明书”写作法

一个外贸总监的认知升级笔记做了八年外贸内容运营,我写过几百个产品页面、几十篇技术文章、数不清的FAQ。以前的标准很明确:关键词布局合理、描述有说服力、排版清晰易读——这就是一篇“好内容”。但去年我开始意识到,这个标准可能不够了。问…

2026/7/27 18:48:59 阅读更多 →
chat_templates高级技巧:自定义stop_token_ids实现精准对话控制

chat_templates高级技巧:自定义stop_token_ids实现精准对话控制

chat_templates高级技巧:自定义stop_token_ids实现精准对话控制 【免费下载链接】chat_templates Chat Templates for 🤗 HuggingFace Large Language Models 项目地址: https://gitcode.com/gh_mirrors/ch/chat_templates 在使用HuggingFace大语…

2026/7/27 18:48:59 阅读更多 →
用NextAuth.js实现完整用户认证:Next.js-Prisma-Boilerplate身份验证指南

用NextAuth.js实现完整用户认证:Next.js-Prisma-Boilerplate身份验证指南

用NextAuth.js实现完整用户认证:Next.js-Prisma-Boilerplate身份验证指南 【免费下载链接】nextjs-prisma-boilerplate Full stack boilerplate with Next.js, Prisma, Tailwind, TypeScript, Docker, Postgres, documentation, frontend and backend unit and inte…

2026/7/27 18:47:59 阅读更多 →

日新闻

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于SpringBoot的社区智能垃圾管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:54 阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:54 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/27 4:33:59 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/27 6:31:56 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/27 4:01:12 阅读更多 →

月新闻