Buffer limit on server listings.

Eric eric.glass at comcast.net
Tue Mar 30 00:32:36 GMT 2004


>>> "NetServerEnum3 turned up in a network trace between an XP client and a
>>> W2K or W2K3 PDC and appears to solve the 64K server list limit
>>> problem..."
>>>
>>> > I have also never heard of a NetrServerEnum() RPC call, and googling
>>> turns
>>> > up nothing.  Can you point me at any documentation?
>>>
>>> I just made the name up. I just mean the NetServerEnum RPC.
>>
>> Thing is, I'm not aware of an RPC that does this.
>
> Sure there is. Just look up NetServerEnum on MSDN.


Actually, this is fairly interesting.  There *doesn't* appear to be a 
precise NetServerEnum RPC for this API call; BrowserrServerEnum is (as I 
understand it) an RPC from the Browser service, similar in function to 
NetServerEnum but not identical.  Over the wire, Windows XP still uses 
the RAP calls to implement the NetServerEnum API call.  Basically, the 
NetServerEnum2 RAP is used to get the first set of servers, and 
NetServerEnum3 is used as a set of "tacked on" calls to get the 
remainder in the event that NetServerEnum2 indicates more data is available.

The reason this is interesting is that the NetServerEnum function has a 
real old bug, in which the "resume_handle" parameter always returns 0, 
causing an infinite loop if you actually try to use it as intended 
(i.e., as the handle for the next set of results when the result = 
ERROR_MORE_DATA):

http://support.microsoft.com/support/kb/articles/q136/4/37.asp

There is an undocumented API, NetServerEnumEx, which addresses this:

http://www.activevb.de/rubriken/apikatalog/deklarationen/netserverenumex.html

This takes the name of the last server in the previous return list as a 
parameter, returning the next chunk of names; which is pretty much 
exactly what the NetServerEnum3 RAP call does.

When I do a NetServerEnum API call for all servers on WinXP, I get 
(over-the-wire):


1) A NetServerEnum2 call with a receive buffer length of 14724, which 
gets the first set of servers and returns ERROR_MORE_DATA (234).

2) A repeat of the NetServerEnum2 with a receive buffer length of 65535, 
which gets the same initial set of servers (only with some additional 
entries at the end, due to the bigger return buffer).  Also returns 
ERROR_MORE_DATA.

3) A NetServerEnum3 call, passing the last server in the return list 
from the previous NetServerEnum2.  This gets the next chunk of servers 
and returns ERROR_MORE_DATA.

4) A series of additional NetServerEnum3 calls, each passing the last 
server in the return list from the previous call.  This is repeated 
while the return code is ERROR_MORE_DATA (i.e., until all servers have 
been retrieved).


I'm not sure why the initial NetServerEnum2 call is done twice, or why 
the first call uses a smaller buffer; this could be some backward 
compatibility issue.  It would appear that at some point NetServerEnumEx 
  (along with the NetServerEnum3) was possibly intended to replace 
NetServerEnum; but for whatever reason, they used the NetServerEnum API, 
deprecated the resume_handle parameter, and implemented the whole 
shebang over-the-wire as a (somewhat bizarre) conversation of 
NetServerEnum2s and NetServerEnum3s.


Eric




More information about the samba-technical mailing list