Mateusz Loskot :: hacking on, working out, living up

WSAPoll hacks for libcurl

18 Dec 2007 | mloskot

cURL logoContinuing my adventures with Visual C++ 2008, I’d like to share some observations about new WinSock2 features. The Visual C++ 2008 uses new incarnation of Microsoft Platform SDK called Windows SDK (New Windows SDK Available to Download). This SDK is named as for Windows Vista what’s quite misinforming because it also supports development for Windows XP, Windows Server 2003 SP1, and Windows Server 2003 R2.

One of new feature in Winsock API is WSAPoll function. As the MSDN says, this function is is defined on Windows Vista and later. However, if the Windows SDK is used on Windows XP this function is also available when building software but it’s not usable in run-time.

wsapoll-unresolved-winxpThere is Ws2_32.dll available under Windows XP but WSAPoll function is inaccessible what can be tracked down with dependency walker. The screenshot on the right shows dependency walker with loaded gdal15.dll. The gdal15.dll was built with libcurl support and the libcurl was built with WSAPoll function enabled using following definitions in libcurl config-win32.h header:

  • define HAVE_POLL_FINE 1

  • define HAVE_STRUCT_POLLFD 1

The red box next to the WSAPoll function in the parent import function list view says that the function is unresolved, as not exported from the module. IOW, ws2_32.dll under Windows in other version than Vista or later does not export WSAPoll function.

Now, the heart of this matter is why libcurl built using Visual C++ 2008 and Windows SDK under Windows XP refers to WSAPoll function which is not available?

The answer is simple though not obvious. The new SDK forces Windows Vista as default target regardless of what host system is used. The default definitions come from file C:FilesSDKs6.0A.h:

#if !defined(_WIN32_WINNT) && !defined(_CHICAGO_)
#define  _WIN32_WINNT   0x0600
#endif

and a few lines later:

#ifndef WINVER
#ifdef _WIN32_WINNT
// set WINVER based on _WIN32_WINNT
#define WINVER   _WIN32_WINNT
#else
#define WINVER   0x0600
#endif
#endif

The value 0x0600 represents Windows Vista. All macros and version numbers are listed in the MSDN article Using the Windows Headers.

In order to build libcurl using Visual C++ 2008 and Windows SDK but without referencing WSAPoll, I had to manually downgrade target platform to Windows XP by defining necessary macros:

#define WINVER         0x0502
#define _WIN32_WINNT   0x0502
#define _WIN32_WINDOWS 0x0502

I put these definitions on top of the libs-win32.h file but they can be also added to CFLAGS in Makefile.

After this small patch, libcurl rebuild and GDAL rebuild using Visual C++ 2008 + Windows SDK, there is no reference to new but unavailable WSAPoll function under Windows non-Vista.

Just for records, here is Vista patch announcement with the WSAPoll function support for libcurl. I think there is a need for new Makefile.vc9 and configuration option used to select target platform, so uses can libcurl with latest Visual C++ compiler and Windows SDK targetting older Windows versions too.

Fork me on GitHub