j0kky

Winsock UDF

2 posts in this topic

#1 ·  Posted (edited)

Hi guys,

some time ago I tried to deal with client\server application using native winsock functions, but I encountered some difficult because their limitations, so I decided to write a new UDF based on winsock library.

Some functions are simply wrappers of native function, but some other are completely renewed and there are a lot of improvements.

Check it out! Each function has a detailed description and I attached 5 simple example script :D

; #INDEX# =======================================================================================================================
; Title .........: Winsock
; AutoIt Version : 3.3.14.2
; Language ......: English
; Description ...: Functions that assist with Winsock library management.
; Author(s) .....: j0kky
; ===============================================================================================================================

; #CONSTANTS# ===================================================================================================================
Global Const $TCP_DATA_EOT = 2
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
; _TCPStartup
; _TCPListen
; _TCPAccept
; _TCPRecv
; _TCPConnect
; _TCPSend
; _TCPNameToIP
; _TCPCloseSocket
; _TCPShutdown
; _GetIps
; _UDPStartup
; _UDPBind
; _UDPSendTo
; _UDPRecvFrom
; _UDPCloseSocket
; _UDPShutdown
; ===============================================================================================================================

; #WRAPPER# =====================================================================================================================
Func _TCPStartup()
    $iResult = TCPStartup()
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPStartup

; #WRAPPER# =====================================================================================================================
Func _TCPListen($iIPAddr, $iPort, $iMaxPendingConnection = 0)
    If Not $iMaxPendingConnection Then
        $iResult = TCPListen($iIPAddr, $iPort)
    Else
        $iResult = TCPListen($iIPAddr, $iPort, $iMaxPendingConnection)
    EndIf
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPListen

; #FUNCTION# ====================================================================================================================
; Name...........: _TCPAccept
; Description ...: Permits an incoming connection attempt on a socket.
; Syntax.........: _TCPAccept($iMainsocket)
; Parameters ....: $iMainsocket - The main socket identifier (SocketID) as returned by _TCPListen function.
; Return values .: On success it returns an array:
;                  |[0] - The connected socket identifier.
;                  |[1] - The external address of the client
;                  |[2] - The external port which the client are communicating on
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter (not used in this function)
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: accept:      https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _TCPAccept($iMainsocket)
    $iMainsocket = Number($iMainsocket)
    If $iMainsocket < 0 Then Return SetError(-4, 0, -1) ; invalid parameter

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL

    Local $bError = 0, $nCode = 0, $hSock = 0
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    If Not $bError Then
        $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $iMainsocket, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
    EndIf

    If Not $bError Then
        $tSockAddr = DllStructCreate($tagSockAddr)

        $aRet = DllCall($hWs2, "uint", "accept", "uint", $iMainsocket, "ptr", DllStructGetPtr($tSockAddr), "int*", DllStructGetSize($tSockAddr))
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = 4294967295) Or ($aRet[0] = -1) Then ;INVALID_SOCKET
            $bError = 1
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $bError = -1
            ElseIf ($aRet[0] = 0) Or ($aRet[0] = 10035) Then ;WSAEWOULDBLOCK
                $nCode = -10 ;internal function value, it means no error
            EndIf
        Else
            $hSock = $aRet[0]
            $aRet = DllCall($hWs2, "ptr", "inet_ntoa", "ulong", DllStructGetData($tSockAddr, "S_addr"))
            If @error Then
                $bError = -1
            ElseIf $aRet[0] = Null Then
                $bError = 1
            Else
                $sIPAddr = DllStructGetData(DllStructCreate("char[15]", $aRet[0]), 1)
                $aRet = DllCall($hWs2, "ushort", "ntohs", "ushort", DllStructGetData($tSockAddr, "sin_port"))
                If @error Then
                    $bError = -1
                Else
                    $nPort = $aRet[0]
                    Local $aResult[3] = [$hSock, $sIPAddr, $nPort]
                EndIf
            EndIf
        EndIf
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
        If $hSock Then TCPCloseSocket($hSock)
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        If $nCode = -10 Then $nCode = 0
        $nReturn = -1
        If $hSock Then TCPCloseSocket($hSock)
    Else
        $nReturn = $aResult
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_TCPAccept

; #FUNCTION# ====================================================================================================================
; Name...........: _TCPRecv
; Description ...: Receives data from a connected socket.
; Syntax.........: _TCPRecv($iMainsocket, $iMaxLen, $iFlag = 0)
; Parameters ....: $iMainsocket - The array as returned by _TCPAccept
;                                 or the connected socket identifier (SocketID) as returned by _TCPConnect.
;                  $iMaxLen - max # of characters to receive (usually 2048).
;                  $iFlag - values can be added together
;                  |$TCP_DATA_DEFAULT (0) - Text data. [Default]
;                  |$TCP_DATA_BINARY (1) - Binary data.
;                  |$TCP_DATA_EOT (2) - Returns data received and
;                                       set @error to -6 when it reaches the End of Text ASCII character (Chr(3))
; Return values .: On success it returns the binary/string sent by the connected socket.
;                  On failure it returns "" and sets the @error or @extended flag to non-zero:
;                  @error values:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
;                  @extended values:
;                  |1 - connection closed
;                  |2 - End of Text reached
; Author ........: j0kky
; Modified ......: 1.0.0
; Remarks .......: If Unicode strings need to be transmitted they must be encoded/decoded with StringToBinary()/BinaryToString().
;                  $iFlag = 2 must be set in couple with _TCPSend
;                  You must check for both @error and @extended, @extended could be set with @error set to zero
; Links .........: recv:        https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _TCPRecv($iMainsocket, $iMaxLen, $iFlag = 0)
    If IsArray($iMainsocket) And (UBound($iMainsocket, 0) = 1) And (UBound($iMainsocket) > 0) Then $iMainsocket = $iMainsocket[0]
    If $iFlag = Default Then $iFlag = 0
    $iMainsocket = Number($iMainsocket)
    $iMaxLen = Number($iMaxLen)
    $iFlag = Number($iFlag)
    If $iMainsocket < 0 Or _
            $iMaxLen < 1 Or _
            Not ($iFlag = 0 Or $iFlag = 1 Or $iFlag = 2) Then Return SetError(-4, 0, -1) ; invalid parameter

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0, $nExtended = 0

    If Not $bError Then
        $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $iMainsocket, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
    EndIf

    Local $tBuf
    If $iFlag Then
        $tBuf = DllStructCreate("byte[" & $iMaxLen & "]")
    Else
        $tBuf = DllStructCreate("char[" & $iMaxLen & "]")
    EndIf
    $aRet = DllCall($hWs2, "int", "recv", "uint", $iMainsocket, "ptr", DllStructGetPtr($tBuf), "int", $iMaxLen, "int", 0)
    If @error Then
        $bError = -1
    ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Then ;SOCKET_ERROR
        $bError = 1
        $aRet = DllCall($hWs2, "int", "WSAGetLastError")
        If @error Then
            $bError = -1
        ElseIf $aRet[0] = 0 Or $aRet[0] = 10035 Then ;WSAEWOULDBLOCK
            $nCode = -10 ;internal function value, it means no error
        EndIf
    ElseIf $aRet[0] = 0 Then
        $bError = 1
        $nCode = -10
        $nExtended = 1 ;connection closed
    Else
        Local $sResult = DllStructGetData($tBuf, 1) ;data
        If BitAND($iFlag, 2) = 2 Then ;EOT
            If StringRight($sResult, 1) = Chr(3) Then
                $sResult = StringTrimRight($sResult, 1)
                $nExtended = 2 ;End of Text reached
            EndIf
        EndIf
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = "" ;failure
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        If $nCode = -10 Then $nCode = 0
        $nReturn = ""
    Else
        $nReturn = $sResult
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, $nExtended, $nReturn)
EndFunc   ;==>_TCPRecv

