#include #include #pragma comment (lib, "mpr") using namespace Upp; class NetworkInfo { struct Node : NETRESOURCE { bool loaded; int parent; void Copy(); Node(); ~Node(); }; Array net; public: String GetName(int node); String GetPath(int node); int GetParent(int node) { return net[node].parent; } void Connect(int node); Vector Enum(int parent_node = 0); NetworkInfo(); }; static void sCopy(LPSTR& x) { LPSTR s = x; if(s) { int n = strlen(s) + 1; x = new char[n]; memcpy(x, s, n); } } void NetworkInfo::Node::Copy() { sCopy(lpProvider); sCopy(lpRemoteName); sCopy(lpLocalName); sCopy(lpComment); } NetworkInfo::Node::Node() { lpProvider = NULL; lpRemoteName = NULL; lpLocalName = NULL; lpComment = NULL; } NetworkInfo::Node::~Node() { delete[] lpProvider; delete[] lpRemoteName; delete[] lpLocalName; delete[] lpComment; } NetworkInfo::NetworkInfo() { Node& n = net.Add(); memset(&n, 0, sizeof(Node)); n.parent = -1; } String DosInitCaps(const char *name) { for(const char *s = name; *s; s++) if(IsLetter(*s) && IsLower(*s)) return name; return InitCaps(name); } String NetworkInfo::GetName(int node) { Node& n = net[node]; String name; const char *s = n.lpRemoteName; if(s) { if(s[0] == '\\' && s[1] == '\\') name = DosInitCaps(GetFileName(s)); else name = s; } if(n.lpComment && *n.lpComment) if(name.GetCount()) return String().Cat() << n.lpComment << " (" << name << ")"; else return n.lpComment; return name; } String NetworkInfo::GetPath(int node) { if(node == 0 || (net[node].dwUsage & RESOURCEUSAGE_CONTAINER)) return Null; return net[node].lpRemoteName; } void NetworkInfo::Connect(int node) { } Vector NetworkInfo::Enum(int node) { Node& pn = net[node]; HANDLE hEnum; if(!pn.loaded) { Connect(node); if(::WNetOpenEnum(node ? RESOURCE_GLOBALNET : RESOURCE_CONTEXT, RESOURCETYPE_DISK, 0, node ? &pn : NULL, &hEnum) == 0) { DWORD cEntries = -1, cbBuffer = 0x4000; Buffer lpnr(cbBuffer); while(::WNetEnumResource(hEnum, &cEntries, lpnr, &cbBuffer) == 0) { for(int i = 0; i < (int)cEntries; i++) { Node& n = net.Add(); *(NETRESOURCE *)&n = lpnr[i]; n.Copy(); n.parent = node; n.loaded = !(n.dwUsage & RESOURCEUSAGE_CONTAINER); } } ::WNetCloseEnum(hEnum); } } Vector r; for(int i = 1; i < net.GetCount(); i++) if(net[i].parent == node) r.Add(i); return r; } NetworkInfo nwk; void EnumNetworkInfo(int node) { Vector n = nwk.Enum(node); for(int i = 0; i < n.GetCount(); i++) { DUMP(nwk.GetName(n[i])); DUMP(nwk.GetPath(n[i])); EnumNetworkInfo(n[i]); } } CONSOLE_APP_MAIN { EnumNetworkInfo(0); }