Эксперт
   
Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006
Репутация: 7 Всего: 50
|
Ресурсы локальной сети Для получения списка ресурсов локальной сети нужно использовать функции lan manager: WNetOpenEnum - начать перечисление, WNetEnumResource - перечислить ресурсы, WNetCloseEnum - закончить перечисление. 3 вышеописанные функции дают список имен серверов, принтеров, и т. д. Для получения информации о конкретном сервере можно воспользоваться функцией NetServerGetInfo. Также, иногда интересно узнать IP адрес компа - здесь нужен WinSock и его gethostbyname. Пример: Код | //Пример консольной проги, реализующей все вышеописанное: #pragma comment(lib, "netapi32.lib") #pragma comment(lib, "mpr.lib") #pragma comment(lib, "ws2_32.lib")
#include <windows.h> #include <stdio.h> #include <lm.h>
// Максимум ресурсов в container'е #define MAX_NET_RESOURCES (1024)
// Рекурсивная функция, которая, собственно, и пишет всю инфу int ResFunc(NETRESOURCE *pNr, // pNr - NETRESOURCE container'а, где смотреть содержимое int sp // sp - количество пробелов для отступа );
// Удалось ли проинициализировать WinSock BOOL bWSA;
// Дни недели char *szWeekDays[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; // Месяцы char *szMonths[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int main(){ // Для определения IP адресов нужен WinSock // Попытаемся проинициализировать WinSock WORD wVersion = MAKEWORD(1, 1); WSADATA wsaData; DWORD dwRes = WSAStartup(wVersion, &wsaData); bWSA = (dwRes == 0); if(!bWSA){ // Если WinSock не работает, то определение IP будет не доступно :-( printf("WSAStartup() failed with %d, gethostbyname() unavailable\n", dwRes); } // Начнем сканирование с самого верхнего уровня ResFunc(NULL, 0); // Освободим WinSock if(bWSA){ WSACleanup(); } return 0; }
int ResFunc(NETRESOURCE *pNr, int sp){ HANDLE hEnum; DWORD dwRes;
// Начнем перечисление сетевых ресурсов dwRes = WNetOpenEnum(RESOURCE_GLOBALNET, // область видимости - вся сеть RESOURCETYPE_ANY, // тип ресурсов - диски и принтеры 0, // тип ресурсов - подключаемые и содержащие pNr, // начать с pNr &hEnum // передать хендл в hEnum ); if(dwRes!=NO_ERROR){ // ошибка printf("WNetOpenEnum failed with %d\n", dwRes); if(dwRes==ERROR_EXTENDED_ERROR){ DWORD dwError; char szErrorBuff[256], szNameBuff[256]; WNetGetLastError(&dwError, szErrorBuff, 256, szNameBuff, 256); printf("%s [%d]: %s\n", szNameBuff, dwError, szErrorBuff); } return 1; }
NETRESOURCE NetResource[MAX_NET_RESOURCES]; // буффер для хранения информации про ресурсы DWORD dwCount = 0xFFFFFFFF, dwSize = sizeof(NETRESOURCE)*MAX_NET_RESOURCES;
// Перечислим ресурсы в текущем container'е dwRes = WNetEnumResource(hEnum, // хендл на перечисление &dwCount, // количество ресурсов (LPVOID*)&NetResource, // буффер для хранения информации про ресурсы &dwSize );
if(dwRes!=NO_ERROR){ // ошибка printf("WNetEnumResource failed with %d\n", dwRes); if(dwRes==ERROR_EXTENDED_ERROR){ DWORD dwError; char szErrorBuff[256], szNameBuff[256]; WNetGetLastError(&dwError, szErrorBuff, 256, szNameBuff, 256); printf("%s [%d]: %s\n", szNameBuff, dwError, szErrorBuff); } return 2; } // Будем перебирать все ресурсы DWORD dw; for(dw=0; dw<dwCount; dw++){ for(int i=0; i<sp; i++) // Нарисуем отступ // Если ресурс - сервер if(NetResource[dw].dwDisplayType == RESOURCEDISPLAYTYPE_SERVER){ char szIP[256]; if(bWSA){ // Если WinSock доступен, то определим IP адрес char szName[256]; for(int i=0; NetResource[dw].lpRemoteName[i+1]!='\0'; i++){ szName[i]=NetResource[dw].lpRemoteName[i+2]; }
struct hostent *hp = gethostbyname(szName); if(!hp){ strcpy(szIP, "ip=???"); }else{ DWORD dwIP = ((in_addr*)hp->h_addr_list[0])->S_un.S_addr; int a = LOBYTE(LOWORD(dwIP)); int b = HIBYTE(LOWORD(dwIP)); int c = LOBYTE(HIWORD(dwIP)); int d = HIBYTE(HIWORD(dwIP));
sprintf(szIP, "%d.%d.%d.%d", a, b, c, d); } }else{ sprintf(szIP, "ip=???"); }
// Буфферы для информации в текстовом виде char szOS[256]; char szOS_Version[256], szOS_Platform[256], szOS_Soft[256]; // Буффер для информации о сервере SERVER_INFO_101 *pSI101; NetApiBufferAllocate(sizeof(SERVER_INFO_101), (LPVOID*)&pSI101); wchar_t wcName[256]; mbstowcs(wcName, NetResource[dw].lpRemoteName, 256); // Получим информацию о сервере NET_API_STATUS nasRes; nasRes = NetServerGetInfo((char*)&wcName, 101, (UCHAR**)&pSI101 ); if(nasRes!=NERR_Success){ printf("NetServerGetInfo failed with %d\n", nasRes); continue; }
// Версия системы sprintf(szOS_Version, "%d.%d", pSI101->sv101_version_major & MAJOR_VERSION_MASK, pSI101->sv101_version_minor );
// Тип системы switch(pSI101->sv101_platform_id){ case PLATFORM_ID_DOS: strcpy(szOS_Platform, "DOS"); break; case PLATFORM_ID_OS2: strcpy(szOS_Platform, "OS2"); break; case PLATFORM_ID_NT: strcpy(szOS_Platform, "NT"); break; case PLATFORM_ID_OSF: strcpy(szOS_Platform, "OSF"); break; case PLATFORM_ID_VMS: strcpy(szOS_Platform, "VMS"); break; default: strcpy(szOS_Platform, "ost=???"); }
// Сервисы strcpy(szOS_Soft, ""); if(pSI101->sv101_type & SV_TYPE_WORKSTATION) strcat(szOS_Soft, "Wst, "); if(pSI101->sv101_type & SV_TYPE_SERVER) strcat(szOS_Soft, "Serv, "); if(pSI101->sv101_type & SV_TYPE_SQLSERVER) strcat(szOS_Soft, "SQL Serv, "); if(pSI101->sv101_type & SV_TYPE_DOMAIN_CTRL) strcat(szOS_Soft, "PDC, "); if(pSI101->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) strcat(szOS_Soft, "BDC, "); if(pSI101->sv101_type & SV_TYPE_TIME_SOURCE) strcat(szOS_Soft, "TimeSource, "); if(pSI101->sv101_type & SV_TYPE_AFP) strcat(szOS_Soft, "AFP, "); if(pSI101->sv101_type & SV_TYPE_NOVELL) strcat(szOS_Soft, "Novell Serv, "); if(pSI101->sv101_type & SV_TYPE_DOMAIN_MEMBER) strcat(szOS_Soft, "Domain Member, "); if(pSI101->sv101_type & SV_TYPE_PRINTQ_SERVER) strcat(szOS_Soft, "Printer Serv, "); if(pSI101->sv101_type & SV_TYPE_DIALIN_SERVER) strcat(szOS_Soft, "Dial Serv, "); if(pSI101->sv101_type & SV_TYPE_XENIX_SERVER) strcat(szOS_Soft, "Unix Serv, "); if(pSI101->sv101_type & SV_TYPE_NT) strcat(szOS_Soft, "NT Wst/Serv, "); if(pSI101->sv101_type & SV_TYPE_SERVER_NT) strcat(szOS_Soft, "NT non-DC, "); if(pSI101->sv101_type & SV_TYPE_WFW) strcat(szOS_Soft, "WFW, "); if(pSI101->sv101_type & SV_TYPE_SERVER_MFPN) strcat(szOS_Soft, "MFPN, "); if(pSI101->sv101_type & SV_TYPE_SERVER_OSF) strcat(szOS_Soft, "OSF, "); if(pSI101->sv101_type & SV_TYPE_SERVER_VMS) strcat(szOS_Soft, "VMS, "); if(pSI101->sv101_type & SV_TYPE_DFS) strcat(szOS_Soft, "DFS, "); if(pSI101->sv101_type & SV_TYPE_CLUSTER_NT) strcat(szOS_Soft, "NT Cluster, "); if(pSI101->sv101_type & SV_TYPE_DCE) strcat(szOS_Soft, "IBM DSS, "); if(pSI101->sv101_type & SV_TYPE_POTENTIAL_BROWSER) strcat(szOS_Soft, "PBR, "); if(pSI101->sv101_type & SV_TYPE_BACKUP_BROWSER) strcat(szOS_Soft, "BBR, "); if(pSI101->sv101_type & SV_TYPE_MASTER_BROWSER) strcat(szOS_Soft, "MBR, "); if(pSI101->sv101_type & SV_TYPE_DOMAIN_MASTER) strcat(szOS_Soft, "Domain master, "); if(pSI101->sv101_type & SV_TYPE_DOMAIN_ENUM) strcat(szOS_Soft, "Primary domain, "); if(pSI101->sv101_type & SV_TYPE_WINDOWS) strcat(szOS_Soft, "W95, ");
szOS_Soft[strlen(szOS_Soft)-2]='\0';
sprintf(szOS, "%s | %s", szOS_Platform, szOS_Version);
NetApiBufferFree((LPVOID)pSI101);
// Буфферы для хранения информации о времени char szTime[256]; TIME_OF_DAY_INFO *pTODI = NULL;
// Получим время на сервере nasRes = NetRemoteTOD(wcName, (LPBYTE*)&pTODI);
if(nasRes==NERR_Success){ sprintf(szTime, "%02d:%02d:%02d %02d/%s/%02d ", pTODI->tod_hours - pTODI->tod_timezone/60, pTODI->tod_mins, pTODI->tod_secs, pTODI->tod_day, szMonths[pTODI->tod_month-1], pTODI->tod_year, szWeekDays[pTODI->tod_weekday], pTODI->tod_timezone ); }else{ sprintf(szTime, "NetRemoteTOD failed"); }
NetApiBufferFree((LPVOID*)pTODI);
// Напишем то, что удалось узнать DWORD j; printf("%s [%s] [%s]\n", NetResource[dw].lpRemoteName, szIP, szOS);
for(j=0; j < sp + strlen(NetResource[dw].lpRemoteName) + 1; j++) printf(" "); printf("[%s]\n", szOS_Soft); for(j=0; j < sp + strlen(NetResource[dw].lpRemoteName) + 1; j++) printf(" "); printf("[%s]\n", szTime); for(j=0; j < sp + strlen(NetResource[dw].lpRemoteName) + 1; j++) printf(" "); printf("(%s) is ", NetResource[dw].lpComment); }else{ printf("%s (%s) is ", NetResource[dw].lpRemoteName, NetResource[dw].lpComment); } // Напишем тип ресурса switch(NetResource[dw].dwDisplayType){ case RESOURCEDISPLAYTYPE_GENERIC: printf("generic, "); break; case RESOURCEDISPLAYTYPE_DOMAIN: printf("domain, "); break; case RESOURCEDISPLAYTYPE_SERVER: printf("server, "); break; case RESOURCEDISPLAYTYPE_SHARE: printf("share, "); break; case RESOURCEDISPLAYTYPE_FILE: printf("file, "); break; case RESOURCEDISPLAYTYPE_GROUP: printf("group, "); break; case RESOURCEDISPLAYTYPE_NETWORK: printf("network, "); break; case RESOURCEDISPLAYTYPE_ROOT: printf("root, "); break; case RESOURCEDISPLAYTYPE_SHAREADMIN: printf("shareadmin, "); break; case RESOURCEDISPLAYTYPE_DIRECTORY: printf("directory, "); break; case RESOURCEDISPLAYTYPE_TREE: printf("tree, "); break; case RESOURCEDISPLAYTYPE_NDSCONTAINER: printf("nds, "); break; default: printf("rdt=???, "); break; }
// connectable - то, что можно подключить (диск, принтер, ...) if(NetResource[dw].dwUsage & RESOURCEUSAGE_CONNECTABLE){ printf("connectable, "); }
// container - то, что содержит connectable :-) if(NetResource[dw].dwUsage & RESOURCEUSAGE_CONTAINER){ printf("container, "); } // Напишем, чем является ресурс switch(NetResource[dw].dwType){ case RESOURCETYPE_ANY: printf("any"); break; case RESOURCETYPE_DISK: printf("disk"); break; case RESOURCETYPE_PRINT: printf("print"); break; case RESOURCETYPE_RESERVED: printf("reserved"); break; case RESOURCETYPE_UNKNOWN: printf("unknown"); break; default: printf("rt=???"); break; } printf("\n"); // Если ресурс является container'ом, то посмотрим, что в нем есть :-) if(NetResource[dw].dwUsage & RESOURCEUSAGE_CONTAINER){ ResFunc(&NetResource[dw], sp+1); } } // Закроем перечисление WNetCloseEnum(hEnum); return 0; }
|
Добавлено @ 11:32Рекурсивный обходчик сети. Пример: Код | void printNet(LPNETRESOURCE lpNetResource){ NETRESOURCE nr; NETRESOURCE nrs[1024]; DWORD sz = sizeof(nrs); DWORD req=-1; HANDLE hnd; DWORD rc=WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, lpNetResource, &hnd ); if(rc != NO_ERROR){ return; } WNetEnumResource( hnd, (DWORD*)&req, nrs, &sz ); for(int i=0;i<(int)req;++i){ printf("%s\n",nrs[i].lpRemoteName); printNet(nrs+i); } WNetCloseEnum(hnd); }
int main(){ printNet(0); }
|
Добавлено @ 11:35Список компьютеров, ресурсов рабочей группы/домена The following code sample demonstrates how to list all servers that are visible in the primary domain with a call to the NetServerEnum function. The sample calls NetServerEnum, specifying information level 101 ( SERVER_INFO_101). The sample code loops through the entries and prints the retrieved data. If the server is a domain controller, it identifies the server as either a primary domain controller (PDC) or a backup domain controller (BDC). The sample also prints the total number of entries available and a hint about the number of entries actually enumerated, warning the user if all entries were not enumerated. Finally, the sample frees the memory allocated for the information buffer. Пример: Код | #ifndef UNICODE #define UNICODE #endif
#include <stdio.h> #include <assert.h> #include <windows.h> #include <lm.h>
int wmain(int argc, wchar_t *argv[]) { LPSERVER_INFO_101 pBuf = NULL; LPSERVER_INFO_101 pTmpBuf; DWORD dwLevel = 101; DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH; DWORD dwEntriesRead = 0; DWORD dwTotalEntries = 0; DWORD dwTotalCount = 0; DWORD dwServerType = SV_TYPE_SERVER; // all servers DWORD dwResumeHandle = 0; NET_API_STATUS nStatus; LPTSTR pszServerName = NULL; DWORD i;
if (argc > 2) { fwprintf(stderr, L"Usage: %s [\\\\ServerName]\n", argv[0]); exit(1); } // The server is not the default local computer. // if (argc == 2) pszServerName = argv[1]; // // Call the NetServerEnum function to retrieve information // for all servers, specifying information level 101. // nStatus = NetServerEnum(pszServerName, dwLevel, (LPBYTE *) &pBuf, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, dwServerType, NULL, &dwResumeHandle); // // If the call succeeds, // if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) { if ((pTmpBuf = pBuf) != NULL) { // // Loop through the entries and // print the data for all server types. // for (i = 0; i < dwEntriesRead; i++) { assert(pTmpBuf != NULL);
if (pTmpBuf == NULL) { fprintf(stderr, "An access violation has occurred\n"); break; }
printf("\tPlatform: %d\n", pTmpBuf->sv101_platform_id); wprintf(L"\tName: %s\n", pTmpBuf->sv101_name); printf("\tVersion: %d.%d\n", pTmpBuf->sv101_version_major, pTmpBuf->sv101_version_minor); printf("\tType: %d", pTmpBuf->sv101_type); // // Check to see if the server is a domain controller; // if so, identify it as a PDC or a BDC. // if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_CTRL) wprintf(L" (PDC)"); else if (pTmpBuf->sv101_type & SV_TYPE_DOMAIN_BAKCTRL) wprintf(L" (BDC)"); printf("\n"); // // Also print the comment associated with the server. // wprintf(L"\tComment: %s\n\n", pTmpBuf->sv101_comment);
pTmpBuf++; dwTotalCount++; } // Display a warning if all available entries were // not enumerated, print the number actually // enumerated, and the total number available.
if (nStatus == ERROR_MORE_DATA) { fprintf(stderr, "\nMore entries available!!!\n"); fprintf(stderr, "Total entries: %d", dwTotalEntries); }
printf("\nEntries enumerated: %d\n", dwTotalCount); } } else fprintf(stderr, "A system error has occurred: %d\n", nStatus); // // Free the allocated buffer. // if (pBuf != NULL) NetApiBufferFree(pBuf);
return 0; }
|
Добавлено через 5 минут и 27 секунд Это сообщение отредактировал(а) Alca - 23.3.2009, 11:36
|