; #FUNCTION# ====================================================================================================================
; Name...........: _TCPConnect
; Description ...: Create a socket connected to an existing server.
; Syntax.........: _TCPConnect($sIPAddr, $iDestPort, $sSourceAddr = "", $iSourcePort = 0, $iTimeOut = 0)
; Parameters ....: $sIPAddr - Destination IP.
;                  |Internet Protocol dotted address(IpV4) as "192.162.1.1".
;                  $iDestPort - Destination port.
;                  |1 : 65534 - port on which the created socket will be connected.
;                  $sSourceAddr - Source IP
;                  |Internet Protocol dotted address(IpV4) as "192.162.1.1". [Default = ""]
;                  $iSourcePort - Source port.
;                  |1 : 65534 - port on which the created socket will be bind (on the local PC). [Default = 0]
;                  $iTimeOut - The maximum time in milliseconds for _TCPConnect to wait for connection.
;                  |Any value > 0 [Default = 0 and it will be equal to Opt("TCPTimeout")].
; Return values .: On success it returns the main socket identifier.
;                  |Any value > 0
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |-5 - not connected
;                  |-6 - timed out
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Remarks .......: This function is used by a client to communicate with the server and it allows to choose a source IP,
;                  a source port and to set a timeout for the connection.
; Links .........: bind:        https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx
;                  connect:     https://msdn.microsoft.com/en-us/library/windows/desktop/ms737625(v=vs.85).aspx
;                  select:      https://msdn.microsoft.com/en-us/library/windows/desktop/ms740141(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _TCPConnect($sIPAddr, $iDestPort, $sSourceAddr = "", $iSourcePort = 0, $iTimeOut = 0)
    If $sSourceAddr = Default Then $sSourceAddr = ""
    If $iSourcePort = Default Then $iSourcePort = 0
    If $iTimeOut = Default Then $iTimeOut = 0
    $sIPAddr = String($sIPAddr)
    $iDestPort = Number($iDestPort)
    $sSourceAddr = String($sSourceAddr)
    $iSourcePort = Number($iSourcePort)
    $iTimeOut = Number($iTimeOut)
    If Not ($iDestPort > 0 And $iDestPort < 65535) Or _
            Not ($iSourcePort >= 0 And $iSourcePort < 65535) Or _
            Not ($iTimeOut >= 0) Then Return SetError(-4, 0, -1) ; invalid parameter
    StringRegExp($sIPAddr, "((?:\d{1,3}\.){3}\d{1,3})", 3) ;$STR_REGEXPARRAYGLOBALMATCH
    If @error Then Return SetError(-4, 0, -1)
    If $sSourceAddr <> "" Then
        StringRegExp($sSourceAddr, "((?:\d{1,3}\.){3}\d{1,3})", 3) ;$STR_REGEXPARRAYGLOBALMATCH
        If @error Then Return SetError(-4, 0, -1)
    EndIf

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6); AF_INET, SOCK_STREAM, IPPROTO_TCP
    If @error Then
        $bError = -1
    ElseIf ($hSock[0] = 4294967295) Or ($hSock[0] = -1) Then ;INVALID_SOCKET
        $bError = 1
    Else
        $hSock = $hSock[0]
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "ulong", "inet_addr", "str", $sIPAddr)
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Or ($aRet[0] = 0) Then ;INADDR_NONE or INADDR_ANY
            $bError = 1
        Else
            $sIPAddr = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "ushort", "htons", "ushort", $iDestPort)
        If @error Then
            $bError = -1
        Else
            $iDestPort = $aRet[0]
        EndIf
    EndIf

    If (Not $bError) And ($sSourceAddr <> "") Then
        $aRet = DllCall($hWs2, "ulong", "inet_addr", "str", $sSourceAddr)
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Or ($aRet[0] = 0) Then ;INADDR_NONE or INADDR_ANY
            $bError = 1
        Else
            $sSourceAddr = $aRet[0]
        EndIf
    EndIf

    If (Not $bError) And $iSourcePort Then
        $aRet = DllCall($hWs2, "ushort", "htons", "ushort", $iSourcePort)
        If @error Then
            $bError = -1
        Else
            $iSourcePort = $aRet[0]
        EndIf
    EndIf

    If (Not $bError) And ($sSourceAddr Or $iSourcePort) Then
        $tSockAddr = DllStructCreate($tagSockAddr)
        DllStructSetData($tSockAddr, "sin_family", 2) ;AF_INET
        If $iSourcePort Then
            DllStructSetData($tSockAddr, "sin_port", $iSourcePort)
        Else
            DllStructSetData($tSockAddr, "sin_port", 0)
        EndIf
        If $sSourceAddr Then
            DllStructSetData($tSockAddr, "S_addr", $sSourceAddr)
        Else
            DllStructSetData($tSockAddr, "S_addr", 0x00000000) ;INADDR_ANY
        EndIf

        $aRet = DllCall($hWs2, "int", "bind", "uint", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
        $tSockAddr = 0
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $hSock, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
    EndIf

    If Not $bError Then
        $tSockAddr = DllStructCreate($tagSockAddr)
        DllStructSetData($tSockAddr, "sin_family", 2) ;AF_INET
        DllStructSetData($tSockAddr, "sin_port", $iDestPort)
        DllStructSetData($tSockAddr, "S_addr", $sIPAddr)
        $aRet = DllCall($hWs2, "int", "connect", "uint", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR -> functional with connect() on non-blocking sockets
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $bError = -1
            ElseIf ($aRet[0] <> 0) And ($aRet[0] <> 10035) Then ;WSAEWOULDBLOCK
                $bError = 1
            EndIf
        EndIf
        $tSockAddr = 0
    EndIf

    If Not $bError Then
        If $iTimeOut = 0 Then $iTimeOut = Opt("TCPTimeout")
        If $iTimeOut < 1 Then $iTimeOut = 100

        Local $tagFd_set = "uint fd_count; uint fd_array[64]"
        Local $tFd_set_writefds = DllStructCreate($tagFd_set)
        DllStructSetData($tFd_set_writefds, "fd_count", 1)
        DllStructSetData($tFd_set_writefds, "fd_array", $hSock, 1)
        Local $tFd_set_exceptfds = DllStructCreate($tagFd_set)
        DllStructSetData($tFd_set_exceptfds, "fd_count", 1)
        DllStructSetData($tFd_set_exceptfds, "fd_array", $hSock, 1)
        Local $tTimeval = DllStructCreate("long tv_sec; long tv_usec")
        DllStructSetData($tTimeval, "tv_sec", Floor($iTimeOut / 1000))
        DllStructSetData($tTimeval, "tv_usec", Round(Mod($iTimeOut, 1000) * 1000))
        $aRet = DllCall($hWs2, "int", "select", _
                "int", $hSock, "ptr", 0, "ptr", DllStructGetPtr($tFd_set_writefds), "ptr", DllStructGetPtr($tFd_set_exceptfds), "ptr", DllStructGetPtr($tTimeval))
        If @error Then
            $bError = -1
        ElseIf $aRet[0] = 0 Then ;time expired
            $bError = 1
            $nCode = -6 ;timed out, similar to WSAETIMEDOUT
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Then ;SOCKET_ERROR
            $bError = 1
        Else
            If Not (DllStructGetData($tFd_set_writefds, "fd_count") = 1) Then
                $bError = 1
                If DllStructGetData($tFd_set_exceptfds, "fd_count") = 1 Then
                    $tBuf = DllStructCreate("int")
                    $aRet = DllCall("Ws2_32.dll", "int", "getsockopt", _
                            "uint", $hSock, "int", 0xffff, "int", 0x1007, "ptr", DllStructGetPtr($tBuf), "int*", DllStructGetSize($tBuf)) ;SO_ERROR
                    If @error Then
                        $bError = -1
                    ElseIf $aRet[0] = 0 Then
                        $nCode = DllStructGetData($tBuf, 1)
                    EndIf
                Else
                    $nCode = -5 ;NOT_CONNECTED
                EndIf
            EndIf
        EndIf
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
        If $hSock Then TCPCloseSocket($hSock)
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        $nReturn = -1
        If $hSock Then TCPCloseSocket($hSock)
    Else
        $nReturn = $hSock
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_TCPConnect

; #MODIFIED WRAPPER# ============================================================================================================
; Name...........: _TCPSend
; Description ...: Wrapper of _TCPSend function, see the guide.
; Syntax.........: _TCPSend($iMainsocket, $iData, $iFlag = 0)
; Parameters ....: $iMainsocket - The array as returned by _TCPAccept
;                                 or the connected socket identifier (SocketID) as returned by _TCPConnect.
;                  $iData - Data sent.
;                  |Text or binary data
;                  $iFlag - values can be added together
;                  |$TCP_DATA_DEFAULT (0) - It doesn't add anything at the end of the string [Default]
;                  |$TCP_DATA_EOT (2) - It adds an End of Text ASCII character (Chr(3)) at the end of the string
; Return values .: see the guide.
; Author ........: j0kky
; Modified ......: 1.0.0
; Remarks .......: If Unicode strings need to be transmitted they must be encoded/decoded with StringToBinary()/BinaryToString().
;                  $iFlag = $TCP_DATA_EOT must be set in couple with _TCPRecv, so don't use it for external application
; Links .........: send:        https://msdn.microsoft.com/en-us/library/windows/desktop/ms740149(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _TCPSend($iMainsocket, $iData, $iFlag = 0)
    If IsArray($iMainsocket) And (UBound($iMainsocket, 0) = 1) And (UBound($iMainsocket) > 0) Then $iMainsocket = $iMainsocket[0]
    If BitAND($iFlag, 2) = 2 Then $iData = String($iData) & Chr(3)
    $iResult = TCPSend($iMainsocket, $iData)
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPSend

; #WRAPPER# =====================================================================================================================
Func _TCPNameToIP($sName)
    $iResult = TCPNameToIP($sName)
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPNameToIP

; #FUNCTION# ====================================================================================================================
; Name...........: _GetIps
; Description ...: Get local and public IP address of a network/computer
; Syntax.........: _GetIps($iServerName = "")
; Parameters ....: $iServerName - The server name which can retrieve your public IP
;                  |For example: "www.something.com/somethingelse" [Default = ""]
; Return values .: On success it returns an array:
;                  |[0] - Local IP (on LAN) of the adapter used to connect to Internet.
;                  |[1] - Public IP.
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter (not used)
;                  |-5 - servers are offline
;                  |-6 - IP retrieving failed
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Remarks .......: It works with Winsock library, so it must be initialized with _TCPStartup().
;                  Local and public IPs are both retrieved through internet.
; Links .........: error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _GetIps($iServerName = "")
    If $iServerName = Default Then $iServerName = ""
    $iServerName = String($iServerName)
    $iServerName = StringRegExpReplace($iServerName, "^http.?://", "")
    If StringInStr($iServerName, "/") Then
        If StringRegExp($iServerName, "/(.*)", 1)[0] Then
            If StringRight($iServerName, 1) = "/" Then $iServerName = StringTrimRight($iServerName, 1)
        EndIf
    Else
        $iServerName &= "/"
    EndIf
    If Not StringRegExp($iServerName, ".+\..{2,}") Then $iServerName = "" ; invalid parameter

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0, $sLocalIP = "", $sPublicIP = ""
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6); AF_INET, SOCK_STREAM, IPPROTO_TCP
    If @error Then
        $bError = -1
    ElseIf ($hSock[0] = 4294967295) Or ($hSock[0] = -1) Then ;INVALID_SOCKET
        $bError = 1
    Else
        $hSock = $hSock[0]
    EndIf

    If Not $bError Then
        If $iServerName Then
            Local $aGetIPURL[][2] = [["www.myexternalip.com/raw"], ["checkip.dyndns.org/"], ["bot.whatismyipaddress.com/"], [$iServerName]], $nElements = 0
        Else
            Local $aGetIPURL[][2] = [["www.myexternalip.com/raw"], ["checkip.dyndns.org/"], ["bot.whatismyipaddress.com/"]], $nElements = 0
        EndIf
        For $i = 0 To (UBound($aGetIPURL) - 1)
            $sServerIp = TCPNameToIP(StringRegExp($aGetIPURL[$i][0], "(.*?)/", 1)[0])
            If $sServerIp <> "" Then
                $aGetIPURL[$nElements][0] = $aGetIPURL[$i][0]
                $aGetIPURL[$nElements][1] = $sServerIp
                $nElements += 1
            EndIf
        Next
        If $nElements Then
            ReDim $aGetIPURL[$nElements][2]
        Else
            $bError = 1
            $nCode = -5 ;there is no valid server for checking IP
        EndIf
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "ushort", "htons", "ushort", 80)
        If @error Then
            $bError = -1
        Else
            $iDestPort = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        For $i = 0 To (UBound($aGetIPURL) - 1)
            $sServerIp = $aGetIPURL[$i][1]

            If Not $bError Then
                $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $hSock, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
                If @error Then
                    $bError = -1
                ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
                    $bError = 1
                EndIf
            EndIf

            If Not $bError Then
                $aRet = DllCall($hWs2, "ulong", "inet_addr", "str", $sServerIp)
                If @error Then
                    $bError = -1
                ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Or ($aRet[0] = 0) Then ;INADDR_NONE or INADDR_ANY
                    $bError = 1
                Else
                    $sServerIp = $aRet[0]
                EndIf
            EndIf

            If Not $bError Then
                $tSockAddr = DllStructCreate($tagSockAddr)
                DllStructSetData($tSockAddr, "sin_family", 2) ;AF_INET
                DllStructSetData($tSockAddr, "sin_port", $iDestPort)
                DllStructSetData($tSockAddr, "S_addr", $sServerIp)
                $aRet = DllCall($hWs2, "int", "connect", "uint", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
                If @error Then
                    $bError = -1
                ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR -> functional with connect() on non-blocking sockets
                    $aRet = DllCall($hWs2, "int", "WSAGetLastError")
                    If @error Then
                        $bError = -1
                    ElseIf ($aRet[0] <> 0) And ($aRet[0] <> 10035) Then ;WSAEWOULDBLOCK
                        $bError = 1
                    EndIf
                EndIf
                $tSockAddr = 0
            EndIf

            If Not $bError Then
                Local $tagFd_set = "uint fd_count; uint fd_array[64]"
                Local $tFd_set_writefds = DllStructCreate($tagFd_set)
                DllStructSetData($tFd_set_writefds, "fd_count", 1)
                DllStructSetData($tFd_set_writefds, "fd_array", $hSock, 1)
                Local $tFd_set_exceptfds = DllStructCreate($tagFd_set)
                DllStructSetData($tFd_set_exceptfds, "fd_count", 1)
                DllStructSetData($tFd_set_exceptfds, "fd_array", $hSock, 1)
                Local $tTimeval = DllStructCreate("long tv_sec; long tv_usec")
                DllStructSetData($tTimeval, "tv_sec", Floor(500 / 1000))
                DllStructSetData($tTimeval, "tv_usec", Round(Mod(500, 1000) * 1000))
                $aRet = DllCall($hWs2, "int", "select", _
                        "int", $hSock, "ptr", 0, "ptr", DllStructGetPtr($tFd_set_writefds), "ptr", DllStructGetPtr($tFd_set_exceptfds), "ptr", DllStructGetPtr($tTimeval))
                If @error Then
                    $bError = -1
                ElseIf ($aRet[0] = 0) Or ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Then
                    $bError = 1
                Else
                    If Not (DllStructGetData($tFd_set_writefds, "fd_count") = 1) Then $bError = 1
                EndIf
            EndIf

            If Not $bError And Not $sLocalIP Then
                $tSockAddr = DllStructCreate($tagSockAddr)
                $aRet = DllCall($hWs2, "int", "getsockname", "uint", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int*", DllStructGetSize($tSockAddr))
                If @error Then
                    $bError = -1
                ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
                    $bError = 1
                Else
                    $aRet = DllCall($hWs2, "ptr", "inet_ntoa", "ulong", DllStructGetData($tSockAddr, "S_addr"))
                    If @error Then
                        $bError = -1
                    ElseIf $aRet[0] = Null Then
                        $bError = 1
                    Else
                        $sLocalIP = DllStructGetData(DllStructCreate("char[15]", $aRet[0]), 1) ;IP address
                    EndIf
                EndIf
                $tSockAddr = 0
            EndIf

            If Not $bError Then
                $sRequest = "GET /" & StringRegExp($aGetIPURL[$i][0], "/(.*)", 1)[0] & " HTTP/1.1" & @CRLF & _
                        "Host: " & StringRegExp($aGetIPURL[$i][0], "(.*?)/", 1)[0] & @CRLF & _
                        "Connection: close" & @CRLF & @CRLF
                TCPSend($hSock, $sRequest)
                Local $sRecv = "", $hTimer = TimerInit()
                While 1
                    $sRecv &= _TCPRecv($hSock, 2048)
                    If @error Or @extended Then
                        If @error Then $bError = 1
                        ExitLoop
                    EndIf
                    If TimerDiff($hTimer) > 2500 Then ExitLoop
                    Sleep(10)
                WEnd
            EndIf

            If Not $bError Then
                $aPublicIP = StringRegExp($sRecv, "((?:\d{1,3}\.){3}\d{1,3})", 3) ;STR_REGEXPARRAYGLOBALMATCH
                If Not @error Then
                    $sPublicIP = $aPublicIP[0]
                    ExitLoop
                Else
                    $bError = 1
                EndIf
            EndIf

            If $bError And $i = (UBound($aGetIPURL) - 1) Then
                $nCode = -6
                ExitLoop
            Else
                $bError = 0
                $nCode = 0
                TCPCloseSocket($hSock)
            EndIf

            Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 1, "int", 6); AF_INET, SOCK_STREAM, IPPROTO_TCP
            If @error Then
                $bError = -1
            ElseIf ($hSock[0] = 4294967295) Or ($hSock[0] = -1) Then ;INVALID_SOCKET
                $bError = 1
            Else
                $hSock = $hSock[0]
            EndIf
        Next
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        $nReturn = -1
    Else
        Local $nReturn[2] = [$sLocalIP, $sPublicIP]
    EndIf
    If $hSock Then TCPCloseSocket($hSock)
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_GetIps

; #MODIFIED WRAPPER# ============================================================================================================
; Name...........: _TCPCloseSocket
; Description ...: Wrapper of TCPCloseSocket function, see the guide.
; Syntax.........: _TCPCloseSocket($iMainsocket)
; Parameters ....: $iMainsocket - The array as returned by _TCPAccept
;                                 or the connected socket identifier (SocketID) as returned by _TCPListen and _TCPConnect.
; Return values .: see the guide.
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: recv:        https://msdn.microsoft.com/en-us/library/windows/desktop/ms740121(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _TCPCloseSocket($iMainsocket)
    If IsArray($iMainsocket) And (UBound($iMainsocket, 0) = 1) And (UBound($iMainsocket) > 0) Then $iMainsocket = $iMainsocket[0]
    $iResult = TCPCloseSocket($iMainsocket)
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPCloseSocket

; #WRAPPER# =====================================================================================================================
Func _TCPShutdown()
    $iResult = TCPShutdown()
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_TCPShutdown


; #WRAPPER# =====================================================================================================================
Func _UDPStartup()
    $iResult = UDPStartup()
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_UDPStartup

; #FUNCTION# ====================================================================================================================
; Name...........: _UDPBind
; Description ...: Creates and bind a socket to a local IP and a local port.
; Syntax.........: _UDPBind($sSourceAddr = "", $iSourcePort = 0)
; Parameters ....: $sSourceAddr - Source IP
;                  |Internet Protocol dotted address(IpV4) as "192.162.1.1". [Default = ""]
;                  $iSourcePort - Source port.
;                  |1 : 65534 - port on which the created socket will be bind (on the local PC). [Default = 0]
; Return values .: On success it returns the main socket identifier.
;                  |Any value > 0
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Remarks .......: It could be used before both of _UDPSendTo (client app) and _UDPRecvFrom (server app) functions
; Links .........: bind:        https://msdn.microsoft.com/en-us/library/windows/desktop/ms737550(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _UDPBind($sSourceAddr = "", $iSourcePort = 0)
    If $sSourceAddr = Default Then $sSourceAddr = ""
    If $iSourcePort = Default Then $iSourcePort = 0
    $sSourceAddr = String($sSourceAddr)
    $iSourcePort = Number($iSourcePort)
    If Not ($iSourcePort >= 0 And $iSourcePort < 65535) Then Return SetError(-4, 0, -1) ; invalid parameter
    If $sSourceAddr <> "" Then
        StringRegExp($sSourceAddr, "((?:\d{1,3}\.){3}\d{1,3})", 3) ;$STR_REGEXPARRAYGLOBALMATCH
        If @error Then Return SetError(-4, 0, -1)
    EndIf

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    Local $hSock = DllCall($hWs2, "uint", "socket", "int", 2, "int", 2, "int", 17); AF_INET, SOCK_DGRAM, IPPROTO_UDP
    If @error Then
        $bError = -1
    ElseIf ($hSock[0] = 4294967295) Or ($hSock[0] = -1) Then ;INVALID_SOCKET
        $bError = 1
    Else
        $hSock = $hSock[0]
    EndIf

    If (Not $bError) And ($sSourceAddr <> "") Then
        $aRet = DllCall($hWs2, "ulong", "inet_addr", "str", $sSourceAddr)
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Or ($aRet[0] = 0) Then ;INADDR_NONE or INADDR_ANY
            $bError = 1
        Else
            $sSourceAddr = $aRet[0]
        EndIf
    EndIf

    If (Not $bError) And $iSourcePort Then
        $aRet = DllCall($hWs2, "ushort", "htons", "ushort", $iSourcePort)
        If @error Then
            $bError = -1
        Else
            $iSourcePort = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        $tSockAddr = DllStructCreate($tagSockAddr)
        DllStructSetData($tSockAddr, "sin_family", 2) ;AF_INET
        If $iSourcePort Then
            DllStructSetData($tSockAddr, "sin_port", $iSourcePort)
        Else
            DllStructSetData($tSockAddr, "sin_port", 0)
        EndIf
        If $sSourceAddr Then
            DllStructSetData($tSockAddr, "S_addr", $sSourceAddr)
        Else
            DllStructSetData($tSockAddr, "S_addr", 0x00000000) ;INADDR_ANY
        EndIf

        $aRet = DllCall($hWs2, "int", "bind", "uint", $hSock, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
        $tSockAddr = 0
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
        If $hSock Then UDPCloseSocket($hSock)
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        $nReturn = -1
        If $hSock Then UDPCloseSocket($hSock)
    Else
        $nReturn = $hSock
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_UDPBind

; #FUNCTION# ====================================================================================================================
; Name...........: _UDPSendTo
; Description ...: Sends data to an address/port, it uses a socket created by _UDPBind or it creates a socket itself
; Syntax.........: _UDPSendTo($sIPAddr, $iDestPort, $iData, $iMainsocket = 0)
; Parameters ....: $sIPAddr - Destination IP.
;                  |Internet Protocol dotted address(IpV4) as "192.162.1.1".
;                  $iDestPort - Destination port.
;                  |1 : 65534 - port which the created socket will connect on.
;                  $iData - Data sent.
;                  |Text or binary data
;                  $iMainsocket - Main socket identifier returned by _UDPBind.
;                  |Any value > 0 [Default = 0]
; Return values .: On success it returns an array:
;                  |[0] - The number of bytes sent.
;                  |[1] - The main socket identifier used.
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: sendto:      https://msdn.microsoft.com/en-us/library/windows/desktop/ms740148(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _UDPSendTo($sIPAddr, $iDestPort, $iData, $iMainsocket = 0)
    If $iMainsocket = Default Then $iMainsocket = 0
    $iMainsocket = Number($iMainsocket)
    $sIPAddr = String($sIPAddr)
    $iDestPort = Number($iDestPort)
    If Not IsBinary($iData) Then $iData = String($iData)
    If Not ($iDestPort > 0 And $iDestPort < 65535) Or _
            $iMainsocket < 0 Then Return SetError(-4, 0, -1) ; invalid parameter
    StringRegExp($sIPAddr, "((?:\d{1,3}\.){3}\d{1,3})", 3) ;$STR_REGEXPARRAYGLOBALMATCH
    If @error Then Return SetError(-4, 0, -1)

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    If Not $iMainsocket Then
        Local $aRet = DllCall($hWs2, "uint", "socket", "int", 2, "int", 2, "int", 17); AF_INET, SOCK_DGRAM, IPPROTO_UDP
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = 4294967295) Or ($aRet[0] = -1) Then ;INVALID_SOCKET
            $bError = 1
        Else
            $iMainsocket = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "ulong", "inet_addr", "str", $sIPAddr)
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Or ($aRet[0] = 0) Then ;INADDR_NONE or INADDR_ANY
            $bError = 1
        Else
            $sIPAddr = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "ushort", "htons", "ushort", $iDestPort)
        If @error Then
            $bError = -1
        Else
            $iDestPort = $aRet[0]
        EndIf
    EndIf

    If Not $bError Then
        $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $iMainsocket, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
    EndIf

    If Not $bError Then
        Local $tSockAddr = DllStructCreate($tagSockAddr)
        DllStructSetData($tSockAddr, "sin_family", 2) ;AF_INET
        DllStructSetData($tSockAddr, "sin_port", $iDestPort)
        DllStructSetData($tSockAddr, "S_addr", $sIPAddr)
        Local $nLenght, $tBuf
        If IsBinary($iData) Then
            $nLenght = BinaryLen($iData)
            $tBuf = DllStructCreate("byte[" & $nLenght & "]")
            DllStructSetData($tBuf, 1, $iData)
        Else
            $nLenght = StringLen($iData)
            $tBuf = DllStructCreate("char[" & $nLenght & "]")
            DllStructSetData($tBuf, 1, $iData)
        EndIf

        $aRet = DllCall($hWs2, "int", "sendto", _
                "uint", $iMainsocket, "ptr", DllStructGetPtr($tBuf), "int", $nLenght, "int", 0, "ptr", DllStructGetPtr($tSockAddr), "int", DllStructGetSize($tSockAddr))
        If @error Then
            $bError = -1
        ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Then ;SOCKET_ERROR
            $bError = 1
        Else
            Local $aReturn[2] = [$aRet[0], $iMainsocket]
        EndIf
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        $nReturn = -1
    Else
        $nReturn = $aReturn
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_UDPSendTo

