tatane Posted April 3, 2015 Share Posted April 3, 2015 (edited) Hi, I was looking for a multi threading Ping and found this post () from Fr0zt. His Ping in assembly is impressive (adapted from the trancexx's and monoceres work ?do=embed' frameborder='0' data-embedContent>)'>?do=embed' frameborder='0' data-embedContent>). expandcollapse popup#include <Memory.au3> #include <Array.au3> Opt('MustDeclareVars', 1) HotKeySet("{ESC}", "_Exit") Global Const $DONT_FRAGMENT = 2, $IP_SUCCESS = 0, $IP_DEST_NET_UNREACHABLE = 11002, $IP_DEST_HOST_UNREACHABLE = 11003, $IP_DEST_PROT_UNREACHABLE = 11004, $IP_DEST_PORT_UNREACHABLE = 11005, _ $IP_NO_RESOURCES = 11006, $IP_HW_ERROR = 11008, $IP_PACKET_TOO_BIG = 11009, $IP_REQ_TIMED_OUT = 11010, $IP_BAD_REQ = 11011, $IP_BAD_ROUTE = 11012, _ $IP_TTL_EXPIRED_TRANSIT = 11013, $IP_TTL_EXPIRED_REASSEM = 11014, $IP_PARAM_PROBLEM = 11015, $IP_SOURCE_QUENCH = 11016, $IP_BAD_DESTINATION =11018, _ $IP_GENERAL_FAILURE = 11050, $NO_STATUS = 10000 ;We will use 10000 as the no status indicator since 0 meens successful reply Local $hPointers = DllStructCreate("ptr IcmpCloseHandle;ptr IcmpSendEcho;ptr IcmpCreateFile;ptr ExitThread") Global $hkernel32Dll = DllOpen("kernel32.dll") Global $hKrn = _WinAPI_GetModuleHandle("kernel32.dll") DllStructSetData($hPointers,"ExitThread",GetProcAddress($hKrn, "ExitThread")) Global $hICMPDll = LibLoad("ICMP.dll");Iphlpapi.dll") DllStructSetData($hPointers,"IcmpCloseHandle",GetProcAddress($hICMPDll, "IcmpCloseHandle")) DllStructSetData($hPointers,"IcmpSendEcho",GetProcAddress($hICMPDll, "IcmpSendEcho")) DllStructSetData($hPointers,"IcmpCreateFile",GetProcAddress($hICMPDll, "IcmpCreateFile")) TCPStartup() ;This is required, not only to do DNS lookup, but also for WSAStartup() Global $pings[1] = [0] ;This array will hold all echo reply data in a struct. ConsoleWrite("Press esc any time to stop" & @CRLF) pingThreaded("www.google.ca") pingThreaded("www.asus.com.tw") Local $pingdata = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Local $timeout = 150 Local $ttl = 255 pingThreaded("www.autoitscript.com", $timeout, $pingdata, $ttl, $DONT_FRAGMENT) While 1 _managePings() WEnd ;Function pingThreaded ;$ip_addr will accept valid DNS Name or Normal IP address. ;Timouts only really work when an IP isn't responding. Thats important to remember because if you think you can timeout an IP which has latent responces, you can't! Func pingThreaded($ip_addr, $timeout=5000, $data="x", $ttl=255, $flags=0) Local $hexIP = encodeIP($ip_addr) If $hexIP == 0 Then Return 0 Local $pingID = _addPing($ip_addr) If IsNumber($ttl) = 0 Or Number($ttl) > 255 Then $ttl = 255 If IsNumber($timeout) = 0 Or Number($timeout) > 5000 Then $timeout = 5000 If StringLen($data) > 256 Then $data = StringTrimRight($data,StringLen($data) - 256) If IsNumber($flags) = 0 Or Number($flags) > 2 Then $flags = 2 DllStructSetData($pings[$pingID],"datasize",StringLen($data)) ;We may wish to report the data size later ;Props to trancexx Local $CodeBuffer = DllStructCreate("byte[696]"); Code=154, Data=256, Echo reply Struct + ICMP_OPTIONS Struct = 286 Local $RemoteCode = _MemVirtualAlloc(0, DllStructGetSize($CodeBuffer), $MEM_COMMIT, $PAGE_EXECUTE_READWRITE) DllStructSetData($CodeBuffer, 1, _ "0x" & _ ;Original Assembly started at 401000 "E889000000" & _ ;Call 0040108E <IcmpCreateFile> "A3" & SwapEndian($RemoteCode + 410) & _ ;mov dword ptr [00403010], eax <hIcmp = IcmpCreateFile Handle> "C605" & SwapEndian($RemoteCode + 418) & Hex($ttl,2) & _ ;mov byte ptr [00403024], xx <TTL> "C605" & SwapEndian($RemoteCode + 419) & "00" & _ ;mov byte ptr [00403025], 00 <TOS> "C605" & SwapEndian($RemoteCode + 420) & Hex($flags,2) & _ ;mov byte ptr [00403026], 02 <Flags, 0x02=DF Bit Set> "C605" & SwapEndian($RemoteCode + 421) & "00" & _ ;mov byte ptr [00403027], 00 "C705" & SwapEndian($RemoteCode + 422) & "00000000" & _ ;mov dword ptr [00403028], 00000000 "68" & SwapEndian(Dec(Hex($timeout,4))) & _ ;push 0000xxxx <Timeout> "681E010000" & _ ;push 0000011E <Size of Echo reply Struct + ICMP_OPTIONS Struct> "68" & SwapEndian($RemoteCode + 426) & _ ;push 0040302C <icmpReply> "68" & SwapEndian($RemoteCode + 418) & _ ;push 00403024 <icmpOptions> "6A" & Hex(StringLen($data),2) & _ ;push 000000xx <Data Size> "68" & SwapEndian($RemoteCode + 154) & _ ;push 00403000 <Data> "68" & SwapEndian(Dec($hexIP)) & _ ;push <Hex(IP ADDRESS)> "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr [00403010] <hIcmp> "E839000000" & _ ;Call 00401094 <IcmpSendEcho> "A1" & SwapEndian($RemoteCode + 434) & _ ;mov eax, dword ptr [00403034] <Get the ms responce time from icmpReply.RoundTripTime> "A3" & SwapEndian(DllStructGetPtr($pings[$pingID],"reply")) & _ ;mov dword ptr [0040301C], eax <Store the ms responce time> "A1" & SwapEndian($RemoteCode + 430) & _ ;mov eax, dword ptr [00403030] <Get the status from icmpReply.Status> "A3" & SwapEndian(DllStructGetPtr($pings[$pingID],"status")) & _ ;mov dword ptr [00403020], eax <Store the status> "FF35" & SwapEndian($RemoteCode + 410) & _ ;push dword ptr [00403010] <hIcmp> "E80E000000" & _ ;Call 00401088 <IcmpCloseHandle> "6A00" & _ ;push 00000000 "E801000000" & _ ;Call 00401082 <ExitThread> "CC" & _ ;int 03 "FF25" & SwapEndian(DllStructGetPtr($hPointers,"ExitThread")) & _ ;JMP dword ptr <kernel32.ExitThread> "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpCloseHandle")) & _ ;JMP dword ptr <ICMP.IcmpCloseHandle> "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpCreateFile")) & _ ;JMP dword ptr <ICMP.IcmpCreateFile> "FF25" & SwapEndian(DllStructGetPtr($hPointers,"IcmpSendEcho"))& _ ;JMP dword ptr <ICMP.IcmpSendEcho> SwapEndian(StringToBinary($data)) _ ;This is our ping Data, Max 256 bytes of space here. ) _MemMoveMemory(DllStructGetPtr($CodeBuffer), $RemoteCode, DllStructGetSize($CodeBuffer)) Local $aCall = DllCall($hkernel32Dll, "ptr", "CreateThread", "ptr", 0, "int", 0, "ptr", $RemoteCode, "ptr", 0, "int", 0, "dword*", 0) Return $aCall[0] EndFunc ;Function _addPing is just for array management of the $pings[] array. Func _addPing($ip_addr) $pings[0] = UBound($pings) ReDim $pings[$pings[0]+1] $pings[$pings[0]] = DllStructCreate("char ip[" & StringLen($ip_addr) & "];ulong reply;ulong status;int datasize");You could add a timeout struct here DllStructSetData($pings[$pings[0]],"ip",$ip_addr) DllStructSetData($pings[$pings[0]],"status",$NO_STATUS) Return $pings[0] EndFunc ;Function _removePing is just for array management of the $pings[] array. Func _removePing($pingID) If $pingID > $pings[0] Then Return ;Ensure our ID is valid $pings[$pingID] = 0 ;Free the DLLStruct _ArrayDelete($pings,$pingID) $pings[0] -= 1 EndFunc ;Function _managePings() ;This is where the reply's get sorted out, and actions taken Func _managePings() Local $pingID, $status $pingID = 1 While $pingID <= $pings[0] $status = DllStructGetData($pings[$pingID],"status") If $status <> $NO_STATUS Then Switch $status Case $IP_SUCCESS If DllStructGetData($pings[$pingID],"reply") = 0 Then ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " replied in <1ms" & @CRLF) Else ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " replied in " & DllStructGetData($pings[$pingID],"reply") & "ms" & @CRLF) EndIf Case $IP_REQ_TIMED_OUT ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " timed-out" & @CRLF) Case $IP_DEST_NET_UNREACHABLE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination network was unreachable." & @CRLF) Case $IP_DEST_HOST_UNREACHABLE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination host was unreachable." & @CRLF) Case $IP_DEST_PROT_UNREACHABLE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination protocol was unreachable." & @CRLF) Case $IP_DEST_PORT_UNREACHABLE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The destination port was unreachable." & @CRLF) Case $IP_NO_RESOURCES ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " Insufficient IP resources were available." & @CRLF) Case $IP_HW_ERROR ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A hardware error occurred." & @CRLF) Case $IP_PACKET_TOO_BIG ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The packet was too big." & @CRLF) Case $IP_BAD_REQ ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad request." & @CRLF) Case $IP_BAD_ROUTE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad route." & @CRLF) Case $IP_TTL_EXPIRED_TRANSIT ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The time to live (TTL) expired in transit." & @CRLF) Case $IP_TTL_EXPIRED_REASSEM ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " The time to live expired during fragment reassembly." & @CRLF) Case $IP_PARAM_PROBLEM ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A parameter problem." & @CRLF) Case $IP_SOURCE_QUENCH ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " Datagrams are arriving too fast to be processed and datagrams may have been discarded." & @CRLF) Case $IP_BAD_DESTINATION ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A bad destination." & @CRLF) Case $IP_GENERAL_FAILURE ConsoleWrite("Ping with " & DllStructGetData($pings[$pingID],"datasize") & " byte(s) to " & DllStructGetData($pings[$pingID],"ip") & " A general failure. This error can be returned for some malformed ICMP packets or lost network connection." & @CRLF) EndSwitch _removePing($pingID) EndIf ; You may wish to include a feature which can timeout manually here. Just remember if you do that, do not destroy the dllstruct for the ping ; because likelly the ping thread will still write to it when it's done. You will have to wait for that to happen before you destroy it. $pingID += 1 WEnd EndFunc Func encodeIP($ip_addr) Local $ip_addr_temp = $ip_addr If Not _isIP($ip_addr) Then $ip_addr = TCPNameToIP($ip_addr) If Not _isIP($ip_addr) Then ConsoleWrite($ip_addr_temp & " is not a valid IP Address. If you supplied a hostname ensure DNS is available." & @CRLF) Return 0 EndIf Return getHexIP($ip_addr) EndFunc Func getHexIP($ip_addr) Return Hex(_getIPOctet($ip_addr,4),2) & Hex(_getIPOctet($ip_addr,3),2) & Hex(_getIPOctet($ip_addr,2),2) & Hex(_getIPOctet($ip_addr,1),2) EndFunc Func LibLoad($lpLibFileName) Local $LibHandle = DllCall($hkernel32Dll, "int", "LoadLibraryA", "str", $lpLibFileName) Return $LibHandle[0] EndFunc Func LibFree($DllHandle) Local $LibFreed = DllCall($hkernel32Dll, "int", "FreeLibrary", "int", $DllHandle) return $LibFreed[0] EndFunc Func GetProcAddress( $hModule, $lpProcName) Local $ProcessAddy = DllCall($hkernel32Dll,"int","GetProcAddress","int",$hModule,"str",$lpProcName) Return $ProcessAddy[0] EndFunc Func SwapEndian($hex) ;trancexx Return Hex(Binary($hex)) EndFunc Func _getIPOctet($ip_addr,$octet=1) Switch $octet Case 1 Return Int(StringMid($ip_addr,1,StringInStr($ip_addr,"."))) Case 4 Return Int(StringMid($ip_addr,StringInStr($ip_addr,".",0,3)+1)) Case Else Return Int(StringMid($ip_addr,StringInStr($ip_addr,".",0,$octet - 1)+1,StringInStr($ip_addr,".",0,$octet)+1)) EndSwitch EndFunc Func _isIP($text) Return StringRegExp($text, "(((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9][0-9])|([1-9]?[0-9]))") EndFunc Func _Exit() TCPShutdown() LibFree($hICMPDll) DllClose($hkernel32Dll) Exit EndFunc I tryed it with HOSTNAMES (instead of ip addresses) from my network. But when the computer is offline, the script is pretty slow. It comes from the TCPNameToIP() function and, I suppose, the getaddrinfo Windows function behind. It seems there is no timeout parameter to pass to this function. So my question is : Is there a way to add a timeout ? Edited April 3, 2015 by tatane Link to comment Share on other sites More sharing options...
Kyan Posted April 3, 2015 Share Posted April 3, 2015 why don't you use local ip addr? those hosts names are specified in your DNS? Or you used hosts file? Heroes, there is no such thing One day I'll discover what IE.au3 has of special for so many users using it.C'mon there's InetRead and WinHTTP, way better Link to comment Share on other sites More sharing options...
tatane Posted April 7, 2015 Author Share Posted April 7, 2015 (edited) I can't use local ip address because they are distributed by dhcp. So I'm using a host file. It seems GetAddrInfoEx function get a timeout parameter : https://msdn.microsoft.com/en-us/library/windows/desktop/ms738518%28v=vs.85%29.aspx But I don't know how to implement this in Autoit... Edited April 7, 2015 by tatane Link to comment Share on other sites More sharing options...
funkey Posted April 11, 2015 Share Posted April 11, 2015 I can't use local ip address because they are distributed by dhcp. So I'm using a host file. It seems GetAddrInfoEx function get a timeout parameter : https://msdn.microsoft.com/en-us/library/windows/desktop/ms738518%28v=vs.85%29.aspx But I don't know how to implement this in Autoit... Since the timeout parameter of GetAddrInfoEx() is only supported on Windows8 and 2012, I cannot test this function. But I hope this works. expandcollapse popup#include <Array.au3> Global Const $AF_UNSPEC = 0 Global Const $AF_INET = 2 Global Const $AF_INET6 = 23 Global Const $IPPROTO_TCP = 6 Global Const $IPPROTO_UDP = 17 Global Const $SOCK_STREAM = 1 Global Const $SOCK_DGRAM = 2 Global Const $NS_DNS = 12 Global Const $tagTimeVal = "long tv_sec;long tv_usec" Global Const $tagAddrInfoEx = "int ai_flags;int ai_family;int ai_socktype;int ai_protocol;UINT_PTR ai_addrlen;ptr ai_canonname;ptr ai_addr;ptr ai_blob;UINT_PTR ai_bloblen;ptr ai_provider;ptr ai_next" Global Const $tagSockAddr_In = "short sin_family;USHORT sin_port;ULONG sin_addr;char sin_zero[8]" Global Const $tagSockAddr_In6 = "short sin6_family;USHORT sin6_port;ULONG sin6_flowinfo;byte sin6_addr[16];ULONG sin6_scope_id" TCPStartup() Global $Timeout = 1000 ; 1 second timeout Global $aIP = _GetAddrInfoEx("..localmachine", $Timeout, $AF_INET) If @error Then MsgBox(0, "GetAddrInfoEx", "Error: " & @extended) Else _ArrayDisplay($aIP) EndIf TCPShutdown() ;https://msdn.microsoft.com/en-us/library/windows/desktop/ms738518%28v=vs.85%29.aspx Func _GetAddrInfoEx($sNodeName = "..localmachine", $iTimeout = 0, $AddressFamily = $AF_UNSPEC, $SockType = $SOCK_STREAM, $IpProtocol = $IPPROTO_TCP, $NameSpace = $NS_DNS) ;funkey 2015.04.11 Local $pResult, $tAddrInfoEx, $sIP, $tName, $tTimeout, $pTimeout If $iTimeout <> 0 Then $tTimeout = DllStructCreate($tagTimeVal) $pTimeout = DllStructGetPtr($tTimeout) DllStructSetData($tTimeout, "tv_sec", Floor($iTimeout / 1000)) DllStructSetData($tTimeout, "tv_usec", ($iTimeout - DllStructGetData($tTimeout, "tv_sec") * 1000) * 1000) Else $pTimeout = 0 EndIf Local $hints = DllStructCreate($tagAddrInfoEx) DllStructSetData($hints, "ai_family", $AddressFamily) DllStructSetData($hints, "ai_socktype", $SockType) DllStructSetData($hints, "ai_protocol", $IpProtocol) Local $aRet = DllCall("ws2_32.dll", "int", "GetAddrInfoExW", "wstr", $sNodeName, "ptr", 0, "DWORD", $NameSpace, "ptr", 0, _ "struct*", $hints, "ptr*", 0, "ptr", $pTimeout, "ptr", 0, "ptr", 0, "ptr", 0) If $aRet[0] <> 0 Then Return SetError(1, $aRet[0], 0) $pResult = $aRet[6] Do $tAddrInfoEx = DllStructCreate($tagAddrInfoEx, $pResult) Switch DllStructGetData($tAddrInfoEx, "ai_family") Case $AF_INET If $AddressFamily = $AF_UNSPEC Or $AddressFamily = $AF_INET Then $tName = DllStructCreate($tagSockAddr_In, DllStructGetData($tAddrInfoEx, "ai_addr")) $sIP &= _InetNtop(DllStructGetPtr($tName, "sin_addr"), $AF_INET) & ";" EndIf Case $AF_INET6 If $AddressFamily = $AF_UNSPEC Or $AddressFamily = $AF_INET6 Then $tName = DllStructCreate($tagSockAddr_In6, DllStructGetData($tAddrInfoEx, "ai_addr")) $sIP &= _InetNtop(DllStructGetPtr($tName, "sin6_addr"), $AF_INET6) & ";" EndIf EndSwitch $pResult = DllStructGetData($tAddrInfoEx, "ai_next") Until $pResult = 0 _FreeAddrInfoEx($aRet[6]) Return StringSplit(StringTrimRight($sIP, 1), ";", 2) EndFunc ;==>_GetAddrInfoEx Func _FreeAddrInfoEx($pAddrInfoEx) DllCall("ws2_32.dll", "none", "FreeAddrInfoEx", "ptr", $pAddrInfoEx) EndFunc ;==>_FreeAddrInfoEx Func _InetNtop($tIn_Addr, $iFamily = $AF_INET) ;IPv4 and IPv6 --> Vista and above Local $tBuffer = DllStructCreate("wchar[46]") ;16 for IPv4, 46 for IPv6 Local $aRet = DllCall("ws2_32.dll", "wstr", "InetNtopW", "int", $iFamily, "struct*", $tIn_Addr, "struct*", $tBuffer, "int", DllStructGetSize($tBuffer) / 2) Return DllStructGetData($tBuffer, 1) EndFunc ;==>_InetNtop Kyan 1 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
tatane Posted April 13, 2015 Author Share Posted April 13, 2015 (edited) Thanks a lot for your time. I tested your script on Win 7 Pro (I don't use Win 8) and unfortunatly I've got an error : 10022. The error is the same with online or offline/wrongHost computer. The Windows Socket error is : Invalid argument. Some invalid argument was supplied (for example, specifying an invalid level to the setsockopt function). In some instances, it also refers to the current state of the socketâfor instance, calling accept on a socket that is not listening. EDIT : I tried to replace $NS_DNS by $NS_NETBT (13) but error is the same. Is there a way in Autoit to implement this UNICODE macro ? timeout [in, optional] An optional parameter indicating the time, in milliseconds, to wait for a response from the namespace provider before aborting the call. This parameter is only supported when the UNICODE or _UNICODE macro has been defined in the sources before calling the GetAddrInfoEx function. Otherwise, this parameter is currently reserved and must be set to NULL since a timeout option is not supported. Edited April 13, 2015 by tatane Link to comment Share on other sites More sharing options...
funkey Posted April 13, 2015 Share Posted April 13, 2015 I told you that the timeout only works on Win8. I use the Unicode version of the function (GetAddrInfoExW). Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
tatane Posted April 13, 2015 Author Share Posted April 13, 2015 I see. So there is no way to make it work on Win7. I guess I will use WSAAsyncGetHostByName instead. Again, thanks you very much. Link to comment Share on other sites More sharing options...
Solution funkey Posted April 13, 2015 Solution Share Posted April 13, 2015 Hello. Here is the WSAAsyncGetHostByName() function to use with timeout. I tried to make the function as easy as possible. Hope this now works for you. expandcollapse popupGlobal Const $AF_INET = 2 Global Const $tagHostent = "ptr h_name;ptr h_aliases;short h_addrtype;short h_length;ptr h_addr_list" Global $WSAAsyncGetHostByName_lParam = 0 TCPStartup() Local $sAddress = "..localmachine" Global $Timeout = 1000 ; 1 second timeout Global $sIP = _WSAAsyncGetHostByName_Timeout($sAddress, $Timeout) If @error Then MsgBox(0, $sAddress, "Error: " & @error) Else MsgBox(0, $sAddress, "IP address: " & $sIP) EndIf TCPShutdown() Func _WSAAsyncGetHostByName_Timeout($sNodeName = "..localmachine", $iTimeout = 0, $hGui = Default, $wMsg = Default) ;funkey 2015.04.13 Local Const $WM_USER = 0x400 Local Const $MAXGETHOSTSTRUCT = 1024 Local $bGuiDelete = False If $wMsg = Default Then $wMsg = $WM_USER + 0x99 If $hGui = Default Then $hGui = GUICreate("_WSAAsyncGetHostByName_Timeout") $bGuiDelete = True EndIf GUIRegisterMsg($wMsg, "_WSAAsyncGetHostByName_Callback") Local $tBuf = DllStructCreate("char buffer[" & $MAXGETHOSTSTRUCT & "]") Local $aRet = DllCall("ws2_32.dll", "HANDLE", "WSAAsyncGetHostByName", "HWND", $hGui, "UINT", $wMsg, "str", $sNodeName, "struct*", $tBuf, "int", $MAXGETHOSTSTRUCT) If $aRet[0] == 0 Then Return SetError(1, 0, 0) Local $IsInTime = False Local $iTimeStart = TimerInit() While 1 If $WSAAsyncGetHostByName_lParam <> 0 Then $IsInTime = True ExitLoop EndIf Sleep(10) If $iTimeout > 0 And TimerDiff($iTimeStart) > $iTimeout Then ExitLoop WEnd If Not $IsInTime Then DllCall("ws2_32.dll", "int", "WSACancelAsyncRequest", "HANDLE", $aRet[0]) $WSAAsyncGetHostByName_lParam = 0 Return SetError(2, 0, 0) EndIf Local $WSAGETASYNCERROR = BitShift($WSAAsyncGetHostByName_lParam, 16) Local $WSAGETASYNCBUFLEN = BitAND($WSAAsyncGetHostByName_lParam, 0xFFFF) $WSAAsyncGetHostByName_lParam = 0 If $WSAGETASYNCERROR Then Return SetError($WSAGETASYNCERROR, $WSAGETASYNCBUFLEN, 0) Local $sIP, $iIP, $tIPs Local $tHostent = DllStructCreate($tagHostent, DllStructGetPtr($tBuf)) Local $ptrList = DllStructGetData($tHostent, "h_addr_list") If $ptrList = 0 Then Return SetError(3, 0, 0) Local $tAddressList = DllStructCreate("ptr", $ptrList) Local $firstAddr = DllStructGetData($tAddressList, 1) If DllStructGetData($tHostent, "h_addrtype") = $AF_INET Then $tIPs = DllStructCreate("UINT", DllStructGetData($tAddressList, 1)) $iIP = DllStructGetData($tIPs, 1) If $iIP = 0 Then Return SetError(4, 0, 0) $sIP = _inet_ntoa($iIP) EndIf Return SetError(0, 0, $sIP) EndFunc ;==>_WSAAsyncGetHostByName_Timeout Func _WSAAsyncGetHostByName_Callback($hWnd, $iMsgID, $wParam, $lParam) $WSAAsyncGetHostByName_lParam = $lParam EndFunc ;==>_WSAAsyncGetHostByName_Callback Func _inet_ntoa($In_Addr) ;only IPv4 (deprecated) --> use _inet_ntop() instead Local $aRet = DllCall("ws2_32.dll", "str", "inet_ntoa", "long", $In_Addr) Return $aRet[0] EndFunc ;==>_inet_ntoa argumentum 1 Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
argumentum Posted April 13, 2015 Share Posted April 13, 2015 Hello. Here is the WSAAsyncGetHostByName() function to use with timeout. I tried to make the function as easy as possible. Hope this now works for you. working beautifully on w7x64 and wXPx32 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting. Link to comment Share on other sites More sharing options...
tatane Posted April 14, 2015 Author Share Posted April 14, 2015 Thank you very much, it works perfectly. Link to comment Share on other sites More sharing options...
funkey Posted April 14, 2015 Share Posted April 14, 2015 You are welcome. Glad to hear this. Programming today is a race between software engineers striving tobuild bigger and better idiot-proof programs, and the Universetrying to produce bigger and better idiots.So far, the Universe is winning. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now