NetServerEnum() Program Example
The NetServerEnum() function lists all servers of the specified type that are visible in a domain. For example, an application can call NetServerEnum() to list all domain controllers only or all SQL servers only. You can combine bit masks to list several types. For example, a value of 0x00000003 combines the bit masks for SV_TYPE_WORKSTATION (0x00000001) and SV_TYPE_SERVER (0x00000002). No special group membership is required to successfully execute the NetServerEnum() function. If you specify the value SV_TYPE_LOCAL_LIST_ONLY, the NetServerEnum() function returns the list of servers that the browser maintains internally. This has meaning only on the master browser (or on a computer that has been the master browser in the past). The master browser is the computer that currently has rights to determine which computers can be servers or workstations on the network.
If there are no servers found that match the types specified in the servertype parameter, the NetServerEnum() function returns the bufptr parameter as NULL and DWORD values pointed to by the entriesread and totalentries parameters are set to zero. The NetServerEnum() function depends on the browser service being installed and running. If no browser servers are found, then NetServerEnum fails with ERROR_NO_BROWSER_SERVERS_FOUND. If you are programming for Active Directory, you may be able to call certain Active Directory Service Interface (ADSI) methods to achieve the same function you can achieve by calling the network management server functions.
The following code sample demonstrates how to list all servers that are visible in a domain with a call to the NetServerEnum() function. The sample calls NetServerEnum, specifying information level 101 (SERVER_INFO_101). If any servers are found, 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.
Create a new empty Win32 console application project. Give the project name and change the project location is needed.

Then, add the source file and give it a suitable name.

Then, add the following source code.
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, netapi32.lib)
#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;
// all servers
DWORD dwServerType = SV_TYPE_SERVER;
DWORD dwResumeHandle = 0;
NET_API_STATUS nStatus;
LPWSTR pszServerName = NULL;
LPWSTR pszDomainName = NULL;
DWORD i;
if (argc > 2)
{
fwprintf_s(stderr, LUsage: %s [DomainName]\n, argv[0]);
wprintf(LExample: %s Yahoo\n, argv[0]);
wprintf(LDefault to local will be used if domain name not supplied\n, argv[0]);
exit(1);
}
// The request is not for the primary domain.
if (argc == 2)
pszDomainName = 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,
pszDomainName,
&dwResumeHandle);
// If the call succeeds,
if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
{
wprintf(LNetServerEnum() is OK!\n);
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)
{
fwprintf_s(stderr, LAn access violation has occurred\n);
break;
}
wprintf(L\tPlatform: %d\n, pTmpBuf->sv101_platform_id);
wprintf(L\tName: %s\n, pTmpBuf->sv101_name);
wprintf(L\tVersion: %d.%d\n,pTmpBuf->sv101_version_major,pTmpBuf->sv101_version_minor);
wprintf(L\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));
wprintf(L\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)
{
fwprintf_s(stderr, L\nMore entries available!!!\n);
fwprintf_s(stderr, LTotal entries: %d, dwTotalEntries);
}
wprintf(L\nEntries enumerated: %d\n, dwTotalCount);
}
else
{
wprintf(LNo servers were found\n);
wprintf(LThe buffer (bufptr) returned was NULL\n);
wprintf(L Entries read: %d\n, dwEntriesRead);
wprintf(L Total entries: %d\n, dwEntriesRead);
}
}
else
fwprintf_s(stderr, LNetServerEnum() failed with error: %d\n, nStatus);
// Free the allocated buffer.
if (pBuf != NULL)
NetApiBufferFree(pBuf);
return 0;
}
Build and run the project. The following screenshot is a sample output.