; #FUNCTION# ====================================================================================================================
; Name...........: _UDPRecvFrom
; Description ...: Receives data from a bound socket on the local PC.
; Syntax.........: _UDPRecvFrom($iMainsocket, $iMaxLen, $iFlag = 0)
; Parameters ....: $iMainsocket - Main socket identifier.
;                  |Any value > 0
;                  $iMaxLen - Max # of characters to receive (usually 2048).
;                  $iFlag
;                  |0 - Text data. [Default]
;                  |1 - Binary data.
; Return values .: On success it returns an array:
;                  |[0] - The data received.
;                  |[1] - The IP address of the sender.
;                  |[2] - The port used by the sender for connection.
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: recvfrom:    https://msdn.microsoft.com/en-us/library/windows/desktop/ms740120(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _UDPRecvFrom($iMainsocket, $iMaxLen, $iFlag = 0)
    If $iFlag = Default Then $iFlag = 0
    $iMainsocket = Number($iMainsocket)
    $iMaxLen = Number($iMaxLen)
    $iFlag = Number($iFlag)
    If $iMainsocket < 0 Or _
            $iMaxLen < 1 Or _
            Not ($iFlag = 0 Or $iFlag = 1) Then Return SetError(-4, 0, -1) ; invalid parameter

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0
    Local $tagSockAddr = "short sin_family; ushort sin_port; " & _
            "STRUCT; ulong S_addr; ENDSTRUCT; " & _ ;sin_addr
            "char sin_zero[8]"

    If Not $bError Then
        $aRet = DllCall($hWs2, "int", "ioctlsocket", "uint", $iMainsocket, "long", 0x8004667e, "ulong*", 1) ;FIONBIO
        If @error Then
            $bError = -1
        ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
            $bError = 1
        EndIf
    EndIf

    Local $tSockAddr = DllStructCreate($tagSockAddr)
    Local $tBuf
    If $iFlag Then
        $tBuf = DllStructCreate("byte[" & $iMaxLen & "]")
    Else
        $tBuf = DllStructCreate("char[" & $iMaxLen & "]")
    EndIf

    $aRet = DllCall($hWs2, "int", "recvfrom", _
            "uint", $iMainsocket, "ptr", DllStructGetPtr($tBuf), "int", $iMaxLen, "int", 0, "ptr", DllStructGetPtr($tSockAddr), "int*", DllStructGetSize($tSockAddr))
    If @error Then
        $bError = -1
    ElseIf ($aRet[0] = -1) Or ($aRet[0] = 4294967295) Then ;SOCKET_ERROR
        $bError = 1
        $aRet = DllCall($hWs2, "int", "WSAGetLastError")
        If @error Then
            $bError = -1
        ElseIf $aRet[0] = 0 Or $aRet[0] = 10035 Then ;WSAEWOULDBLOCK
            $nCode = -10 ;internal function value, it means no error
        EndIf
    Else
        Local $aResult[3] = [DllStructGetData($tBuf, 1)] ;data

        $aRet = DllCall($hWs2, "ptr", "inet_ntoa", "ulong", DllStructGetData($tSockAddr, "S_addr"))
        If @error Then
            $bError = -1
        ElseIf $aRet[0] = Null Then
            $bError = 1
        Else
            $aResult[1] = DllStructGetData(DllStructCreate("char[15]", $aRet[0]), 1) ;IP address
            $aRet = DllCall($hWs2, "ushort", "ntohs", "ushort", DllStructGetData($tSockAddr, "sin_port"))
            If @error Then
                $bError = -1
            Else
                $aResult[2] = $aRet[0] ;port
            EndIf
        EndIf
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        If $nCode = -10 Then $nCode = 0
        $nReturn = -1
    Else
        $nReturn = $aResult
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_UDPRecvFrom

