Search code examples
c++windowswinapinetapi32

NetShareEnum giving no results


I've been working on a function to enumerate shares in Windows using Win32 C++ and hit a snag.

net share shows all the shares with the default shares and that is good. But for some reason with the below code, the program gives no shares back as a result. I tried using _SHARE_INFO_1, _SHARE_INFO_2, and _SHARE_INFO_501.

In IDA Free, I see net.exe calls NetShareEnum() and it gets the servername I think from NetWkstaGetInfo(). Ghidra says the imports are there, and it doesn't look like there are any other imports to things like GetComputerNameEx etc.

Anyway, I'm wondering if I have to call a log in, or if maybe my AV is preventing me or something?

Here is the code. The function completes with ERROR_SUCCESS. In debug, totalEntries and entriesRead are zero after the function call.

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;
}

What am I doing wrong, and how do I fix it?


Solution

  • As @Luke mentioned in a comment, you have Undefined Behavior because you are not initializing resumeHandle correctly, so the results of NetShareEnum() are unpredictable.

    Per the NetShareEnum() documentation:

    [in, out] resume_handle

    Pointer to a value that contains a resume handle which is used to continue an existing share search. The handle should be zero on the first call and left unchanged for subsequent calls. If resume_handle is NULL, then no resume handle is stored.

    It is an input AND output parameter, so the input value is important, but you are passing in an indeterminate input value.


    Also, you have Undefined Behavior if NetWkstaGetInfo() fails, as you would be dereferencing an invalid pointer when reading pBuf->wki100_computername. And you are leaking its buffer if it succeeds:

    [out] bufptr

    Pointer to the buffer that receives the data. The format of this data depends on the value of the level parameter. This buffer is allocated by the system and must be freed using the NetApiBufferFree function. For more information, see Network Management Function Buffers and Network Management Function Buffer Lengths.

    You are also leaking the NetShareEnum() buffer, too:

    [out] bufptr

    Pointer to the buffer that receives the data. The format of this data depends on the value of the level parameter.

    This buffer is allocated by the system and must be freed using the NetApiBufferFree function. Note that you must free the buffer even if the function fails with ERROR_MORE_DATA.