0
votes

In a Visual FoxPro app using sockets, we are using wsock32.dll and use the htons() function to convert a portnumber to TCP/IP network byte order. It should return an unsigned short between 0 and 65535. When testing this with port 63333 it returns 26103 but after installing the Windows Fall Creators update it returns a bigger value: 16213495.

Sample FoxPro program:

DECLARE INTEGER htons IN "wsock32.dll" INTEGER hostshort
LOCAL portNumber, htonsNumber
portNumber  = 63333
htonsNumber = htons( portNumber )
? htonsNumber

The resulting value should go into a "sockaddr" structure used by the connect() function but there is only space for 2 bytes for the port.

Does anyone know what has happened in this windows update to the wsock32 functions and/or has a suggestion to solve this?

1
It is roughly the same number, 0xF765F7 instead of 0x65F7. Perhaps you've been getting away with a bad declaration for a very long time, htos() uses a 16-bit unsigned argument and return value. Not INTEGER. And-ing it with 0xFFFF ought to be a workaround. - Hans Passant
Its documentation shows that the return value should be a unsigned short, not an integer. I would try declare short ... (BTW in creators update I get 26103 without any change to code). - Cetin Basoz
Thanks guys. Declaring it as SHORT results in the same value. Calculating the modulus of the returned value when dived by 0xFFFF+1 does solve the problem for now: MOD(htonsNumber, 65536) I might need to look at new IPv6 structure for future use. - Gert

1 Answers

0
votes

I compared the Windows 10 FCU function with Windows 8 and Windows has reordered the register usage and saved one AND instruction. This is most likely a compiler optimization and not a source code change. Because the left-shifted half is not masked you get garbage in bits 16-23 but these bits should be ignored. The function is still correct for anyone that follows the Windows ABI.

The best solution is to update the function declaration so it uses a 16-bit integer type. If that is not possible you can cast the number to a 16-bit type in languages that support casting. The final option is to truncate the value yourself by ANDing with 0xffff:

htonsNumber = BitAnd(htons(portNumber), 0xffff)

SHORT is listed as a valid return type so that should work as well:

DECLARE SHORT htons IN "wsock32.dll" INTEGER