在Windows系统中,通过网络邻居可以方便地查看本地网络中的共享资源和计算机。通过使用Windows API中的一些网络相关函数,我们可以实现枚举网络邻居信息的功能,获取连接到本地网络的其他计算机的相关信息。本文将介绍一个简单的C++程序,使用Windows API枚举网络邻居信息,并获取对端名称、本机名称、主机名称以及主机IP等信息。

引言

首先,我们需要了解一下几个与网络邻居信息有关的Windows API函数:

NETRESOURCE 结构体是 Windows 网络 API 中的一个结构体,用于描述网络资源的信息。它在网络资源的枚举和连接等操作中经常被使用。

结构体定义

typedef struct _NETRESOURCE {
DWORD dwScope;
DWORD dwType;
DWORD dwDisplayType;
DWORD dwUsage;
LPTSTR lpLocalName;
LPTSTR lpRemoteName;
LPTSTR lpComment;
LPTSTR lpProvider;
} NETRESOURCE, *LPNETRESOURCE;

结构体成员

  • dwScope:指定资源的可见性。可能的取值为:

    • RESOURCE_CONNECTED:表示已连接的资源。
    • RESOURCE_CONTEXT:表示会话特定的资源。
  • dwType:指定资源的类型。可能的取值为:
    • RESOURCETYPE_ANY:表示任何类型的资源。
    • RESOURCETYPE_DISK:表示磁盘资源。
    • RESOURCETYPE_PRINT:表示打印机资源。
  • dwDisplayType:指定资源的显示类型。可能的取值为:
    • RESOURCEDISPLAYTYPE_GENERIC:表示通用资源。
    • RESOURCEDISPLAYTYPE_DOMAIN:表示域。
  • dwUsage:指定资源的使用类型。可能的取值为:
    • RESOURCEUSAGE_CONNECTABLE:表示资源可以连接。
    • RESOURCEUSAGE_CONTAINER:表示资源是一个容器,可以包含其他资源。
  • lpLocalName:指定本地驱动器或打印机的本地名称。
  • lpRemoteName:指定远程共享资源的网络名称。
  • lpComment:指定资源的注释。
  • lpProvider:指定提供资源的网络提供程序的名称。

WNetOpenEnum 是 Windows 网络功能中的一个API函数,WNetOpenEnum 通过指定的参数打开一个用于列举网络资源的枚举句柄。这个句柄可以在后续的操作中用于获取网络资源的枚举信息。

函数原型

DWORD WNetOpenEnum(
DWORD dwScope,
DWORD dwType,
DWORD dwUsage,
LPNETRESOURCE lpNetResource,
LPHANDLE lphEnum
);

参数说明

  • dwScope:指定枚举的范围,可以是 RESOURCE_CONNECTEDRESOURCE_GLOBALNETRESOURCE_REMEMBEREDRESOURCE_CONTEXT 中的一个。
  • dwType:指定枚举资源的类型,可以是 RESOURCETYPE_DISKRESOURCETYPE_PRINTRESOURCETYPE_ANY 中的一个。
  • dwUsage:指定枚举资源的使用类型,可以是 RESOURCEUSAGE_CONNECTABLERESOURCEUSAGE_CONTAINERRESOURCEUSAGE_NOLOCALDEVICERESOURCEUSAGE_SIBLING 中的一个。
  • lpNetResource:指向 NETRESOURCE 结构的指针,用于指定枚举的起始位置。如果为 NULL,则从所有资源的最顶层开始枚举。
  • lphEnum:指向句柄的指针,用于接收枚举句柄。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回一个错误代码,可以通过 GetLastError 函数获取详细信息。

WNetEnumResource 是 Windows 网络功能中的 API 函数之一,用于通过枚举句柄获取网络资源的详细信息,包括资源的类型、用途、本地名、远程名等信息。

函数原型

DWORD WNetEnumResource(
HANDLE hEnum,
LPDWORD lpcCount,
LPVOID lpBuffer,
LPDWORD lpBufferSize
);

参数说明

  • hEnum:枚举句柄,通过 WNetOpenEnum 函数获取的句柄。
  • lpcCount:指向一个变量的指针,该变量用于接收枚举的资源数目。
  • lpBuffer:指向一个缓冲区的指针,用于接收枚举的资源信息。
  • lpBufferSize:指向一个变量的指针,该变量用于指定或接收缓冲区的大小。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回一个错误代码,可以通过 GetLastError 函数获取详细信息。

WNetCloseEnum 函数用于关闭由 WNetOpenEnum 函数打开的网络资源的枚举句柄。在使用 WNetOpenEnum 函数枚举网络资源后,当不再需要使用枚举句柄时,应该通过调用 WNetCloseEnum 函数来释放资源,避免内存泄漏。

函数定义

DWORD WNetCloseEnum(
HANDLE hEnum
);

