Merge pull request #3787 from vegansk/fix_3539_3
Fixed issue #3539 - could not import inet_ntop on XP/2003 - 3rd try
This commit is contained in:
commit
f340f7634a
2 changed files with 118 additions and 10 deletions
|
|
@ -12,9 +12,18 @@
|
||||||
|
|
||||||
{.deadCodeElim:on.}
|
{.deadCodeElim:on.}
|
||||||
|
|
||||||
|
import dynlib
|
||||||
|
|
||||||
const
|
const
|
||||||
useWinUnicode* = not defined(useWinAnsi)
|
useWinUnicode* = not defined(useWinAnsi)
|
||||||
|
|
||||||
|
when useWinUnicode:
|
||||||
|
type WinChar* = Utf16Char
|
||||||
|
{.deprecated: [TWinChar: WinChar].}
|
||||||
|
else:
|
||||||
|
type WinChar* = char
|
||||||
|
{.deprecated: [TWinChar: WinChar].}
|
||||||
|
|
||||||
type
|
type
|
||||||
Handle* = int
|
Handle* = int
|
||||||
LONG* = int32
|
LONG* = int32
|
||||||
|
|
@ -74,17 +83,18 @@ type
|
||||||
nFileIndexHigh*: DWORD
|
nFileIndexHigh*: DWORD
|
||||||
nFileIndexLow*: DWORD
|
nFileIndexLow*: DWORD
|
||||||
|
|
||||||
|
OSVERSIONINFO* {.final, pure.} = object
|
||||||
|
dwOSVersionInfoSize*: DWORD
|
||||||
|
dwMajorVersion*: DWORD
|
||||||
|
dwMinorVersion*: DWORD
|
||||||
|
dwBuildNumber*: DWORD
|
||||||
|
dwPlatformId*: DWORD
|
||||||
|
szCSDVersion*: array[0..127, WinChar];
|
||||||
|
|
||||||
{.deprecated: [THandle: Handle, TSECURITY_ATTRIBUTES: SECURITY_ATTRIBUTES,
|
{.deprecated: [THandle: Handle, TSECURITY_ATTRIBUTES: SECURITY_ATTRIBUTES,
|
||||||
TSTARTUPINFO: STARTUPINFO, TPROCESS_INFORMATION: PROCESS_INFORMATION,
|
TSTARTUPINFO: STARTUPINFO, TPROCESS_INFORMATION: PROCESS_INFORMATION,
|
||||||
TFILETIME: FILETIME, TBY_HANDLE_FILE_INFORMATION: BY_HANDLE_FILE_INFORMATION].}
|
TFILETIME: FILETIME, TBY_HANDLE_FILE_INFORMATION: BY_HANDLE_FILE_INFORMATION].}
|
||||||
|
|
||||||
when useWinUnicode:
|
|
||||||
type WinChar* = Utf16Char
|
|
||||||
{.deprecated: [TWinChar: WinChar].}
|
|
||||||
else:
|
|
||||||
type WinChar* = char
|
|
||||||
{.deprecated: [TWinChar: WinChar].}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
STARTF_USESHOWWINDOW* = 1'i32
|
STARTF_USESHOWWINDOW* = 1'i32
|
||||||
STARTF_USESTDHANDLES* = 256'i32
|
STARTF_USESTDHANDLES* = 256'i32
|
||||||
|
|
@ -117,6 +127,13 @@ const
|
||||||
|
|
||||||
CREATE_NO_WINDOW* = 0x08000000'i32
|
CREATE_NO_WINDOW* = 0x08000000'i32
|
||||||
|
|
||||||
|
when useWinUnicode:
|
||||||
|
proc getVersionExW*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExW".}
|
||||||
|
else:
|
||||||
|
proc getVersionExA*(lpVersionInfo: ptr OSVERSIONINFO): WINBOOL {.stdcall, dynlib: "kernel32", importc: "GetVersionExA".}
|
||||||
|
|
||||||
|
proc getVersion*(): DWORD {.stdcall, dynlib: "kernel32", importc: "GetVersion".}
|
||||||
|
|
||||||
proc closeHandle*(hObject: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
|
proc closeHandle*(hObject: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
|
||||||
importc: "CloseHandle".}
|
importc: "CloseHandle".}
|
||||||
|
|
||||||
|
|
@ -192,6 +209,9 @@ proc flushFileBuffers*(hFile: Handle): WINBOOL {.stdcall, dynlib: "kernel32",
|
||||||
proc getLastError*(): int32 {.importc: "GetLastError",
|
proc getLastError*(): int32 {.importc: "GetLastError",
|
||||||
stdcall, dynlib: "kernel32".}
|
stdcall, dynlib: "kernel32".}
|
||||||
|
|
||||||
|
proc setLastError*(error: int32) {.importc: "SetLastError",
|
||||||
|
stdcall, dynlib: "kernel32".}
|
||||||
|
|
||||||
when useWinUnicode:
|
when useWinUnicode:
|
||||||
proc formatMessageW*(dwFlags: int32, lpSource: pointer,
|
proc formatMessageW*(dwFlags: int32, lpSource: pointer,
|
||||||
dwMessageId, dwLanguageId: int32,
|
dwMessageId, dwLanguageId: int32,
|
||||||
|
|
@ -597,9 +617,6 @@ proc freeaddrinfo*(ai: ptr AddrInfo) {.
|
||||||
proc inet_ntoa*(i: InAddr): cstring {.
|
proc inet_ntoa*(i: InAddr): cstring {.
|
||||||
stdcall, importc, dynlib: ws2dll.}
|
stdcall, importc, dynlib: ws2dll.}
|
||||||
|
|
||||||
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
|
|
||||||
stringBufSize: int32): cstring {.stdcall, importc, dynlib: ws2dll.}
|
|
||||||
|
|
||||||
const
|
const
|
||||||
MAXIMUM_WAIT_OBJECTS* = 0x00000040
|
MAXIMUM_WAIT_OBJECTS* = 0x00000040
|
||||||
|
|
||||||
|
|
@ -645,6 +662,7 @@ const
|
||||||
const
|
const
|
||||||
ERROR_ACCESS_DENIED* = 5
|
ERROR_ACCESS_DENIED* = 5
|
||||||
ERROR_HANDLE_EOF* = 38
|
ERROR_HANDLE_EOF* = 38
|
||||||
|
ERROR_BAD_ARGUMENTS* = 165
|
||||||
|
|
||||||
proc duplicateHandle*(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
|
proc duplicateHandle*(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
|
||||||
hTargetProcessHandle: HANDLE,
|
hTargetProcessHandle: HANDLE,
|
||||||
|
|
@ -806,3 +824,54 @@ proc getSystemTimes*(lpIdleTime, lpKernelTime,
|
||||||
proc getProcessTimes*(hProcess: Handle; lpCreationTime, lpExitTime,
|
proc getProcessTimes*(hProcess: Handle; lpCreationTime, lpExitTime,
|
||||||
lpKernelTime, lpUserTime: var FILETIME): WINBOOL {.stdcall,
|
lpKernelTime, lpUserTime: var FILETIME): WINBOOL {.stdcall,
|
||||||
dynlib: "kernel32", importc: "GetProcessTimes".}
|
dynlib: "kernel32", importc: "GetProcessTimes".}
|
||||||
|
|
||||||
|
type inet_ntop_proc = proc(family: cint, paddr: pointer, pStringBuffer: cstring,
|
||||||
|
stringBufSize: int32): cstring {.stdcall.}
|
||||||
|
|
||||||
|
var inet_ntop_real: inet_ntop_proc = nil
|
||||||
|
|
||||||
|
let l = loadLib(ws2dll)
|
||||||
|
if l != nil:
|
||||||
|
inet_ntop_real = cast[inet_ntop_proc](symAddr(l, "inet_ntop"))
|
||||||
|
|
||||||
|
proc WSAAddressToStringA(pAddr: ptr SockAddr, addrSize: DWORD, unused: pointer, pBuff: cstring, pBuffSize: ptr DWORD): cint {.stdcall, importc, dynlib: ws2dll.}
|
||||||
|
proc inet_ntop_emulated(family: cint, paddr: pointer, pStringBuffer: cstring,
|
||||||
|
stringBufSize: int32): cstring {.stdcall.} =
|
||||||
|
case family
|
||||||
|
of AF_INET:
|
||||||
|
var sa: Sockaddr_in
|
||||||
|
sa.sin_family = AF_INET
|
||||||
|
sa.sin_addr = cast[ptr InAddr](paddr)[]
|
||||||
|
var bs = stringBufSize.DWORD
|
||||||
|
let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
|
||||||
|
if r != 0:
|
||||||
|
result = nil
|
||||||
|
else:
|
||||||
|
result = pStringBuffer
|
||||||
|
of AF_INET6:
|
||||||
|
var sa: Sockaddr_in6
|
||||||
|
sa.sin6_family = AF_INET6
|
||||||
|
sa.sin6_addr = cast[ptr In6_addr](paddr)[]
|
||||||
|
var bs = stringBufSize.DWORD
|
||||||
|
let r = WSAAddressToStringA(cast[ptr SockAddr](sa.addr), sa.sizeof.DWORD, nil, pStringBuffer, bs.addr)
|
||||||
|
if r != 0:
|
||||||
|
result = nil
|
||||||
|
else:
|
||||||
|
result = pStringBuffer
|
||||||
|
else:
|
||||||
|
setLastError(ERROR_BAD_ARGUMENTS)
|
||||||
|
result = nil
|
||||||
|
|
||||||
|
proc inet_ntop*(family: cint, paddr: pointer, pStringBuffer: cstring,
|
||||||
|
stringBufSize: int32): cstring {.stdcall.} =
|
||||||
|
var ver: OSVERSIONINFO
|
||||||
|
ver.dwOSVersionInfoSize = sizeof(ver).DWORD
|
||||||
|
let res = when useWinUnicode: getVersionExW(ver.addr) else: getVersionExA(ver.addr)
|
||||||
|
if res == 0:
|
||||||
|
result = nil
|
||||||
|
elif ver.dwMajorVersion >= 6:
|
||||||
|
if inet_ntop_real == nil:
|
||||||
|
quit("Can't load inet_ntop proc from " & ws2dll)
|
||||||
|
result = inet_ntop_real(family, paddr, pStringBuffer, stringBufSize)
|
||||||
|
else:
|
||||||
|
result = inet_ntop_emulated(family, paddr, pStringBuffer, stringBufSize)
|
||||||
|
|
|
||||||
39
tests/stdlib/tnet_ll.nim
Normal file
39
tests/stdlib/tnet_ll.nim
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
discard """
|
||||||
|
action: run
|
||||||
|
"""
|
||||||
|
|
||||||
|
when defined(windows):
|
||||||
|
import winlean
|
||||||
|
elif defined(posix):
|
||||||
|
import posix
|
||||||
|
else:
|
||||||
|
{.error: "Unsupported OS".}
|
||||||
|
|
||||||
|
import unittest, strutils
|
||||||
|
|
||||||
|
suite "inet_ntop tests":
|
||||||
|
|
||||||
|
setup:
|
||||||
|
when defined(windows):
|
||||||
|
var wsa: WSAData
|
||||||
|
discard wsaStartup(0x101'i16, wsa.addr)
|
||||||
|
|
||||||
|
test "IP V4":
|
||||||
|
var ip4 = 0x10111213
|
||||||
|
var buff: array[0..255, char]
|
||||||
|
let r = inet_ntop(AF_INET, ip4.addr, buff[0].addr, buff.sizeof.int32)
|
||||||
|
let res = if r == nil: "" else: $r
|
||||||
|
check: res == "19.18.17.16"
|
||||||
|
|
||||||
|
|
||||||
|
test "IP V6":
|
||||||
|
when defined(windows):
|
||||||
|
let ipv6Support = (getVersion() and 0xff) > 0x5
|
||||||
|
else:
|
||||||
|
let ipv6Support = true
|
||||||
|
|
||||||
|
var ip6 = [0x1000'u16, 0x1001, 0x2000, 0x2001, 0x3000, 0x3001, 0x4000, 0x4001]
|
||||||
|
var buff: array[0..255, char]
|
||||||
|
let r = inet_ntop(AF_INET6, ip6[0].addr, buff[0].addr, buff.sizeof.int32)
|
||||||
|
let res = if r == nil: "" else: $r
|
||||||
|
check: not ipv6Support or res == "10:110:20:120:30:130:40:140"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue