Yet another WinSock trap

| | Comments (3)

For those of you who really enjoy the pain of weak-linking against WinSock, here's another gotcha to watch out for.

We use getaddrinfo as a way to do DNS address lookups from IP addresses. This is a very standard function across any POSIX implementation. Well, except for Windows, in which it only lives in Windows XP and up. If you care to support Windows 2000 or below, you actually have a ton of hoops to jump through.

Now, I will grant the WinSock team this -- they at least made an effort to help people out with backwards compatibility. If you do the magic header file dance properly, then everything works as expected. However, not everyone cares to do that magic dance because not everyone can rely on all the proper DLLs being installed on any given system. You see, if you care about older systems, you can't hard-link against WinSock unless you also plan to distribute the DLLs with your app. This isn't so bad, but in the case of REALbasic, it's a non-starter because we don't want any reliances like that to be passed on to our end users. So, if you weak link, you're screwed.

That's because getaddrinfo doesn't exist in Win2k or less, so Microsoft made an inline replacement which is dynamically loaded the first time the function is called. However, this inline function assumes you're hard-linking in the WinSock functions, so if you're weak linking, you have to do a lot of extra dancing to get things to work.

I attempted to do such a dance this afternoon and got as far as getting everything to compile and link -- but alas, when I ran the code on Windows 2000, the functions still failed. I'm not entirely certain of why that is, but after about four hours of messing around with it, I wasn't too inclined to spend more time trying to figure it out. Perhaps another day I will revisit the problem to see if I can make it work on Windows 2000, but for now: watch out.

3 Comments

Looks like a yawner....better luck next time {s}.

Support for getaddrinfo on older versions of Windows

The getaddrinfo function was added to the Ws2_32.dll on Windows XP and later. If you want to execute an application using this function on earlier versions of Windows (Windows 2000, Windows NT, and Windows Me/98/95), then you need to include the Ws2tcpip.h file and also include the Wspiapi.h file. When the Wspiapi.h include file is added, the getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older Windows platforms that do not natively support the getaddrinfo function.

The IPv6 protocol is supported on Windows 2000 when the IPv6 Technology Preview for Windows 2000 is installed. Otherwise getaddrinfo support on versions of Windows earlier than Windows XP is limited to handling IPv4 name resolution.

The GetAddrInfoW function is the Unicode version of getaddrinfo. The GetAddrInfoW function was added to the Ws2_32.dll in Windows XP SP2. The GetAddrInfoW function cannot be used on versions of Windows earlier than Windows XP SP2.

more info, reads http://msdn2.microsoft.com/en-us/library/ms738520.aspx

While this is good in theory, in practice it doesn't work for dynamic loading of the API. It's the inline implementation which throws a wrench in the process. If you want to dynamically load getaddrinfo, you can do it from the two different DLLs, but in the case where you need to support older systems, you can't dynamically load anything.

Leave a comment

Disclaimer

I'm currently an employee of REAL Software. My blog is mine. The opinions represented in this blog are mine as well and may not represent my employer's opinions. All original material is copyrighted and property of the author.

REALbasic® is a registered trademark of REAL Software, Inc. REAL SQL Server™ and Lingua™ are pending trademarks of REAL Software, Inc. All rights reserved.