Hi all,
I have a 2-PC network: my PC (Windows 2000) and my brother's (Windows 98SE). This code, when run on Windows 2000, correctly lists the computers and their IP addresses on the network. When I run it on my brother's '98 PC, though, it fails to get the information. I have checked all of the Win32 API commands I'm using and they should all work on '9x, but something's not quite right :/
One thing I have found is that if you change 'For entry = 1 To entries', in the section that lists the computers, to 'For entry = 0 To entries', you at least get partial information for one of the PCs.
Can anyone tell why this isn't working when run on '98? (:·O
Code: Select all
; -----------------------------------------------------------------------------
; List IP addresses of local network PCs -- james @ hi-toro.com
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; * * * * * ONLY WORKS WHEN RUN ON WINDOWS 2000...! :( * * * * *
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; SAMPLE OUTPUT:
; -----------------------------------------------------------------------------
; Local network resources...
; "FRANK" on "Microsoft Windows Network" ; A Windows98SE PC...
; Host name: FRANK
; IP address: 192.168.0.210
; "SCORPIO" on "Microsoft Windows Network" ; This Windows 2000 PC...
; Host name: scorpio
; IP address: 192.168.0.1
; Press ENTER...
; -----------------------------------------------------------------------------
; Structure not defined in PB (needed for gethostbyname function)...
; -----------------------------------------------------------------------------
Structure HOSTENT
h_name.l
h_aliases.l
h_addrtype.l
h_length.l
h_addr_list.l
EndStructure
; -----------------------------------------------------------------------------
; Some constants not defined in PB...
; -----------------------------------------------------------------------------
#NO_ERROR = 0
#ERROR_NO_ERROR = 0
#ERROR_BAD_DEVICE = 1200
#ERROR_CONNECTION_UNAVAIL = 1201
#ERROR_EXTENDED_ERROR = 1208
#ERROR_MORE_DATA = 234
#ERROR_NOT_SUPPORTED = 50
#ERROR_NO_NET_OR_BAD_PATH = 1203
#ERROR_NO_NETWORK = 1222
#ERROR_NOT_CONNECTED = 2250
; -----------------------------------------------------------------------------
; Some error procedures...
; -----------------------------------------------------------------------------
; Used to set last error to 0 on startup (NEEDED!)...
Procedure InitErrors (default)
SetLastError_ (default)
EndProcedure
; Retrieves last reported error in program...
Procedure GetLastError ()
error = GetLastError_ ()
If error
AllocateMemory (0, 255)
FormatMessage_ (#FORMAT_MESSAGE_FROM_SYSTEM, #NULL, error, 0, MemoryID (), 255, #NULL)
e$ = PeekS (MemoryID ())
FreeMemory (0)
MessageRequester (title$, e$, #MB_ICONWARNING)
EndIf
EndProcedure
; Retrieves last network error in program...
Procedure GetNetError ()
error$ = Space (256)
provider$ = Space (256)
WNetGetLastError_ (code, error$, 256, provider$, 256)
If error$ = Space (256)
error$ = "Weird; there's no reported network error! Why am I here?!"
EndIf
MessageRequester ("Network error!", "A network error has occurred!" + Chr (10) + Chr (10) + error$, #MB_ICONWARNING)
EndProcedure
; -----------------------------------------------------------------------------
; MAIN PROGRAM...
; -----------------------------------------------------------------------------
; Reset the error system...
InitErrors (0)
; WSAStartup is needed before calling gethostbyname_ () further down...
; Version 1.1 of Windows Sockets needed...
high.b = 1
low.b = 1
DefType.w wsaversion
PokeB (@wsaversion, high) ; Gotta poke major version number into low byte...
PokeB (@wsaversion + 1, low) ; ... and minor version number into high byte
; WSAStartup returns 0 (no errors) if successful...
If WSAStartup_ (wsaversion, wsa.WSAData)
MessageRequester ("Network error", "WSA startup failed!" + Chr (10) + Chr (10) + error$, #MB_ICONWARNING)
End
EndIf
; Get a handle for retrieving a list of computers on local network...
error = WNetOpenEnum_ (#RESOURCE_CONTEXT, #RESOURCETYPE_DISK, 0, #NULL, @nethandle)
Select error
Case #ERROR_NO_ERROR
; ---------------------------------------------------------------------
; START OF NETWORK PC LIST CODE...
; ---------------------------------------------------------------------
; No error, so let's see what we have here...
OpenConsole ()
PrintN ("")
PrintN ("Local network resources...")
PrintN ("")
; Default to a large number of PCs (thanks to M$, you MUST do it like this!)...
check = 1024
entries = -1
size = SizeOf (NETRESOURCE) * check
Dim network.NETRESOURCE (check)
; Read list of PCs into network.NETRESOURCE array...
reserror = WNetEnumResource_ (nethandle, @entries, @network (), @size)
If reserror = #NO_ERROR
; Read array for however many we found (WNetEnumResource pokes the number into 'entries')...
For entry = 1 To entries
Select network (entry)\dwScope
; Dunno what this means exactly...
Case #RESOURCE_CONNECTED
PrintN ("Resource connected")
; But this is the one we want...
Case #RESOURCE_GLOBALNET
; Get network PC name and the type of network (eg. Microsoft Windows Network)...
computer$ = PeekS (network (entry)\lpRemoteName)
networktype$ = PeekS (network (entry)\lpProvider)
; Strip off backslash prefix (eg. "\\YOURCOMPUTERNAME")...
While Left (computer$, 1) = "\"
computer$ = Right (computer$, Len (computer$) - 1)
Wend
PrintN (Chr (34) + computer$ + Chr (34) + " on " + Chr (34) + networktype$ + Chr (34))
; Get pointer to the host data for the network PC...
*host.HOSTENT = gethostbyname_ (computer$)
If *host #NULL
; Here we print the name and the IP address (hooray for inet_ntoa!)...
PrintN ("")
PrintN (" Host name: " + PeekS (*host\h_name))
PrintN (" IP address: " + PeekS (inet_ntoa_ (PeekL (*host\h_addr_list))))
Else
GetLastError ()
EndIf
; Dunno about this either...
Case #RESOURCE_REMEMBERED
PrintN ("Resource remembered")
EndSelect
PrintN ("")
Next
EndIf
PrintN ("Press ENTER...")
Input ()
CloseConsole ()
; We MUST free the handle we got for listing the network PCs...
WNetCloseEnum_ (nethandle)
; ... and we also MUST clean up the WSA thing!
WSACleanup_ ()
; ---------------------------------------------------------------------
; END OF NETWORK PC LIST CODE...
; ---------------------------------------------------------------------
; This stuff is the remainder of the first Select/EndSelect after WNetOpenEnum...
Case #ERROR_NO_NETWORK
MessageRequester ("Network error!", "There's no network here!", #MB_ICONWARNING)
End
Case #ERROR_EXTENDED_ERROR
GetNetError ()
End
Default
GetLastError ()
EndSelect
End
--
See ya,
James L Boyd.
http://www.hi-toro.com/
--