You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win32 C++调用NetShareEnum无结果,如何排查与修复?

问题:Win32 C++枚举Windows共享资源失败,NetShareEnum返回成功但无结果

我用Win32 C++编写枚举Windows共享资源的函数时遇到问题:net share命令可正常显示包括默认共享在内的所有共享,但我的代码返回ERROR_SUCCESS却没有任何结果,尝试_SHARE_INFO_1、_SHARE_INFO_2、_SHARE_INFO_501等结构体均无效。

通过IDA Free分析net.exe,发现其调用NetShareEnum()时通过NetWkstaGetInfo()获取服务器名称,Ghidra显示相关导入项存在,未发现GetComputerNameEx等其他相关导入。我疑惑是否需先执行登录操作,或是杀毒软件阻止了相关调用?

以下是我的代码,调试时totalEntries和entriesRead均为0:

std::list<String> FileSystem::listShares() {
    std::list<String> shares;
    _SHARE_INFO_502* buffer, p;
    LPWKSTA_INFO_100 pBuf = NULL;
    NET_API_STATUS nStatus;

    // Retrieve workstation information at level 100
    nStatus = NetWkstaGetInfo(NULL, 100, (LPBYTE*)&pBuf);
    if (nStatus != NERR_Success) {
        Util::printError(L"NetWkstaGetInfo");
    }
    LPWSTR serverName = pBuf->wki100_computername;
    DWORD entriesRead;
    DWORD totalEntries;
    DWORD resumeHandle;
    DWORD result = NetShareEnum(serverName, 502, (LPBYTE*)&buffer, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resumeHandle);
    std::wstringstream ss;
    if (result == 0) {
        for (DWORD i = 0; i < entriesRead; i++) {
            p = buffer[i];
            ss << L"Share Name: " << p.shi502_netname << L"\n\tShare Type: " << p.shi502_type << L"\n\tRemark: " << p.shi502_remark << std::endl;
            shares.push_back(ss.str());
            ss.str(L"");
        }
    }
    else {
        Util::printError(L"NetShareEnum");
    }
    return shares;
}

问题分析与修复

1. 核心问题:resumeHandle未初始化

NetShareEnum的resume_handle参数必须初始化为0,否则函数会因未定义行为无法正确枚举共享。你的代码仅声明了该变量但未赋值,这是导致返回成功却无条目读取的关键原因。

2. 次要问题:未处理NetWkstaGetInfo失败的情况

如果NetWkstaGetInfo调用失败,pBuf会是NULL,后续访问pBuf->wki100_computername会直接触发崩溃,必须在错误发生后终止后续逻辑。

3. 内存泄漏风险

调用NetShareEnum和NetWkstaGetInfo后,未使用NetApiBufferFree释放系统分配的内存,会造成内存泄漏。

修复后的代码

#include <list>
#include <sstream>
#include <windows.h>
#include <lmshare.h>

#pragma comment(lib, "netapi32.lib")

std::list<std::wstring> FileSystem::listShares() {
    std::list<std::wstring> shares;
    _SHARE_INFO_502* buffer = nullptr;
    LPWKSTA_INFO_100 pBuf = nullptr;
    NET_API_STATUS nStatus;

    // 获取工作站信息
    nStatus = NetWkstaGetInfo(nullptr, 100, reinterpret_cast<LPBYTE*>(&pBuf));
    if (nStatus != NERR_Success) {
        Util::printError(L"NetWkstaGetInfo");
        return shares;
    }

    DWORD entriesRead = 0;
    DWORD totalEntries = 0;
    DWORD resumeHandle = 0; // 必须初始化为0
    nStatus = NetShareEnum(pBuf->wki100_computername, 502, reinterpret_cast<LPBYTE*>(&buffer), 
                           MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resumeHandle);

    std::wstringstream ss;
    if (nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) {
        // 处理分段枚举的情况
        do {
            if (buffer != nullptr && entriesRead > 0) {
                for (DWORD i = 0; i < entriesRead; ++i) {
                    _SHARE_INFO_502& share = buffer[i];
                    ss << L"Share Name: " << share.shi502_netname 
                       << L"\n\tShare Type: " << share.shi502_type 
                       << L"\n\tRemark: " << (share.shi502_remark ? share.shi502_remark : L"") 
                       << std::endl;
                    shares.push_back(ss.str());
                    ss.str(L"");
                }
                NetApiBufferFree(buffer);
                buffer = nullptr;
            }
            // 还有更多数据则继续枚举
            if (nStatus == ERROR_MORE_DATA) {
                nStatus = NetShareEnum(pBuf->wki100_computername, 502, reinterpret_cast<LPBYTE*>(&buffer), 
                                       MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resumeHandle);
            } else {
                break;
            }
        } while (nStatus == ERROR_MORE_DATA);
    } else {
        Util::printError(L"NetShareEnum");
    }

    // 释放所有分配的内存
    if (pBuf != nullptr) NetApiBufferFree(pBuf);
    if (buffer != nullptr) NetApiBufferFree(buffer);

    return shares;
}

额外说明

  • 无需额外登录:本地枚举共享时,普通用户权限即可枚举大部分共享,默认共享(如C$)需要管理员权限,若看不到默认共享可尝试以管理员身份运行程序。
  • 杀毒软件干扰概率低:net share能正常运行说明系统API可用,问题基本出在代码本身而非外部拦截。

内容的提问来源于stack exchange,提问作者seanlum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 11:00:03