参数

  • hEnum:网络资源的枚举句柄,该句柄是由 WNetOpenEnum 函数返回的。

返回值

如果函数调用成功,返回 NO_ERROR,否则返回错误代码,可以通过 GetLastError 函数获取详细的错误信息。

代码实现

以下是一个简单的C++程序,使用上述API函数实现了枚举网络邻居信息的功能。该程序通过遍历枚举得到的网络资源信息,获取对端名称、本机名称、主机名称以及主机IP等信息,并输出到控制台。

#include <iostream>
#include <Windows.h>
#include <winnetwk.h> #pragma comment(lib,"Mpr.lib")
#pragma comment(lib,"Ws2_32.lib") // 枚举网络邻居
BOOL EnumNetResource()
{
NETRESOURCE *NetResource = NULL;
HANDLE hEnum;
unsigned int i;
char szHostName[MAX_PATH] = { 0 };
hostent *host = NULL;
char *lpszIP = NULL; // 通过WSAStartup函数完成对Winsock服务的初始化
WSADATA wsaData = { 0 };
WSAStartup(MAKEWORD(2, 2), &wsaData); // 指定枚举范围, 获取枚举句柄
WNetOpenEnum(RESOURCE_CONTEXT, NULL, NULL, NULL, &hEnum);
if (hEnum)
{
DWORD Count = 0xFFFFFFFF;
DWORD BufferSize = 2048;
BYTE *pBuffer = new BYTE[2048]; // 根据设置的枚举返回, 获取枚举信息
WNetEnumResource(hEnum, &Count, pBuffer, &BufferSize);
NetResource = (NETRESOURCE*)pBuffer; for (i = 0; i < BufferSize / sizeof(NETRESOURCE); i++, NetResource++)
{
// 判断资源类型是否是所有资源 以及 判断资源使用类型是否是容器资源
if (NetResource->dwUsage == RESOURCEUSAGE_CONTAINER && NetResource->dwType == RESOURCETYPE_ANY)
{
if (NetResource->lpRemoteName)
{
// 获取远程主机名
RtlZeroMemory(szHostName, MAX_PATH);
lstrcpy(szHostName, (char *)((DWORD64)NetResource->lpRemoteName + 2)); // 根据主机名获取IP地址信息
host = gethostbyname(szHostName);
if (host == NULL)
{
std::cout << "错误代码" << std::endl;
continue;
} // 将Ipv4网络地址转换为Internet标准点分十进制格式的ASCII字符串
lpszIP = inet_ntoa(*(in_addr *)host->h_addr_list[0]);
std::cout << "对端名称: " << NetResource->lpRemoteName
<< " 本机名称: " << NetResource->lpLocalName
<< " 主机名称: " << szHostName
<< " 主机IP: " << lpszIP
<< std::endl;
}
}
} // 释放内存并关闭句柄
delete[]pBuffer;
pBuffer = NULL;
WNetCloseEnum(hEnum);
}
return TRUE;
} int main(int argc, char *argv[])
{
EnumNetResource(); system("pause");
return 0;
}

结语

通过这个简单的程序,我们可以了解如何使用Windows API函数来枚举网络邻居信息。这对于需要在程序中获取网络中其他计算机信息的场景是非常有用的。在实际应用中,可以根据需要进一步扩展和优化代码,以满足特定的功能需求。

