*************************************************************************** *** INSTALLATION NOTES FOR QUEUEUSERAPCEX DRIVER INSTALLATION PACKAGE *** *************************************************************************** For full functionality with C++ exceptions, pthreads-win32 requires the QueueUserAPCEx driver. This driver enables true Asynchronous Procedure Calls for client use -- in effect, this allows pthreads-win32 to behave as required by POSIX even when the threads are in "non interruptible" states (because APC's can be called in a thread's context even if the thread is in a kernel or win32 system call that is "not interruptible"). Note that this driver is NOT required by the pthreads implementation that uses the C (setjmp/longjmp) cleanup code. And, provided certain shortcomings are acceptable, it is not STRICTLY required by the C++ exception-handling implementation either. Because compiling the driver and test application requires a fair bit of effort, not to mention downloading and installing 1.8G worth of Microsoft free-as-in-beer tools (Windows Driver Kit, Visual Studio Express 2010, and Windows SDK 7.1), the driver and test applications have been pre-compiled and assembled in an Inno Setup-based installer. Simply double click the installer, and the following files will be installed: Program Files/Pthreads-Win32/QueueUserAPCEx/COPYING_LIB.txt Program Files/Pthreads-Win32/QueueUserAPCEx/testapp.exe (*) Program Files/Pthreads-Win32/QueueUserAPCEx/uninst.exe Windows/system32/drivers/alertdrv.sys (*) (*) The installer is multiplatform; the correct version of these files -- x86, x64, or ia64 -- will be installed. However, only the x86 versions have been tested. In addition, the kernel mode driver will be registered and started automatically (but it will not start automatically every boot; you need to use net start alertsrv to enable it -- or use the Device Manager to change its settings. Starting and Stopping the AlertDrv driver ----------------------------------------- To start the service, log in as Administrator and open a cmd prompt (or launch a cmd prompt using 'Run As Administrator'). Then, either net start alertsrv sc start alertsrv will work. Similarly, to stop the driver: net stop alertsrv sc stop alertsrv To query the driver, you can use sc query alertsrv Making alertdrv.sys start automatically --------------------------------------- 1. Add a new system environment variable devmgr_show_nonpresent_devices and set its value to 1. 2. Launch the Device Manager 3. Click View->Show Hidden Devices 4. Expand Non-Plug and Play Drivers 5. Right-click 'AlertDrv (Pthreads-Win32/QueueUserAPCEx)' and select 'Properties' 6. On the driver tab, you can change the Startup Type. NOTES: ======================== 1. Driver, test app, and installer have been tested on WinXP(32), and Vista(32). The 64bit versions have not been tested. 2. Worse, Windows7 and Server2008 require all kernel mode drivers to be signed by a certified CA, at least in their 64bit incarnations (I'm not sure about the 32bit versions). I don't have a signed certicate with which to sign the driver -- and it IS a kernel mode driver. 3. This installer does NOT provide the client DLL, quserex.dll, or any associated static or import libraries. I intend to provide those in a separate package, and built using free-as-in-speech tools rather that the free-as-in-beer tools used to create the driver. a) The driver must be compiled using MS tools, because it uses SEH __try/__except/__finally constructs. b) Compiling the DLLs with any recent free-as-in-beer VisualStudio introduces dependencies on the non-freely redistributable runtime libraries, like msvcrt90.dll or whatever. If that's okay with you -- or you are already using VS2008 or whatever to build the rest of your projects -- then simply download this source package and roll your own. THAT part is easy. However, to ensure that the mingw.org-provided client library is unencumbered by the Visual Studio runtimes, we will build the client library using mingw.org's gcc (which will link against msvcrt.dll). That dll will be available from mingw.org as a separate download. *************************************************************************** *** BUILD NOTES FOR QUEUEUSERAPCEX DRIVER INSTALLATION PACKAGE *** *************************************************************************** SOURCE PREPARATION ================== There is no online repository OR independent code distribution of QueueUserAPCEx. Each pthreads-w32 ".exe" release package contains a snapshot of the source code (but the .tar release package does not). In addition, the pthreads-w32 ftp site provides an unpacked snapshot of the code: ftp://sourceware.org/pub/pthreads-win32/QueueUserAPCEx/* So, as a starting point, we can use either: wget -nH -r --cut-dirs=2 --random-wait \ ftp://sourceware.org/pub/pthreads-win32/QueueUserAPCEx find QueueUserAPCEx -name "md5.sum" | xargs rm -f OR unzip pthreads-w32-2-8-0-release.exe 'QueueUserAPCEx/*' followed by additional preparation. In this case, assume we followed the second method, but fixed the line endings before patching to make equiv. to ftp snapshot: unzip pthreads-w32-2-8-0-release.exe 'QueueUserAPCEx/*' for f in Readme.txt driver/MAKEFILE driver/Sources driver/alertdrv.c \ driver/alertdrv.rc testapp/QueueUserAPCEx.c \ testapp/QueueUserAPCEx.h testapp/testapp.c user/GNUmakefile \ user/Makefile user/QueueUserAPCEx.c user/QueueUserAPCEx.h do d2u QueueUserAPCEx/$f done patch -p1 < QueueUserAPCEx-2.8.0-to-snapshot20110505.patch Next, we need to patch in order to make compatible with the WDK 7.1.0 (and to fix up a few oversights with regards to explicit __stdcall vs __cdecl decoration). Then, we remove the pre-compiled binaries distributed with the source code: rm -f QueueUserAPCEx/user/quserex.dll rm -f QueueUserAPCEx/user/quserex.lib rm -f QueueUserAPCEx/execs/alertdrv.sys rmdir QueueUserAPCEx/execs/ Note that QueueUserAPCEx/driver/install.bat should not be used. Instead, we provide an InnoSetup-based installer package for the driver, below. Finally, the source tree is ready for (re)packaging: tar cvJf QueueUserAPCEx-20110505.tar.xz QueueUserAPCEx BUILDING THE DRIVER =================== First, you have to install the Windows Driver Kit (which used to be known as the Device Driver Kit or DDK). The currently available version of the WDK (7.1.0) supports only WinXP(32) and later (for 64bit, only Vista and later). So, this procedure will result in two versions of the driver: i386/alertdrv.sys 32bit, for XP and hopefully Vista,W7,and above amd64/alertdrv.sys 64bit, for Windows Server 2003 and hopefully Vista, W7 and above (*) ia64/alertdrv.sys 64bit, for Windows Server 2003 and hopefully Vista, W7 and above (*) While it would be nice to use free (as in speech) tools to build the driver, unfortunately the code uses the Structured Exception Handling (with the non-standard __try, __except, and __finally keywords), which are not yet supported by mingw.org or mingw64's gcc. So, we're stuck with free (as in beer) tools from Microsoft: the Windows Driver Kit. (*) Note that WinXP-64bit is actually based on the 64bit Windows Server 2003 kernel, which is (a) more recent than XP32, but (b) older than Vista64. It is unclear whether amd64/alertdrv.sys will work on XP64. (**) W7 and Server 2008R2 require that kernel mode drivers are signed, using certificate validated by a recognized CA. I don't have one, so the pre-compiled driver is not signed. On the other hand, the driver is not a "kernel mode" driver...so you might be able to install it, and it might work -- or maybe not. :-( In my case, the WDK refused to install on Vista machine. I had to install it in a virtual machine running XP32. However, once I did so the build procedure was straightforward: To build the 32bit version -------------------------- 1. From the Start Menu, choose Start -> All Programs -> Windows Driver Kits -> WDK $YourBuildNumber -> Build Environments -> Windows XP -> "x86 Free Build Environment". 2. This will open a dos box. Change directory to where-ever you unpacked QueueUserAPCEx: cd C://driver 3. build -ceZ This will create QueueUserAPCEx/driver/objfre_wxp_x86/i386/alertdrv.sys To build the 64bit version (amd64) ---------------------------------- The procedure is similar: 1. From the Start Menu, choose Start -> All Programs -> Windows Driver Kits -> WDK $YourBuildNumber -> Build Environments -> Windows Server 2003 -> "x64 Free Build Environment". 2. This will open a dos box. Change directory to where-ever you unpacked QueueUserAPCEx: cd C://driver 3. build -ceZ This will create QueueUserAPCEx/driver/objfre_wnet_amd64/amd64/alertdrv.sys To build the 64bit version (ia64) --------------------------------- And finally... 1. From the Start Menu, choose Start -> All Programs -> Windows Driver Kits -> WDK $YourBuildNumber -> Build Environments -> Windows Server 2003 -> "x64 Free Build Environment". 2. This will open a dos box. Change directory to where-ever you unpacked QueueUserAPCEx: cd C://driver 3. build -ceZ This will create QueueUserAPCEx/driver/objfre_wnet_ia64/ia64/alertdrv.sys Since this is quite an involved procedure, requiring the installation of a 680MB download from MS, the pre-compiled driver binaries have been provided along with this package: tar xvJf QueueUserAPCEx-20110505-driver-precompiled.tar.xz BUILDING THE TEST APPS ====================== QueueUserAPCEx ships a test application (which uses a static version of the QueueUserAPCEx client code). This application can be used to test the driver, in isolation from pthreads-win32. To build the test application using free (as in beer, but not as in speech) tools, I installed the following in my handy XP virtual machine: Visual Studio Express 2010 (C++) http://www.microsoft.com/express/Downloads/#2010-All The express editions include only the "native" compiler (e.g. the x86 vs2010 includes only a c++ compiler for x86, not amd64 or ia64). Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO) http://www.microsoft.com/downloads/en/details.aspx?FamilyID=35AEDA01-421D-4BA5-B44B-543DC8C33A20 This includes the cross compilers for amd64 and ia64 that are the same as the ones delivered with the VS2010 installers, as well as (slightly) updated SDK headers and libs. The C++ runtimes, tho, are the same as those used by VS2010. This SDK supports OS's back to Windows XPsp3 (32bit), and Windows 2003 R2 (64bit) -- which is NOT the same as Windows XP64. However, MSDN says that as long as you don't use "new" APIs, user applications should work on older OS's, so here's hoping. A note about Windows SDK 6.0: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4377f86d-c913-4b5c-b87e-ef72e5b4e065&displaylang=en This is pretty old, but it is the newest one that still definitely supports Windows Server 2003 (aka XP64) -- but I couldn't figure out how to get VS2010 to use its compilers. I could convince it to use the SDK6.0's includes, libs, AND runtime (*) -- but it insisted on using its own compiler -- which, given the cheapskate Express installation, only allowed to build native (e.g. 32bit) versions. (*) By launching an SDK shell, then manually starting VCExpress with the /useenv option. Yuck. Now, again, it would be nice to use free (as in speech) tools here, but I figured since we were already using non-free-as-in-speech for the driver, doing the same thing for the driver test program is reasonable. Note that end users MAY have to install the VS2010 C++ runtime manually in order to run the test application (this is NOT necessary for the driver). The runtime is "redistributable" in the sense that IF you bought VS2010, you are free to pass out copies of the runtime package. However, if you're a cheapskate and are using the free VS2010 Express, then you can NOT do so -- you have to point your users to Microsoft's website, where THEY can get a copy of it themselves. So...I'm pointing you at Microsoft's website: Microsoft Visual C++ 2010 Redistributable Package (x86) http://www.microsoft.com/downloads/en/details.aspx?FamilyID=a7b7a05e-6de6-4d3a-a423-37bf0912db84 Microsoft Visual C++ 2010 Redistributable Package (x64) http://www.microsoft.com/downloads/en/details.aspx?FamilyID=BD512D9E-43C8-4655-81BF-9350143D5867 Microsoft Visual C++ 2010 Redistributable Package (ia64) http://www.microsoft.com/downloads/en/details.aspx?FamilyID=1a2df53a-d8f4-4bfe-be35-152c5d3d0f82 So, to build the test apps, unpack this archive over your original source: tar xvJf QueueUserAPCEx-20110505-testapp-vs2010-project.tar.xz Next, launch Visual Studio Express 2010 C++, and open the solution file QueueUserAPCEx/testapp/testapp.sln Then, simply build each configuration -- Release/Win32 Release/Itanium Release/x64 Since this is quite an involved procedure, requiring the installation of two 700MB downloads from MS, pre-compiled copies of these apps have been provided along with this package: tar xvJf QueueUserAPCEx-20110505-testapp-precompiled.tar.xz BUILDING THE DRIVER INSTALLATION PACKAGE ======================================== After unpacking the following files: QueueUserAPCEx-20110505.tar.xz QueueUserAPCEx-20110505-driver-precompiled.tar.xz QueueUserAPCEx-20110505-testapp-precompiled.tar.xz It's a rather simple matter of running the InnoSetup compiler with the provided script QueueUserAPCEx.iss This will generate: QueueUserAPCEx-install.exe Requires: *ANSI* InnoSetup 5.3.x or above. I recommend the "ISPack", which includes a much better user interface/IDE for InnoSetup. The 5.3.x ISPacks included 'ISTool', while the 5.4.x ISPacks include InnoIDE. Both are better than the stock InnoSetup interface. SOURCE PACKAGE ======================================== Include the following: QueueUserAPCEx-20110505.tar.xz patches-preapplied/QueueUserAPCEx-2.8.0-to-snapshot20110505.patch patches-preapplied/QueueUserAPCEx-patch-driver-for-WDK7.1.0.patch QueueUserAPCEx-20110505-driver-precompiled.tar.xz QueueUserAPCEx-20110505-testapp-precompiled.tar.xz QueueUserAPCEx-20110505-testapp-vs2010-project.tar.xz README.MinGW services.iss devices.iss QueueUserAPCEx.iss