I thought I'd post this since it might be useful to others -- it looks up and lists all resources on a Windows LAN (dunno what'll happen if you have a Linux or other PC attached!), showing sizes of shared disks and computer names/IP addresses (the IP lookup is Flype's code).
I've no idea how well it'll work with a router/switch, but it works on my setup, which is a server that has two PCs going directly into it.
I've made it as fault-proof as possible, but it just shows how to retrieve this information and prints it to the Debug Output window.
I think it should work with Windows 2000 or above. Don't be surprised if it appears to pause for long periods, as Windows can take its time in finding network resources! I've never understood why this is...
(The only minor thing bugging me at the moment is that it prints the public IP for the client running the program, rather than the LAN IP, though it lists the other PCs on the LAN with their local IPs.)
Code: Select all
; TURN ON DEBUGGER TO SEE THE OUTPUT!
Procedure.s GetIP (ComputerName.s)
; By Flype! (Just reformatted to my preference.)
If ComputerName
If WSAStartup_ ((1<<8|1), wsa.WSADATA) = #NOERROR
*host.HOSTENT = gethostbyname_ (ComputerName)
WSACleanup_ ()
If *host
ProcedureReturn PeekS (inet_ntoa_ (PeekL (PeekL (*host\h_addr_list))))
EndIf
EndIf
EndIf
EndProcedure
; -----------------------------------------------------------------------------
; Enumerate LAN resources...
; -----------------------------------------------------------------------------
Procedure ShowNetworkInfo (*resource.NETRESOURCE = #Null, indent = 0)
; Indent string for debugging recursive function...
in$ = LSet ("", 8 * indent, "-")
If indent > 0
in$ = in$ + "> "
EndIf
chunk = 262144 ; 4 times the M$-suggested amount (in 1992-1996)...
openresult = WNetOpenEnum_ (#RESOURCE_GLOBALNET, #RESOURCETYPE_ANY, 0, *resource, @enum)
Select openresult
Case #NO_ERROR
size = chunk
; Try to enumerate resources. In the unlikely event that the buffer is too small,
; add another 'chunk' of memory until OK...
; Probably won't be relevant except for massive business networks anyway...
Repeat
count = $FFFFFFFF
*mem = ReAllocateMemory (*mem, size)
enumresult = WNetEnumResource_ (enum, @count, *mem, @size)
If enumresult = #ERROR_MORE_DATA
size = size + chunk
EndIf
Until enumresult <> #ERROR_MORE_DATA
Select enumresult
Case #NO_ERROR
; ---------------------------------------------------------
; All OK, enumerate this resource...
; ---------------------------------------------------------
For loop = 0 To count - 1
*temp.NETRESOURCE = *mem + (loop * SizeOf (NETRESOURCE))
iterate = #False ; Used at end of loop to enumerate this resource...
; -------------------------------------------------------------
; Read available strings for resource...
; -------------------------------------------------------------
If *temp\lpLocalName <> #Null
Debug in$ + "Local resource name: " + PeekS (*temp\lpLocalName)
EndIf
If *temp\lpRemoteName <> #Null
name$ = PeekS (*temp\lpRemoteName)
If Left (name$, 2) = "\\"
name$ = Mid (name$, 3)
EndIf
info$ = in$ + "Remote resource name: " + name$
If *temp\dwDisplayType = #RESOURCEDISPLAYTYPE_SERVER
ip$ = GetIP (name$)
If ip$ <> ""
info$ = info$ + " (" + ip$ + ")"
EndIf
EndIf
Debug info$
EndIf
If *temp\lpProvider <> #Null
Debug in$ + "Network resource provider: " + PeekS (*temp\lpProvider)
EndIf
If *temp\lpComment <> #Null
comment$ = PeekS (*temp\lpComment)
If comment$ = ""
comment$ = "[No comment set]"
EndIf
Debug in$ + "Comment: " + comment$
EndIf
; -------------------------------------------------------------
; Get scope of resource...
; -------------------------------------------------------------
Select *temp\dwScope
Case #RESOURCE_CONNECTED
Debug in$ + "Scope: Currently connected resource"
Case #RESOURCE_GLOBALNET
Debug in$ + "Scope: Network resource"
; NOTE: dwUsage is only valid for #RESOURCE_GLOBALNET...
If *temp\dwUsage And #RESOURCEUSAGE_CONNECTABLE
Debug in$ + "Usage: Connectable resource"
EndIf
If *temp\dwUsage And #RESOURCEUSAGE_CONTAINER
Debug in$ + "Usage: Container resource"
If *temp\dwType <> #RESOURCETYPE_DISK
iterate = #True ; Can iterate through this resource...
EndIf
EndIf
Case #RESOURCE_REMEMBERED
Debug in$ + "Scope: Persistent resource"
EndSelect
; -------------------------------------------------------------
; Get type of resource...
; -------------------------------------------------------------
Select *temp\dwType
Case #RESOURCETYPE_ANY
Debug in$ + "Share type: Undefined (probably a container)"
Case #RESOURCETYPE_DISK
Debug in$ + "Share type: Disk"
; Get disk size/space...
If *temp\lpRemoteName <> #Null
SetErrorMode_ (#SEM_FAILCRITICALERRORS)
If GetDiskFreeSpaceEx_ (*temp\lpRemoteName, @ignored.q, @totalbytes.q, @freebytes.q)
total = totalbytes / 1024 / 1024 / 1024
free = freebytes / 1024 / 1024 / 1024
Debug in$ + "Share size: " + StrU (total, #PB_Quad) + " GB"
Debug in$ + "Free space: " + StrU (free, #PB_Quad) + " GB"
Else
Debug "Couldn't read disk size/space"
EndIf
SetErrorMode_ (0)
EndIf
Case #RESOURCETYPE_PRINT
Debug in$ + "Share type: Printer"
EndSelect
; -------------------------------------------------------------
; How the resource is displayed in a network browser GUI...
; -------------------------------------------------------------
Select *temp\dwDisplayType
Case #RESOURCEDISPLAYTYPE_DOMAIN
Debug in$ + "Displayed as: Domain"
Case #RESOURCEDISPLAYTYPE_GENERIC
Debug in$ + "Displayed as: Generic"
Case #RESOURCEDISPLAYTYPE_SERVER
Debug in$ + "Displayed as: Server"
Case #RESOURCEDISPLAYTYPE_SHARE
Debug in$ + "Displayed as: Share"
Default
Debug in$ + "Displayed as: Unknown (probably root node)"
EndSelect
Debug ""
; -------------------------------------------------------------
; Try to enumerate this resource (recursive function call)...
; -------------------------------------------------------------
If iterate
indent = indent + 1
ShowNetworkInfo (*temp, indent)
indent = indent - 1
EndIf
Next
Case #ERROR_NO_MORE_ITEMS
; ---------------------------------------------------------
; Can't enumerate within this resource...
; ---------------------------------------------------------
Debug in$ + "No items to enumerate in this resource"
Debug ""
EndSelect
FreeMemory (*mem)
WNetCloseEnum_ (enum)
Case #ERROR_NOT_CONTAINER
Debug in$ + "The specified resource is not a container"
Debug ""
Case #ERROR_INVALID_PARAMETER
Debug in$ + "WNetOpenEnum received an invalid dwScope or dwType parameter"
Debug ""
Case #ERROR_NO_NETWORK
Debug in$ + "No network connected to resource being enumerated"
Debug ""
Case #ERROR_EXTENDED_ERROR
Debug in$ + "Extended error information available:"
; Untested -- haven't run into this and don't know how to test! Should work, though...
*errorbuffer = AllocateMemory (1024)
*providerbuffer = AllocateMemory (1024)
If WNetGetLastError_ (@neterror, *errorbuffer, 1024, *providerbuffer, 1024) = #NO_ERROR
Debug PeekS (*providerbuffer) + " reports: " + PeekS (*errorbuffer)
EndIf
Debug ""
Default
Debug in$ + "Unexpected error on opening resource. (Eg. May not support enumeration.)"
; This is (ironically) expected sometimes! Eg. "NetDrive Network" doesn't
; support enumeration and reports "The request is not supported" when
; GetLastError () is called...
Debug ""
EndSelect
EndProcedure
Debug ""
Debug "Scanning LAN -- this may take some time!"
Debug ""
ShowNetworkInfo ()