C/C++ 实现枚举网上邻居信息的更多相关文章

  1. Win8无法访问xp共享的解决方法——win8网上邻居访问别的xp电脑要用户名和密码取消方法

    新装win8,原来的win7正常连接xp下载机的共享,但在win8下进网上邻居却无法访问xp的共享,显示”用户名或密码不正确”,而密码明明是对的如图所示: 解决方法: 按Win+R启动运行,输secp ...

  2. Win7 如何访问XP系统里的网上邻居?

    Win7 如何访问XP系统里的网上邻居? [ 标签:win7,xp系统 ] 现有两台电脑,一台XP,一台WIN7,共用一个无线路由器(两者都是经无线网络连接路由器).可以从XP里访问WIN7里的共享文 ...

  3. 深入了解"网上邻居"原理

    说到“网上邻居”,相信很多人都很熟悉.但是说起“网上邻居”的工作机制,可能大家就不太清楚了. 要说“网上邻居”的工作机制,不妨联系一下生活中的例子:比如我(A),要拜访一个远方的朋友(B),我要去他的 ...

  4. Win7网上邻居提示未授予用户在此计算机上的请求登录类型解决办法

        内容简介 装了Win7之后很多人遇到这样的问题,网上邻居访问Win7的电脑时出现“未授予用户在此计算机上的请求登录类型”问题.打开“控制面板”--“管理工具”--“本地安全策略”--“本地策略 ...

  5. server2003中看不到网上邻居内容,其他电脑无法通过计算机名和IP访问本计算机(但网上邻居中可访问到)

    现象1:server2003中看不到网上邻居内容,查看工作组计算机看到的是空列表, 现象2:其他电脑无法通过计算机名和IP访问本计算机(但网上邻居中可访问到)   访问提示:--Windows 200 ...

  6. .NET获取枚举DescriptionAttribute描述信息性能改进的多种方法

    一. DescriptionAttribute的普通使用方式 1.1 使用示例 DescriptionAttribute特性可以用到很多地方,比较常见的就是枚举,通过获取枚举上定义的描述信息在UI上显 ...

  7. 在Ubuntu 12.04安装和设置Samba实现网上邻居共享

    转载:http://www.startos.com/ubuntu/tips/2012031333097.html          有微小改动. Samba 是一款功能强大的共享工具,可以实现与win ...

  8. Win10无法访问网上邻居电脑共享的文件夹怎么办

    Win10无法访问网上邻居电脑共享的文件夹怎么办 现在许多电脑上装的都是Win系统,Win10无法访问网上邻居电脑共享的文件夹怎么办呢?下面小编为大家介绍下解决的方法吧! 1点击桌面上的“此电脑”图标 ...

  9. 在Windows Server 2008的桌面上显示“我的电脑”“网上邻居”等图标?

    装完windows server2008 r2 x64后发现桌面只有一个“回收站”图标,如何把“我的电脑”“网上邻居”等图标添加到桌面呢?操作步骤: 1. 点击 开始 在搜索中输入 icon 2. 点 ...

  10. windows的网上邻居

    要说以前中学最怕上什么课就是电脑课,要说电脑印象最深的是什么软件就是总摆在桌面又听不懂又点进去什么都没有的“网上邻居”. “网上邻居”指的是同一局域网内在线的的电脑,更简单些就是连在同一路由器中开机的 ...

随机推荐

  1. Flask中本地代理的使用

    本地代理 当请求到来时应用上下文和程序上下文被推入本地栈中,全局变量current_app,request,g,session都可以使用了.以current_app为例,current_app代表的是 ...

  2. 【django-vue】 项目上线 uuid重复问题 内网穿透 支付宝验签 nginx集群 远程连接redis 使用uwsgi启动django

    目录 上节回顾 uuid重复问题 内网穿透 支付宝验签 今日内容 1 上线架构图 2 阿里云购买 3 安装git和其他依赖 4 云服务器安装mysql 5 云服务器安装redis(源码安装) 远程连接 ...

  3. Android RxJava 异常时堆栈信息显示不全(不准确),解决方案都在这里了

    现象 大家好,我是徐公,今天为大家带来的是 RxJava 的一个血案,一行代码 return null 引发的. 前阵子,组内的同事反馈说 RxJava 在 debug 包 crash 了,捕获到的异 ...

  4. 对于 CDN 的多元理解

    这是二狗子为数不多的创业故事. 那时二狗子还是一名高中生,学校是封闭式管理.由于二狗子总忍不住上课吃零食,他便每周一都会背着一麻袋零食来上学. 这上课吃零食行为,不知不觉诱惑到了周围的同学.大家纷纷向 ...

  5. Tomcat--启动慢

    本篇为转载文章 来自:https://www.cnblogs.com/user-sunli/articles/13917035.html 有时启动Tomcat,发现启动很慢,需要几分钟,这个问题值得重 ...

  6. 灵魂拷问std::enable_shared_from_this,揭秘实现原理

    参考博客: std::enable_shared_from_this原理浅析 引言 在C++编程中,使用智能指针是一种安全管理对象生命周期的方式.std::shared_ptr是一种允许多个指针共享对 ...

  7. <vue 基础知识 5、事件监听>

    代码结构 一.     v-on基本使用 1.效果 按钮点击一下数字增加1 2.代码 01-v-on基本使用.html <!DOCTYPE html> <html lang=&quo ...

  8. 《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab

    这是CSAPP的第四个实验,这个实验比较有意思,也比较难.通过这个实验我们可以更加熟悉GDB的使用和机器代码的栈和参数传递机制. @ 目录 实验目的 准备工作 内容简介 代码注入攻击 Level 1 ...

  9. [TSG@Site开发日志3]从C#到Qt,再从Qt到C# 和 Qt的组合开发,浅谈在采集端工控设备开发中不同技术之间选型的利与弊

    [TSG开发日志3]从C#到Qt,再从Qt到C#,浅谈不同技术之间选型的利与弊 当前在South公司的开发历经了几个时代,第一个时代是用C#进行的开发,第二个时代是从C#向Qt逐渐转型,第三个时代是我 ...

  10. P2058

    这道不难的题引发了我不少思考 我第一个版本是用vector嵌套vector写成的,后来发现没必要还存储那些已经超过24h的船,完全可以删除前面的船,因此把外层vector换成了deque. 即用deq ...