MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как адаптировать код под поиск устройств в сети?"
Answer 962395
С данным кодом есть несколько проблем:
Если вас интересуют компьютеры, а не общие каталоги, вам и не надо раскрывать контейнеры, достаточно перечислить элементы на основном уровне вложенности.
Для компьютеров в качестве имени нужно брать не lpLocalName, а lpRemoteName; локальное имя для них все равно будет NULL.
Закрывать дескриптор надо WNetCloseEnum, а не CloseHandle
Ну, а чтобы получить IP-адреса, необходимо добавить разрешение имен. Если исправить ошибки в вашем коде и добавить его, получится такой код:
#include <stdlib.h> #include <stdio.h> #include <iostream> #include <WS2tcpip.h> #include <Windows.h> #pragma comment( lib, "Mpr.lib" ) #pragma comment( lib, "Ws2_32.lib") std::wstring ResolveAddr(WCHAR* addr) { ADDRINFOW *result = NULL; ADDRINFOW hints; LPSOCKADDR sockaddr_ip; wchar_t ipstringbuffer[46]; DWORD ipbufferlength; DWORD res; int iRetval; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; res = GetAddrInfoW(addr, nullptr, &hints, &result); if (res != 0) { wprintf(L"GetAddrInfoW failed with error: %d\n", res); return std::wstring(L""); } if (result->ai_family != AF_INET) { wprintf(L"Error: Unsupported address\n", res); return std::wstring(L""); } sockaddr_ip = result->ai_addr; ipbufferlength = 46; iRetval = WSAAddressToString(sockaddr_ip, (DWORD)result->ai_addrlen, NULL, ipstringbuffer, &ipbufferlength); if (iRetval) { wprintf(L"WSAAddressToString failed with %u\n", WSAGetLastError()); return std::wstring(L""); } return std::wstring(ipstringbuffer); } BOOL WINAPI EnumResources(LPNETRESOURCE lpNR = nullptr) { HANDLE hNetEnum; DWORD dwResultOpen = WNetOpenEnumW(RESOURCE_CONTEXT, NULL, 0, lpNR, &hNetEnum); if (dwResultOpen != NO_ERROR) return FALSE; constexpr DWORD numOfResources = 2048; DWORD count = -1; DWORD cbBuffer = numOfResources * sizeof(NETRESOURCE); DWORD dwResultEnum = 0; LPNETRESOURCE lpNRlocal = new NETRESOURCE[numOfResources]; WCHAR* pwc; do { dwResultEnum = WNetEnumResourceW(hNetEnum, &count, lpNRlocal, &cbBuffer); if (dwResultEnum == NO_ERROR) { for (int i = 0; i < count; ++i) { if (lpNRlocal[i].lpRemoteName == nullptr) continue; std::wcout << lpNRlocal[i].lpRemoteName << L": "; pwc = lpNRlocal[i].lpRemoteName; if (wcslen(pwc) > 2) { if(pwc[0]=='\\' && pwc[1]=='\\') pwc = lpNRlocal[i].lpRemoteName + 2; } std::wcout << ResolveAddr(pwc).c_str() << std::endl; } } else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { std::wcout << L"WNetEnumResourceW error: "<< dwResultEnum << std::endl; } } while (dwResultEnum != ERROR_NO_MORE_ITEMS); delete[] lpNRlocal; WNetCloseEnum(hNetEnum); return TRUE; } int main() { WSADATA wsaData; int iResult; iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (iResult != 0) { wprintf(L"WSAStartup failed: %d\n", iResult); return 1; } EnumResources(); getchar(); }
Так как данный код завязан на сетевое обнаружение (которое использует в том числе широковещательные запросы протоколов NetBIOS/WS-Discovery/UPnP/SSDP в зависимости от версии и конфигурации Windows), насколько быстро он будет работать, и будет ли работать вообще, зависит от многих факторов. Если вы хотите более надежный способ получения списка компьютеров для доменных сетей, смотрите в сторону ADSI.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.