; #FUNCTION# ====================================================================================================================
; Name...........: _UDPCloseSocket
; Description ...: Close a UDP socket.
; Syntax.........: _UDPCloseSocket($iMainsocket)
; Parameters ....: $iMainsocket - Main socket identifier returned by _UDPBind or the array returned by _UDPSendTo.
;                  |Any value > 0
; Return values .: On success it returns 1.
;                  On failure it returns -1 and sets @error to non zero:
;                  |-1 - internal error
;                  |-2 - missing DLL (Ws2_32.dll)
;                  |-3 - undefined error
;                  |-4 - invalid parameter
;                  |Any Windows Socket Error Code retrieved by WSAGetLastError
; Author ........: j0kky
; Modified ......: 1.0.0
; Links .........: closesocket: https://msdn.microsoft.com/en-us/library/windows/desktop/ms737582(v=vs.85).aspx
;                  error codes: https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
; ===============================================================================================================================
Func _UDPCloseSocket($iMainsocket)
    If IsArray($iMainsocket) Then
        If Not ((UBound($iMainsocket, 0) = 1) And (UBound($iMainsocket) = 2)) Then Return SetError(-1, 0, -4)
        $iMainsocket = $iMainsocket[1]
    Else
        If $iMainsocket < 1 Then Return SetError(-1, 0, -4)
    EndIf

    Local $hWs2 = DllOpen("Ws2_32.dll")
    If @error Then Return SetError(-2, 0, -1) ;missing DLL
    Local $bError = 0, $nCode = 0

    $aRet = DllCall($hWs2, "int", "closesocket", "uint", $iMainsocket)
    If @error Then
        $bError = -1
    ElseIf $aRet[0] <> 0 Then ;SOCKET_ERROR
        $bError = 1
    EndIf

    If $bError < 0 Then
        $nCode = -1 ;internal error
        $nReturn = -1 ;failure
    ElseIf $bError > 0 Then
        If Not $nCode Then
            $aRet = DllCall($hWs2, "int", "WSAGetLastError")
            If @error Then
                $nCode = -1
            Else
                $nCode = $aRet[0]
            EndIf
            If $nCode = 0 Then $nCode = -3 ;undefined error
        EndIf
        $nReturn = -1
    Else
        $nReturn = 1
    EndIf
    DllClose($hWs2)
    Return SetError($nCode, 0, $nReturn)
