Enumerate shared folders on Windows with low privileges
Using C++ (VS2008) I need to be able to enumerate all shared folders on the current machine and get or construct the local and remote names.
We've been using NetShareEnum
for this fairly successfully, but have hit a problem where we need to run with a user account with low 开发者_StackOverflow社区privileges.
To get the local path using NetShareEnum
we need to retrieve at least SHARE_INFO_2
structures - but that requires "Administrator, Power User, Print Operator, or Server Operator group membership".
I've been trying to use WNetOpenEnum
and WNetEnumResource
instead but I don't seem to be getting the local name back for that for shares either. AFAICS it only enumerates the shares from an external perspective.
So I'd either like help on where I'm going wrong with WNetEnumResource
, or a suggestion as to another way of doing this. Any suggestions are much appreciated.
It sounds like you're specifying RESOURCE_GLOBALNET
for the scope, but it's hard to tell what's wrong without seeing your code.
It's hard to help without knowing what you tried and what you got back. For example, what local name are you expecting and what is getting returned? Did you try NetShareEnum with SHARE_INFO_503?
If you have an idea what the local path would be, you can brute-force it by testing: (TODO: make everything Unicode)
// Helper function to make a name unique.
std::string computername()
{
static std::string name = []() {
WCHAR buf[MAX_COMPUTERNAME_LENGTH];
DWORD len = MAX_COMPUTERNAME_LENGTH;
GetComputerNameEx(ComputerNameNetBIOS, buf, &len);
return std::string(buf, buf + len);
}();
return name;
}
int main()
{
std::string dir = "C:\\FindThisShare\\";
// First, create marker
std::string testfile = computername() + " 038D2B86-7459-417B-9179-90CEECC6EC9D.txt";
std::ofstream test(dir + testfile);
test << "This directory holds files from " << computername()
<< std::endl;
test.close();
// Next, find the UNC path holding it.
BYTE* buf;
DWORD numEntries;
NetShareEnum(nullptr, 1, &buf, MAX_PREFERRED_LENGTH, &numEntries,
&numEntries, nullptr);
auto data = reinterpret_cast<SHARE_INFO_1*>(buf);
std::string retval;
for (int i = 0; i != numEntries; ++i)
{
auto const& entry = data[i];
std::wstring tmp(entry.shi1_netname);
std::string share(tmp.begin(), tmp.end());
std::string uncdir = "\\\\" + computername() + "\\" + share + "\\";
if (PathFileExistsA((uncdir + testfile).c_str()))
{
printf("Exists");
}
}
remove((dir + testfile).c_str());
NetApiBufferFree(buf);
}
精彩评论