EndFunc   ;==>_UDPCloseSocket

; #WRAPPER# =====================================================================================================================
Func _UDPShutdown()
    $iResult = UDPShutdown()
    Return SetError(@error, 0, $iResult)
EndFunc   ;==>_UDPShutdown

Obviously there can be a lot of errors, so please report here any problem\suggestion!

Updated to: 11/01/16

winsock.zip

Edited by j0kky
4 people like this

Share this post


Link to post
Share on other sites



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 account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Similar Content

    • imitto
      By imitto
      Hello all!
      I use Autoit for a while, already made some automation for a TV station's master control room with it. I made a UDF to easily work with PAL timecode and time with milliseconds, convert, add or subtract them. Feel free to use it if you want something like this
      #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_Description=PAL Timecode Calculator UDF #AutoIt3Wrapper_Res_LegalCopyright=horvath.imre@gmail.com #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ; #FUNCTION# ; Name...........: _tcAdd ; Description....: Returns addition of two timecodes ; Syntax.........: _tcAdd($fTc1, fTc2 [, $fFormat = "P"]) ; ; Parameters.....: $fTc1 - First timecode in hh:mm:ss.ff format ; $fTc2 - Second timecode in hh:mm:ss.ff format ; $fFormat - Time base - "P" (default): PAL (25 fps) ; "M" : millisecond ; ; Return value...: Sum of the two timecode in the selected format Func _tcAdd($fTc1, $fTc2, $fFormat = "P", $fHourFormat = 1) Local $fMs1 = _tcToMs($fTc1) Local $fMs2 = _tcToMs($fTc2) Local $fSumMs = $fMs1 + $fMs2 Return _msToTc($fSumMs, $fFormat, $fHourFormat) EndFunc ; #FUNCTION# ; Name...........: _tcsSub ; Description....: Returns addition of two timecodes ; Syntax.........: _tcSub($fTc1, fTc2 [, $fFormat = "P"]) ; ; Parameters.....: $fTc1 - First timecode in hh:mm:ss.ff format ; $fTc2 - Second timecode in hh:mm:ss.ff format ; $fFormat - Time base - "P" (default): PAL (25 fps) ; "M" : millisecond ; ; Return value...: Subtract $fTc2 from $fTc1 in the source format Func _tcSub($fTc1, $fTc2, $fFormat = "P") Local $fMs1 = _tcToMs($fTc1) Local $fMs2 = _tcToMs($fTc2) Local $fSumMs = $fMs1 - $fMs2 If $fSumMs < 0 Then $fSumMs = _tcToMs("24:00:00.00") - ($fSumMs * -1) EndIf Return _msToTc($fSumMs, $fFormat) EndFunc ; #FUNCTION# ; Name...........: _tcToMs ; Description....: Returns timecode converted to total milliseconds ; Syntax.........: _tcToMs($fTc) ; ; Parameters.....: $fTc - Timecode in hh:mm:ss.ff or hh:mm:ss:xxx format, where xxx are milliseconds ; ; Return value...: Milliseconds as an integer value Func _tcToMs($fTc) Local $fTemp = StringSplit($fTc, ":.") Local $fChr = StringLen($fTemp[4]) Switch $fChr Case 2 Return ($fTemp[4] * 40) + ($fTemp[3] * 1000) + ($fTemp[2] * 60000) + ($fTemp[1] * 3600000) Case 3 Return ($fTemp[4]) + ($fTemp[3] * 1000) + ($fTemp[2] * 60000) + ($fTemp[1] * 3600000) EndSwitch EndFunc ; #FUNCTION# ; Name...........: _msToTc ; Description....: Converts total milliseconds to timecode ; Syntax.........: _msToTc($fIn, $fFormat = "P", $fHourFormat = 1) ; ; Parameters.....: $fIn - Time in milliseconds ; $fFormat - Output format "P": PAL TC (default) ; "M": hh:mm:ss.xxx where xxx are milliseconds ; $fHourFormat - Hour format "1": max. value is 23, then starts from 0 (default) ; "0": hours can be more then 23 ; ; Return value...: Timecode as string in the selected format Func _msToTc($fIn, $fFormat = "P", $fHourFormat = 1) Switch $fFormat Case "P" Local $fFr = StringFormat("%02i", (StringRight($fIn, 3) - Mod(StringRight($fIn, 3), 40)) / 40) Case "M" Local $fFr = StringFormat("%03i", StringRight($fIn, 3)) EndSwitch $fIn = StringTrimRight($fIn, 3) Local $fSec = StringFormat("%02i", Mod($fIn, 60)) $fIn -= $fSec Local $fMinTot = $fIn / 60 Local $fMin = StringFormat("%02i", Mod($fMinTot, 60)) $fIn -= $fMin*60 Local $fHourTot = $fIn / 60 / 60 Switch $fHourFormat Case 1 $fHour = StringFormat("%02i", Mod($fHourTot, 24)) Case 0 $fHour = StringFormat("%02i", $fHourTot) EndSwitch Return($fHour & ":" & $fMin & ":" & $fSec & "." & $fFr) EndFunc ; #FUNCTION# ; Name...........: _tcFormatChange ; Description....: Toggle TC format ; Syntax.........: _tcFormatChange($fTc) ; ; Parameters.....: $fTc - Timecode in hh:mm:ss.ff or hh:mm:ss:xxx format, where xxx are milliseconds ; ; Return value...: PAL timecode or time with milliseconds as string, depends on input Func _tcFormatChange($fTc) Local $fTemp = StringSplit($fTc, ":.") Local $fChr = StringLen($fTemp[4]) Switch $fChr Case 2 Return $fTemp[1]&":"&$fTemp[2]&":"&$fTemp[3]&"."&StringFormat("%03i", $fTemp[4]*40) Case 3 Return $fTemp[1]&":"&$fTemp[2]&":"&$fTemp[3]&"."&StringFormat("%02i", ($fTemp[4]-Mod($fTemp[4], 40))/40) EndSwitch EndFunc And the example script:
      #include<_PAL_TC_Calc.au3> $palTC1 = "00:01:12.20" $palTC2 = "23:59:50.02" $msTC1 = "00:01:12.800" $msTC2 = "23:59:50.120" MsgBox(0, "1", _tcAdd($palTC1, $palTC2)); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns PAL TC format MsgBox(0, "2", _tcAdd($palTC1, $palTC2, "M")); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns time with milliseconds format MsgBox(0, "3", _tcAdd($palTC1, $palTC2, "M", 0)); Adds $palTC1 to $palTC2, hours can be infinite, returns time with milliseconds format MsgBox(0, "4", _tcAdd($msTC1, $msTC2)); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns PAL TC format MsgBox(0, "5", _tcAdd($msTC1, $msTC2, "M")); Adds $palTC1 to $palTC2, turns hour back to 0 after 23, returns time with milliseconds format MsgBox(0, "6", _tcAdd($msTC1, $msTC2, "M", 0)); Adds $palTC1 to $palTC2, hours can be infinite, returns time with milliseconds format MsgBox(0, "7", _tcSub($palTC2, $palTC1)); Subtract $palTC1 from $palTC2, returns PAL TC format MsgBox(0, "8", _tcSub($palTC2, $palTC1, "M")); Subtract $palTC1 from $palTC2, time with milliseconds format MsgBox(0, "9", _tcSub($msTC1, $msTC2)); Subtract $palTC1 from $palTC2, returns PAL TC format - when hits zero, counts back from 24:00:00.00 MsgBox(0, "10", _tcSub($msTC1, $msTC2, "M")); Subtract $palTC1 from $palTC2, time with milliseconds format - when hits zero, counts back from 24:00:00.000 MsgBox(0, "11", _tcFormatChange($palTC2)); Convert PAL TC to time with milliseconds and back MsgBox(0, "12", _tcFormatChange($msTC2)); Convert PAL TC to time with milliseconds and back  
      TC_CALC_example.au3
      _PAL_TC_Calc.au3
    • TRAGENALPHA
      By TRAGENALPHA
      A small UDF to Modify the Console Interface.
      #include-once ;#AutoIt3Wrapper_Au3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 ; =============================================================================================================================== ; Name...........: Console Modify ; Description ...: A small UDF to manipulate the Console Interface for scripts that are compiled as a console application. ; Syntax.........: _ConsoleClear() -- Clears the Console ; _ConsoleTitle("VALUE") - Sets the console title. ; _ConsoleWindow([WIDTH BUFFER SIZE], [HEIGHT BUFFER SIZE]) - Sets the Width and Height Buffer size of the console. ; Parameters ....: $bh6e5v_ctval = Title of the Console Window. ; $bh6e5v_cwwidth = Window width buffer size. ; $bh6e5v_cwheight = Window height buffer size. ; Return values .: True = Console window buffer size has been changed ; False = Failed to change console window buffer size. ; Author ........: TRAGENALPHA <3 ; Example .......: _ConsoleTitle("This is the new title") // _ConsoleWindow(200, 60) ; =============================================================================================================================== ; -- This is here because writing RunDos and including a whole UDF is too much. But this is basically just _RunDos() ;Func cmd($bh6e5v_ldvar) ; RunWait(@ComSpec & " /c " & $bh6e5v_ldval) ;EndFunc Func _ConsoleClear() RunWait(@ComSpec & " /c cls") EndFunc Func _ConsoleTitle($bh6e5v_ctval) RunWait(@ComSpec & " /c title " & $bh6e5v_ctval) EndFunc Func _ConsoleWindow($bh6e5v_cwwidth, $bh6e5v_cwheight) If IsNumber($bh6e5v_cwwidth) And IsNumber($bh6e5v_cwheight) And ($bh6e5v_cwwidth > 0) And ($bh6e5v_cwheight > 0) Then RunWait(@ComSpec & " /c mode con: cols=" & $bh6e5v_cwwidth & " lines=" & $bh6e5v_cwheight) Return True Else Return False EndIf EndFunc  
      ConsoleModify.au3
    • FrancescoDiMuro
      By FrancescoDiMuro
      Good morning everyone
      I'm working on a little project, and, I encountered a little strange error when I try to add some data to an array...
      The code I wrote is this:
      Func _WMI_Get_Win32_TemperatureProbe($blnCanUseWMI, $blnCustomArrayDisplay = False, $blnReturnEU = False) If $blnCanUseWMI Then Local $objWMI_QueryResult = $objWMI.ExecQuery("SELECT * FROM Win32_TemperatureProbe", "WQL", 32) If @error Then __ConsoleWrite("Error executing the query on Win32_TemperatureProbe class.", @error, 9999) Else Local $arrWin32_TemperatureProbe[1][3] _ArrayDelete($arrWin32_TemperatureProbe, 0) If @error Then __ConsoleWrite("Error deleting the 0st element $arrWin32_TemperatureProbe array.", @error, 9999) Else Local $objWMI_Variable = Null, $strWMI_QueryResult = "", $i = 0 For $objWMI_Variable In $objWMI_QueryResult $strWMI_QueryResult &= "QUERY RESULT" & "|# " & $i & "|/" & @CRLF & _ "Accuracy" & "|" & $objWMI_Variable.Accuracy & "|" & "[sint32]" & @CRLF & _ "Availability" & "|" & $objWMI_Variable.Availability & "|" & "[uint16]" & @CRLF & _ "Caption" & "|" & $objWMI_Variable.Caption & "|" & "[string]" & @CRLF & _ "ConfigManagerErrorCode" & "|" & $objWMI_Variable.ConfigManagerErrorCode & "|" & "[uint32]" & @CRLF & _ "ConfigManagerUserConfig" & "|" & $objWMI_Variable.ConfigManagerUserConfig & "|" & "[boolean]" & @CRLF & _ "CreationClassName" & "|" & $objWMI_Variable.CreationClassName & "|" & "[string]" & @CRLF & _ "CurrentReading" & "|" & $objWMI_Variable.CurrentReading & "|" & "[sint32]" & @CRLF & _ "Description" & "|" & $objWMI_Variable.Description & "|" & "[string]" & @CRLF & _ "DeviceID" & "|" & $objWMI_Variable.DeviceID & "|" & "[string]" & @CRLF & _ "ErrorCleared" & "|" & $objWMI_Variable.ErrorCleared & "|" & "[boolean]" & @CRLF & _ "ErrorDescription" & "|" & $objWMI_Variable.ErrorDescription & "|" & "[string]" & @CRLF & _ "InstallDate" & "|" & $objWMI_Variable.InstallDate & "|" & "[datetime]" & @CRLF & _ "IsLinear" & "|" & $objWMI_Variable.IsLinear & "|" & "[boolean]" & @CRLF & _ "LastErrorCode" & "|" & $objWMI_Variable.LastErrorCode & "|" & "[uint32]" & @CRLF & _ "LowerThresholdCritical" & "|" & $objWMI_Variable.LowerThresholdCritical & "|" & "[sint32]" & @CRLF & _ "LowerThresholdFatal" & "|" & $objWMI_Variable.LowerThresholdFatal & "|" & "[sint32]" & @CRLF & _ "LowerThresholdNonCritical" & "|" & $objWMI_Variable.LowerThresholdNonCritical & "|" & "[sint32]" & @CRLF & _ "MaxReadable" & "|" & $objWMI_Variable.MaxReadable & "|" & "[sint32]" & @CRLF & _ "MinReadable" & "|" & $objWMI_Variable.MinReadable & "|" & "[sint32]" & @CRLF & _ "Name" & "|" & $objWMI_Variable.Name & "|" & "[string]" & @CRLF & _ "NominalReading" & "|" & $objWMI_Variable.NominalReading & "|" & "[sint32]" & @CRLF & _ "NormalMax" & "|" & $objWMI_Variable.NormalMax & "|" & "[sint32]" & @CRLF & _ "NormalMin" & "|" & $objWMI_Variable.NormalMin & "|" & "[sint32]" & @CRLF & _ "PNPDeviceID" & "|" & $objWMI_Variable.PNPDeviceID & "|" & "[string]" & @CRLF & _ "PowerManagementCapabilities" & "|" & $objWMI_Variable.PowerManagementCapabilities & "|" & "[uint16]" & @CRLF & _ "PowerManagementSupported" & "|" & $objWMI_Variable.PowerManagementSupported & "|" & "[boolean]" & @CRLF & _ "Resolution" & "|" & $objWMI_Variable.Resolution & "|" & "[uint32]" & @CRLF & _ "Status" & "|" & $objWMI_Variable.Status & "|" & "[string]" & @CRLF & _ "StatusInfo" & "|" & $objWMI_Variable.StatusInfo & "|" & "[uint16]" & @CRLF & _ "SystemCreationClassName" & "|" & $objWMI_Variable.SystemCreationClassName & "|" & "[string]" & @CRLF & _ "SystemName" & "|" & $objWMI_Variable.SystemName & "|" & "[string]" & @CRLF & _ "Tolerance" & "|" & $objWMI_Variable.Tolerance & "|" & "[sint32]" & @CRLF & _ "UpperThresholdCritical" & "|" & $objWMI_Variable.UpperThresholdCritical & "|" & "[sint32]" & @CRLF & _ "UpperThresholdFatal" & "|" & $objWMI_Variable.UpperThresholdFatal & "|" & "[sint32]" & @CRLF & _ "UpperThresholdNonCritical" & "|" & $objWMI_Variable.UpperThresholdNonCritical & "|" & "[sint32]" $i+=1 Next ConsoleWrite($strWMI_QueryResult & @CRLF) _ArrayAdd($arrWin32_TemperatureProbe, $strWMI_QueryResult) ; I'll wait for an answer... See you later :) If @error Then __ConsoleWrite("Error inserting item #" & $i & " in the $arrWin32_TemperatureProbe array.", @error, 9999) Else If $blnCustomArrayDisplay Then _ArrayDisplay($arrWin32_TemperatureProbe, "Win32_TemperatureProbe:", "", 64 + 32 + 4, "|", "VARIABLE NAME|ACTUAL VALUE|ENGINEERING UNIT", 350, 0xD3D3D3) If @error Then __ConsoleWrite("Error displaying the $arrWin32_TemperatureProbe array.", @error, 9999) EndIf EndIf If $blnReturnEU = False Then _ArrayColDelete($arrWin32_TemperatureProbe, 2) If @error Then __ConsoleWrite("Error deleting the column #2 of $arrWin32_TemperatureProbe array.") EndIf EndIf If IsArray($arrWin32_TemperatureProbe) Then Return $arrWin32_TemperatureProbe Else Return False EndIf EndIf EndIf EndIf EndIf EndFunc And I get this error ( undocumented in the Help File on _ArrayAdd() function ):
      [15/09/2017 10:24:46] : Error inserting item #4 in the $arrWin32_TemperatureProbe array. > Error: 0 Adding a ConsoleWrite() before the _ArrayAdd() function, I can see the content of $strWMI_QueryResult, and, here it is:
      QUERY RESULT|# 0|/
      Accuracy|32768|[sint32]
      Availability||[uint16]
      Caption|Sensore numerico|[string]
      ConfigManagerErrorCode||[uint32]
      ConfigManagerUserConfig||[boolean]
      CreationClassName|Win32_TemperatureProbe|[string]
      CurrentReading||[sint32]
      Description|CPU Thermal Probe|[string]
      DeviceID|root\cimv2 0|[string]
      ErrorCleared||[boolean]
      ErrorDescription||[string]
      InstallDate||[datetime]
      IsLinear||[boolean]
      LastErrorCode||[uint32]
      LowerThresholdCritical||[sint32]
      LowerThresholdFatal||[sint32]
      LowerThresholdNonCritical||[sint32]
      MaxReadable|1270|[sint32]
      MinReadable|64266|[sint32]
      Name|Sensore numerico|[string]
      NominalReading||[sint32]
      NormalMax||[sint32]
      NormalMin||[sint32]
      PNPDeviceID||[string]
      PowerManagementCapabilities||[uint16]
      PowerManagementSupported||[boolean]
      Resolution|1000|[uint32]
      Status|Unknown|[string]
      StatusInfo||[uint16]
      SystemCreationClassName|Win32_ComputerSystem|[string]
      SystemName|DESKTOP-25LFPVU|[string]
      Tolerance|32768|[sint32]
      UpperThresholdCritical||[sint32]
      UpperThresholdFatal||[sint32]
      UpperThresholdNonCritical||[sint32]QUERY RESULT|# 1|/
      Accuracy|32768|[sint32]
      Availability||[uint16]
      Caption|Sensore numerico|[string]
      ConfigManagerErrorCode||[uint32]
      ConfigManagerUserConfig||[boolean]
      CreationClassName|Win32_TemperatureProbe|[string]
      CurrentReading||[sint32]
      Description|True Ambient Thermal Probe|[string]
      DeviceID|root\cimv2 1|[string]
      ErrorCleared||[boolean]
      ErrorDescription||[string]
      InstallDate||[datetime]
      IsLinear||[boolean]
      LastErrorCode||[uint32]
      LowerThresholdCritical||[sint32]
      LowerThresholdFatal||[sint32]
      LowerThresholdNonCritical||[sint32]
      MaxReadable|1270|[sint32]
      MinReadable|64266|[sint32]
      Name|Sensore numerico|[string]
      NominalReading||[sint32]
      NormalMax||[sint32]
      NormalMin||[sint32]
      PNPDeviceID||[string]
      PowerManagementCapabilities||[uint16]
      PowerManagementSupported||[boolean]
      Resolution|1000|[uint32]
      Status|Unknown|[string]
      StatusInfo||[uint16]
      SystemCreationClassName|Win32_ComputerSystem|[string]
      SystemName|DESKTOP-25LFPVU|[string]
      Tolerance|32768|[sint32]
      UpperThresholdCritical||[sint32]
      UpperThresholdFatal||[sint32]
      UpperThresholdNonCritical||[sint32]QUERY RESULT|# 2|/
      Accuracy|32768|[sint32]
      Availability||[uint16]
      Caption|Sensore numerico|[string]
      ConfigManagerErrorCode||[uint32]
      ConfigManagerUserConfig||[boolean]
      CreationClassName|Win32_TemperatureProbe|[string]
      CurrentReading||[sint32]
      Description|Memory Module Thermal Probe|[string]
      DeviceID|root\cimv2 2|[string]
      ErrorCleared||[boolean]
      ErrorDescription||[string]
      InstallDate||[datetime]
      IsLinear||[boolean]
      LastErrorCode||[uint32]
      LowerThresholdCritical||[sint32]
      LowerThresholdFatal||[sint32]
      LowerThresholdNonCritical||[sint32]
      MaxReadable|1270|[sint32]
      MinReadable|64266|[sint32]
      Name|Sensore numerico|[string]
      NominalReading||[sint32]
      NormalMax||[sint32]
      NormalMin||[sint32]
      PNPDeviceID||[string]
      PowerManagementCapabilities||[uint16]
      PowerManagementSupported||[boolean]
      Resolution|1000|[uint32]
      Status|Unknown|[string]
      StatusInfo||[uint16]
      SystemCreationClassName|Win32_ComputerSystem|[string]
      SystemName|DESKTOP-25LFPVU|[string]
      Tolerance|32768|[sint32]
      UpperThresholdCritical||[sint32]
      UpperThresholdFatal||[sint32]
      UpperThresholdNonCritical||[sint32]QUERY RESULT|# 3|/
      Accuracy|32768|[sint32]
      Availability||[uint16]
      Caption|Sensore numerico|[string]
      ConfigManagerErrorCode||[uint32]
      ConfigManagerUserConfig||[boolean]
      CreationClassName|Win32_TemperatureProbe|[string]
      CurrentReading||[sint32]
      Description|Video Card Thermal Probe|[string]
      DeviceID|root\cimv2 3|[string]
      ErrorCleared||[boolean]
      ErrorDescription||[string]
      InstallDate||[datetime]
      IsLinear||[boolean]
      LastErrorCode||[uint32]
      LowerThresholdCritical||[sint32]
      LowerThresholdFatal||[sint32]
      LowerThresholdNonCritical||[sint32]
      MaxReadable|1270|[sint32]
      MinReadable|64266|[sint32]
      Name|Sensore numerico|[string]
      NominalReading||[sint32]
      NormalMax||[sint32]
      NormalMin||[sint32]
      PNPDeviceID||[string]
      PowerManagementCapabilities||[uint16]
      PowerManagementSupported||[boolean]
      Resolution|1000|[uint32]
      Status|Unknown|[string]
      StatusInfo||[uint16]
      SystemCreationClassName|Win32_ComputerSystem|[string]
      SystemName|DESKTOP-25LFPVU|[string]
      Tolerance|32768|[sint32]
      UpperThresholdCritical||[sint32]
      UpperThresholdFatal||[sint32]
      UpperThresholdNonCritical||[sint32]
       
      Could please anyone help me out? 
      Thanks in advance
      Francesco
    • TheDcoder
      By TheDcoder
      Hello, I recently opened a bug report without reading the Helpfile... My bad . After @Melba23's gentle reminder, I was curious about why it was like that.
      It is about SetError's behaviour. This is the example from the bug report:
      Example() If @error Then ConsoleWrite("Error" & @CRLF) Else ConsoleWrite("No Error" & @CRLF) EndIf Func Example() SetError(1) Sleep(1000) EndFunc What I tried to do is set Example's (my user defined function's) @error value to 1... but the value set by SetError is cleared after calling a function, I wonder why? Why should calling to an external function effect my function's @error which is set when my function returns.
      Setting the error of a UDF in advance by using SetError makes sense... but I cannot find a reason why calling a function should clear it? Please note that I am not talking about @error, I am talking about the @error set by my function when it ends/returns!
      I hope someone can enlighten me, thanks for the answers in advance!
      P.S I tried to explain my best but my English is not very good and I didn't feel like I did a good job explaining today, so please pardon any mistakes that I have made
    • pboom
      By pboom
      I am looking for a way to retrieve filtered messages from the ‘system debug channel.' also known as  ‘kernel-mode debug output.'

      AutoIt must do the capture in real time. The following AutoIt UDF almost does what is required but it only captures application level, or Win32 debug output.

      https://www.autoitscript.com/forum/topic/82889-capture-debug-information-udf/#comment-593268

      The utility DebugView by Sysinternals captures the information as required by turning on Capture Kernal and in my case using the Filter include:

      *Incoming connection*

      The use of DebugView to do this is covered in the following tech note;

      https://www.tacticalsoftware.com/support/tech-notes/logging-com-port-activity.htm

      https://technet.microsoft.com/en-us/sysinternals/debugview.aspx

      However to make to make the information from DebugView available to my AutoIt script required DebugView capture to a text file and then my AutoIt script monitor that file for changes. The use of DebugView to capture the system debug channel could be made to work, but it was less than reliable and difficult to get started. The startup wasn’t something that could be easily automated not even with AutoIt.

      If you understood what I am talking about and made it this far, I think an explanation of the application is in order. Lots of details here sorry trying to answer questions in advance.

      I support a large installation of General Electric MUSE application. MUSE is a Windows-based medical application that processes and archives ECGs (electrocardiograms) taken on dedicated hardware (ECG Carts). Several methods exist on the cart to get the ECG from the Carts to the MUSE system; they range from floppies (on old obsolete hardware), memory cards, RS232 serial ports, and hardwired network connections.

      In our installation, we choose not to use the vendor-supplied network solution due to a variety of reasons I won’t get into here.  Instead, we have designed our own connection solution.

      We use a wireless serial server mounted on the ECG carts connecting to a server running a Serial/IP COM Port Redirector. The ECG cart and MUSE application think they are talking to each other via an RS232 port and as far as they are concerned, they are. However, this RS232 cable happens to run through our province (think State) wide Health Care WAN.  The hardware and software used can be seen on these two sites;

      http://www.bb-elec.com/Products/Wireless-Cellular/AirborneM2M-802-11-a-b-g-n-Dual-Band-Wireless/AirborneM2M-Industrial-Dual-Band-Wi-Fi-Router-Brid.aspx

      https://www.tacticalsoftware.com/virtual-serial-port-redirector/serial-ip.htm

      This setup works well we have over 130 ECG carts connecting using this setup. However, the end users are not technical, and there is a lot that can go wrong with wireless connections. So we do get complaints, often after the fact, that the ECG cart would not connect. A log of what ECG carts connected and when would be very helpful.

      The Serial redirector software can be configured to log all activity to the Kernal-mode Debug output. The serial redirector software itself being kernel level software. For configuration of the Wireless modules, we have custom written software (written in AutoIt) that amongst other things can display relevant configuration information for a Wireless module given it’s IP address.

      By extracting messages like the ones below from the Kernal-Mode Debug channel;

      COM56 : ½ Incoming connection from 10.158.188.172:51562

      COM18 : ½ Incoming connection from 10.158.188.200:50896

      COM19 : ½ Incoming connection from 10.158.188.180:59074

      COM68 : ½ Incoming connection from 142.239.15.82:34322

      We can have the module configuration program retrieve the configuration. The retrieved configuration contains more information such as the module ID number and wireless signal strength. This information is then logged to a file which is later loaded into a database. We can then query the database for connections made by a particular module within a specified time frame. The results of these Queries help us determine if the module was connected or is having problems connecting. Problems are usually indicated by poor signal strength and frequent re-connecting.

      So what I am looking for is a way for our module configuration program (written in AutoIt) to retrieve filtered Kernal-Level debug messages directly without using the DebugView application.

      The Forum post listed at the first of this message includes the source code for the DLL. So if you are versed in these matters and Visual Studio this may be an easy task. I looked at what needed to be done but, I was way over my head. If you look up the price of the serial IP redirector software, you can see that there is some money in our project for such things however, I do have a spending limit for purchases such as this.