Index: /trunk/src/VBox/Runtime/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Runtime/Makefile.kmk	(revision 96504)
+++ /trunk/src/VBox/Runtime/Makefile.kmk	(revision 96505)
@@ -64,5 +64,7 @@
  LIBRARIES.solaris += RuntimeR0Stub
  LIBRARIES.win += RuntimeR0Stub #RuntimeR3NoCrt
- LIBRARIES.win.x86 += RuntimeR3VccTricks
+ ifndef VBOX_WITH_NOCRT_STATIC
+  LIBRARIES.win.x86 += RuntimeR3VccTricks
+ endif
  include $(PATH_SUB_CURRENT)/tools/Makefile.kmk
  ifdef VBOX_WITH_VALIDATIONKIT_UNITTESTS_PACKING
@@ -125,5 +127,7 @@
   #LIBRARIES.os2 += RuntimeGuestR0OS2Warp3
  endif # VBOX_WITH_ADDITIONS
- LIBRARIES.win.x86 += RuntimeR3VccTricks
+ ifndef VBOX_WITH_NOCRT_STATIC
+  LIBRARIES.win.x86 += RuntimeR3VccTricks
+ endif
  DLLS += VBoxRT
  ifdef VBOX_WITH_32_ON_64_MAIN_API
@@ -2652,15 +2656,17 @@
 	common/time/timesysalias.cpp \
 	VBox/logbackdoor.cpp
-RuntimeGuestR3_DEFS.win.x86              = $(RuntimeR3_DEFS.win.x86) \
-	VCC_FAKES_TARGET_$(VBOX_VCC_TOOL_STEM) VCC_FAKES_TARGET=$(substr $(VBOX_VCC_TOOL_STEM),-3)
-RuntimeGuestR3_SOURCES.win.x86           = $(RuntimeR3_SOURCES.win.x86) \
-	r3/win/vcc-fakes-kernel32.cpp \
-	r3/win/vcc-fakes-kernel32-A.asm \
-	r3/win/vcc-fakes-ntdll.cpp \
-	r3/win/vcc-fakes-ntdll-A.asm \
-	r3/win/vcc-fakes-ws2_32.cpp \
-	r3/win/vcc-fakes-ws2_32-A.asm \
-	r3/win/vcc-fakes-shell32.cpp \
-	r3/win/vcc-fakes-shell32-A.asm \
+ifndef VBOX_WITH_NOCRT_STATIC
+ RuntimeGuestR3_DEFS.win.x86             = $(RuntimeR3_DEFS.win.x86) \
+ 	VCC_FAKES_TARGET_$(VBOX_VCC_TOOL_STEM) VCC_FAKES_TARGET=$(substr $(VBOX_VCC_TOOL_STEM),-3)
+ RuntimeGuestR3_SOURCES.win.x86          = $(RuntimeR3_SOURCES.win.x86) \
+ 	r3/win/vcc-fakes-kernel32.cpp \
+ 	r3/win/vcc-fakes-kernel32-A.asm \
+ 	r3/win/vcc-fakes-ntdll.cpp \
+ 	r3/win/vcc-fakes-ntdll-A.asm \
+ 	r3/win/vcc-fakes-ws2_32.cpp \
+ 	r3/win/vcc-fakes-ws2_32-A.asm \
+ 	r3/win/vcc-fakes-shell32.cpp \
+ 	r3/win/vcc-fakes-shell32-A.asm
+endif
 
 
@@ -4352,13 +4358,15 @@
 # early XP and early W2K3.  Used by validation kit.
 #
-RuntimeR3VccTricks_TEMPLATE = VBoxR3Static
-RuntimeR3VccTricks_DEFS     = VCC_FAKES_TARGET_$(VBOX_VCC_TOOL_STEM) VCC_FAKES_TARGET=$(substr $(VBOX_VCC_TOOL_STEM),-3)
-RuntimeR3VccTricks_SOURCES  = \
-	r3/win/vcc-fakes-kernel32.cpp \
-	r3/win/vcc-fakes-kernel32-A.asm \
-	r3/win/vcc-fakes-shell32.cpp \
-	r3/win/vcc-fakes-shell32-A.asm \
-	r3/win/vcc-fakes-ntdll.cpp \
-	r3/win/vcc-fakes-ntdll-A.asm
+ifndef VBOX_WITH_NOCRT_STATIC
+ RuntimeR3VccTricks_TEMPLATE = VBoxR3Static
+ RuntimeR3VccTricks_DEFS     = VCC_FAKES_TARGET_$(VBOX_VCC_TOOL_STEM) VCC_FAKES_TARGET=$(substr $(VBOX_VCC_TOOL_STEM),-3)
+ RuntimeR3VccTricks_SOURCES  = \
+ 	r3/win/vcc-fakes-kernel32.cpp \
+ 	r3/win/vcc-fakes-kernel32-A.asm \
+ 	r3/win/vcc-fakes-shell32.cpp \
+ 	r3/win/vcc-fakes-shell32-A.asm \
+ 	r3/win/vcc-fakes-ntdll.cpp \
+ 	r3/win/vcc-fakes-ntdll-A.asm
+endif
 
 if defined(VBOX_WITH_MORE_NT4_COMPAT_BINARIES) && "$(KBUILD_TARGET).$(KBUILD_TARGET_ARCH)" == "win.x86" # Ugly hacks... :-)
Index: /trunk/src/VBox/Runtime/r3/win/fileaio-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/fileaio-win.cpp	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/fileaio-win.cpp	(revision 96505)
@@ -51,4 +51,6 @@
 
 #include <iprt/win/windows.h>
+
+#include "internal-r3-win.h"
 
 
@@ -283,29 +285,31 @@
 RTDECL(int) RTFileAioCtxCreate(PRTFILEAIOCTX phAioCtx, uint32_t cAioReqsMax, uint32_t fFlags)
 {
-    PRTFILEAIOCTXINTERNAL pCtxInt;
     AssertPtrReturn(phAioCtx, VERR_INVALID_POINTER);
     AssertReturn(!(fFlags & ~RTFILEAIOCTX_FLAGS_VALID_MASK), VERR_INVALID_PARAMETER);
     RT_NOREF_PV(cAioReqsMax);
 
-    pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOCTXINTERNAL));
-    if (RT_UNLIKELY(!pCtxInt))
-        return VERR_NO_MEMORY;
-
-    pCtxInt->hIoCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
-                                                        NULL,
-                                                        0,
-                                                        0);
-    if (RT_UNLIKELY(!pCtxInt->hIoCompletionPort))
+    if (   g_pfnCreateIoCompletionPort
+        && g_pfnGetQueuedCompletionStatus
+        && g_pfnPostQueuedCompletionStatus)
     {
-        RTMemFree(pCtxInt);
-        return VERR_NO_MEMORY;
+        PRTFILEAIOCTXINTERNAL pCtxInt = (PRTFILEAIOCTXINTERNAL)RTMemAllocZ(sizeof(RTFILEAIOCTXINTERNAL));
+        if (RT_UNLIKELY(!pCtxInt))
+            return VERR_NO_MEMORY;
+
+        pCtxInt->hIoCompletionPort = g_pfnCreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+        if (RT_UNLIKELY(!pCtxInt->hIoCompletionPort))
+        {
+            RTMemFree(pCtxInt);
+            return VERR_NO_MEMORY;
+        }
+
+        pCtxInt->fFlags   = fFlags;
+        pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
+
+        *phAioCtx = (RTFILEAIOCTX)pCtxInt;
+
+        return VINF_SUCCESS;
     }
-
-    pCtxInt->fFlags   = fFlags;
-    pCtxInt->u32Magic = RTFILEAIOCTX_MAGIC;
-
-    *phAioCtx = (RTFILEAIOCTX)pCtxInt;
-
-    return VINF_SUCCESS;
+    return VERR_NOT_SUPPORTED;
 }
 
@@ -331,13 +335,19 @@
 RTDECL(int) RTFileAioCtxAssociateWithFile(RTFILEAIOCTX hAioCtx, RTFILE hFile)
 {
-    int rc = VINF_SUCCESS;
     PRTFILEAIOCTXINTERNAL pCtxInt = hAioCtx;
     RTFILEAIOCTX_VALID_RETURN(pCtxInt);
 
-    HANDLE hTemp = CreateIoCompletionPort((HANDLE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
-    if (hTemp != pCtxInt->hIoCompletionPort)
-        rc = RTErrConvertFromWin32(GetLastError());
-
-    return rc;
+    if (   g_pfnCreateIoCompletionPort
+        && g_pfnGetQueuedCompletionStatus
+        && g_pfnPostQueuedCompletionStatus)
+    {
+        int rc = VINF_SUCCESS;
+        HANDLE hTemp = g_pfnCreateIoCompletionPort((HANDLE)RTFileToNative(hFile), pCtxInt->hIoCompletionPort, 0, 1);
+        if (hTemp != pCtxInt->hIoCompletionPort)
+            rc = RTErrConvertFromWin32(GetLastError());
+
+        return rc;
+    }
+    return VERR_NOT_SUPPORTED;
 }
 
@@ -445,9 +455,9 @@
 
         ASMAtomicXchgBool(&pCtxInt->fWaiting, true);
-        fSucceeded = GetQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
-                                               &cbTransfered,
-                                               &lCompletionKey,
-                                               &pOverlapped,
-                                               dwTimeout);
+        fSucceeded = g_pfnGetQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
+                                                    &cbTransfered,
+                                                    &lCompletionKey,
+                                                    &pOverlapped,
+                                                    dwTimeout);
         ASMAtomicXchgBool(&pCtxInt->fWaiting, false);
         if (   !fSucceeded
@@ -532,7 +542,7 @@
         && fWaiting)
     {
-        BOOL fSucceeded = PostQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
-                                                     0, AIO_CONTEXT_WAKEUP_EVENT,
-                                                     NULL);
+        BOOL fSucceeded = g_pfnPostQueuedCompletionStatus(pCtxInt->hIoCompletionPort,
+                                                          0, AIO_CONTEXT_WAKEUP_EVENT,
+                                                          NULL);
 
         if (!fSucceeded)
Index: /trunk/src/VBox/Runtime/r3/win/init-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/init-win.cpp	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/init-win.cpp	(revision 96505)
@@ -94,4 +94,9 @@
 DECL_HIDDEN_DATA(decltype(IsDebuggerPresent) *)                 g_pfnIsDebuggerPresent = NULL;
 DECL_HIDDEN_DATA(decltype(GetSystemTimeAsFileTime) *)           g_pfnGetSystemTimeAsFileTime = NULL;
+DECL_HIDDEN_DATA(decltype(GetProcessAffinityMask) *)            g_pfnGetProcessAffinityMask = NULL;
+DECL_HIDDEN_DATA(decltype(SetThreadAffinityMask) *)             g_pfnSetThreadAffinityMask = NULL;
+DECL_HIDDEN_DATA(decltype(CreateIoCompletionPort) *)            g_pfnCreateIoCompletionPort = NULL;
+DECL_HIDDEN_DATA(decltype(GetQueuedCompletionStatus) *)         g_pfnGetQueuedCompletionStatus = NULL;
+DECL_HIDDEN_DATA(decltype(PostQueuedCompletionStatus) *)        g_pfnPostQueuedCompletionStatus = NULL;
 
 /** The native ntdll.dll handle. */
@@ -568,13 +573,24 @@
         g_pfnGetSystemWindowsDirectoryW  = (PFNGETWINSYSDIR)GetProcAddress(g_hModKernel32, "GetWindowsDirectoryW");
     g_pfnSystemTimeToTzSpecificLocalTime = (decltype(SystemTimeToTzSpecificLocalTime) *)GetProcAddress(g_hModKernel32, "SystemTimeToTzSpecificLocalTime");
-    g_pfnCreateWaitableTimerExW     = (PFNCREATEWAITABLETIMEREX)           GetProcAddress(g_hModKernel32, "CreateWaitableTimerExW");
-    g_pfnGetHandleInformation       = (decltype(GetHandleInformation) *)   GetProcAddress(g_hModKernel32, "GetHandleInformation");
-    g_pfnSetHandleInformation       = (decltype(SetHandleInformation) *)   GetProcAddress(g_hModKernel32, "SetHandleInformation");
-    g_pfnIsDebuggerPresent          = (decltype(IsDebuggerPresent) *)      GetProcAddress(g_hModKernel32, "IsDebuggerPresent");
-    g_pfnGetSystemTimeAsFileTime    = (decltype(GetSystemTimeAsFileTime) *)GetProcAddress(g_hModKernel32, "GetSystemTimeAsFileTime");
-    Assert(g_pfnSetHandleInformation    || g_enmWinVer < kRTWinOSType_NT351);
-    Assert(g_pfnGetHandleInformation    || g_enmWinVer < kRTWinOSType_NT351);
-    Assert(g_pfnIsDebuggerPresent       || g_enmWinVer < kRTWinOSType_NT4);
-    Assert(g_pfnGetSystemTimeAsFileTime || g_enmWinVer < kRTWinOSType_NT4);
+    g_pfnCreateWaitableTimerExW     = (PFNCREATEWAITABLETIMEREX)              GetProcAddress(g_hModKernel32, "CreateWaitableTimerExW");
+    g_pfnGetHandleInformation       = (decltype(GetHandleInformation) *)      GetProcAddress(g_hModKernel32, "GetHandleInformation");
+    g_pfnSetHandleInformation       = (decltype(SetHandleInformation) *)      GetProcAddress(g_hModKernel32, "SetHandleInformation");
+    g_pfnIsDebuggerPresent          = (decltype(IsDebuggerPresent) *)         GetProcAddress(g_hModKernel32, "IsDebuggerPresent");
+    g_pfnGetSystemTimeAsFileTime    = (decltype(GetSystemTimeAsFileTime) *)   GetProcAddress(g_hModKernel32, "GetSystemTimeAsFileTime");
+    g_pfnGetProcessAffinityMask     = (decltype(GetProcessAffinityMask) *)    GetProcAddress(g_hModKernel32, "GetProcessAffinityMask");
+    g_pfnSetThreadAffinityMask      = (decltype(SetThreadAffinityMask) *)     GetProcAddress(g_hModKernel32, "SetThreadAffinityMask");
+    g_pfnCreateIoCompletionPort     = (decltype(CreateIoCompletionPort) *)    GetProcAddress(g_hModKernel32, "CreateIoCompletionPort");
+    g_pfnGetQueuedCompletionStatus  = (decltype(GetQueuedCompletionStatus) *) GetProcAddress(g_hModKernel32, "GetQueuedCompletionStatus");
+    g_pfnPostQueuedCompletionStatus = (decltype(PostQueuedCompletionStatus) *)GetProcAddress(g_hModKernel32, "PostQueuedCompletionStatus");
+
+    Assert(g_pfnGetHandleInformation       || g_enmWinVer < kRTWinOSType_NT351);
+    Assert(g_pfnSetHandleInformation       || g_enmWinVer < kRTWinOSType_NT351);
+    Assert(g_pfnIsDebuggerPresent          || g_enmWinVer < kRTWinOSType_NT4);
+    Assert(g_pfnGetSystemTimeAsFileTime    || g_enmWinVer < kRTWinOSType_NT4);
+    Assert(g_pfnGetProcessAffinityMask     || g_enmWinVer < kRTWinOSType_NT350);
+    Assert(g_pfnSetThreadAffinityMask      || g_enmWinVer < kRTWinOSType_NT350);
+    Assert(g_pfnCreateIoCompletionPort     || g_enmWinVer < kRTWinOSType_NT350);
+    Assert(g_pfnGetQueuedCompletionStatus  || g_enmWinVer < kRTWinOSType_NT350);
+    Assert(g_pfnPostQueuedCompletionStatus || g_enmWinVer < kRTWinOSType_NT350);
 
     /*
Index: /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/internal-r3-win.h	(revision 96505)
@@ -117,13 +117,16 @@
 typedef UINT (WINAPI *PFNGETWINSYSDIR)(LPWSTR,UINT);
 extern DECL_HIDDEN_DATA(PFNGETWINSYSDIR)                                g_pfnGetSystemWindowsDirectoryW;
-extern DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *)    g_pfnSystemTimeToTzSpecificLocalTime;
 typedef HANDLE (WINAPI *PFNCREATEWAITABLETIMEREX)(LPSECURITY_ATTRIBUTES, LPCWSTR, DWORD, DWORD);
 extern DECL_HIDDEN_DATA(PFNCREATEWAITABLETIMEREX)                       g_pfnCreateWaitableTimerExW;
+extern DECL_HIDDEN_DATA(decltype(SystemTimeToTzSpecificLocalTime) *)    g_pfnSystemTimeToTzSpecificLocalTime;
 extern DECL_HIDDEN_DATA(decltype(GetHandleInformation) *)               g_pfnGetHandleInformation;
 extern DECL_HIDDEN_DATA(decltype(SetHandleInformation) *)               g_pfnSetHandleInformation;
 extern DECL_HIDDEN_DATA(decltype(IsDebuggerPresent) *)                  g_pfnIsDebuggerPresent;
 extern DECL_HIDDEN_DATA(decltype(GetSystemTimeAsFileTime) *)            g_pfnGetSystemTimeAsFileTime;
-typedef UINT (WINAPI *PFNGETWINSYSDIR)(LPWSTR,UINT);
-extern DECL_HIDDEN_DATA(PFNGETWINSYSDIR)                                g_pfnGetSystemWindowsDirectoryW;
+extern DECL_HIDDEN_DATA(decltype(GetProcessAffinityMask) *)             g_pfnGetProcessAffinityMask;
+extern DECL_HIDDEN_DATA(decltype(SetThreadAffinityMask) *)              g_pfnSetThreadAffinityMask;
+extern DECL_HIDDEN_DATA(decltype(CreateIoCompletionPort) *)             g_pfnCreateIoCompletionPort;
+extern DECL_HIDDEN_DATA(decltype(GetQueuedCompletionStatus) *)          g_pfnGetQueuedCompletionStatus;
+extern DECL_HIDDEN_DATA(decltype(PostQueuedCompletionStatus) *)         g_pfnPostQueuedCompletionStatus;
 
 
Index: /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/localipc-win.cpp	(revision 96505)
@@ -2,4 +2,7 @@
 /** @file
  * IPRT - Local IPC, Windows Implementation Using Named Pipes.
+ *
+ * @note This code only works on W2K because of the dependency on
+ *       ConvertStringSecurityDescriptorToSecurityDescriptor.
  */
 
@@ -40,17 +43,12 @@
 *********************************************************************************************************************************/
 #define LOG_GROUP RTLOGGROUP_LOCALIPC
-/*
- * We have to force NT 5.0 here because of
- * ConvertStringSecurityDescriptorToSecurityDescriptor. Note that because of
- * FILE_FLAG_FIRST_PIPE_INSTANCE this code actually requires W2K SP2+.
- */
-#ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0500 /* for ConvertStringSecurityDescriptorToSecurityDescriptor */
-#elif _WIN32_WINNT < 0x0500
-# undef _WIN32_WINNT
-# define _WIN32_WINNT 0x0500
+#ifdef _WIN32_WINNT
+# if _WIN32_WINNT < 0x0500
+#  undef _WIN32_WINNT
+#  define _WIN32_WINNT 0x0500       /* For ConvertStringSecurityDescriptorToSecurityDescriptor. */
+# endif
 #endif
-#define UNICODE    /* For the SDDL_ strings. */
-#include <iprt/win/windows.h>
+#define UNICODE                     /* For the SDDL_ strings. */
+#include <iprt/nt/nt-and-windows.h> /* Need NtCancelIoFile */
 #include <sddl.h>
 
@@ -238,5 +236,5 @@
  * @param   fServer             Whether it's for a server or client instance.
  */
-static int rtLocalIpcServerWinAllocSecurityDescriptior(PSECURITY_DESCRIPTOR *ppDesc, bool fServer)
+static int rtLocalIpcServerWinAllocSecurityDescriptor(PSECURITY_DESCRIPTOR *ppDesc, bool fServer)
 {
     /*
@@ -298,5 +296,5 @@
 
     PSECURITY_DESCRIPTOR pSecDesc;
-    int rc = rtLocalIpcServerWinAllocSecurityDescriptior(&pSecDesc, fFirst /* Server? */);
+    int rc = rtLocalIpcServerWinAllocSecurityDescriptor(&pSecDesc, fFirst /* Server? */);
     if (RT_SUCCESS(rc))
     {
@@ -671,5 +669,9 @@
                 fRc = DisconnectNamedPipe(pThis->hNmPipe);
             else if (dwErr == ERROR_IO_PENDING)
-                fRc = CancelIo(pThis->hNmPipe);
+            {
+                IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+                NTSTATUS rcNt = NtCancelIoFile(pThis->hNmPipe, &Ios);
+                fRc = NT_SUCCESS(rcNt);
+            }
             else
                 fRc = TRUE;
@@ -825,5 +827,5 @@
              */
             PSECURITY_DESCRIPTOR pSecDesc;
-            rc = rtLocalIpcServerWinAllocSecurityDescriptior(&pSecDesc, false /*fServer*/);
+            rc = rtLocalIpcServerWinAllocSecurityDescriptor(&pSecDesc, false /*fServer*/);
             if (RT_SUCCESS(rc))
             {
@@ -897,10 +899,14 @@
 
     /*
-     * Call CancelIo since this call cancels both read and write oriented operations.
+     * Call NtCancelIoFile since this call cancels both read and write
+     * oriented operations.
      */
     if (   pThis->fZeroByteRead
         || pThis->Read.hActiveThread != NIL_RTTHREAD
         || pThis->Write.hActiveThread != NIL_RTTHREAD)
-        CancelIo(pThis->hNmPipe);
+    {
+        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+        NtCancelIoFile(pThis->hNmPipe, &Ios);
+    }
 
     /*
@@ -1036,9 +1042,10 @@
  * The zero byte read is started by the RTLocalIpcSessionWaitForData method and
  * left pending when the function times out.  This saves us the problem of
- * CancelIo messing with all active I/O operations and the trouble of restarting
- * the zero byte read the next time the method is called.  However should
- * RTLocalIpcSessionRead be called after a failed RTLocalIpcSessionWaitForData
- * call, the zero byte read will still be pending and it must wait for it to
- * complete before the OVERLAPPEDIO structure can be reused.
+ * NtCancelIoFile messing with all active I/O operations and the trouble of
+ * restarting the zero byte read the next time the method is called.  However
+ * should RTLocalIpcSessionRead be called after a failed
+ * RTLocalIpcSessionWaitForData call, the zero byte read will still be pending
+ * and it must wait for it to complete before the OVERLAPPEDIO structure can be
+ * reused.
  *
  * Thus, both functions will do WaitForSingleObject and share this routine to
Index: /trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/ntdll-mini-implib.def	(revision 96505)
@@ -44,4 +44,5 @@
     NtAlertThread                         ;;= _NtAlertThread@4
     NtAllocateVirtualMemory               ;;= _NtAllocateVirtualMemory@24
+    NtCancelIoFile                        ;;= _NtCancelIoFile@8
     NtClearEvent                          ;;= _NtClearEvent@4
     NtClose                               ;;= _NtClose@4
Index: /trunk/src/VBox/Runtime/r3/win/pipe-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/pipe-win.cpp	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/pipe-win.cpp	(revision 96505)
@@ -612,6 +612,12 @@
                 RTCritSectLeave(&pThis->CritSect);
 
-                if (!CancelIo(pThis->hPipe))
+                /* We use NtCancelIoFile here because the CancelIo API
+                   providing access to it wasn't available till NT4.  This
+                   code needs to work (or at least load) with NT 3.1 */
+                IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+                NTSTATUS rcNt = NtCancelIoFile(pThis->hPipe, &Ios);
+                if (!NT_SUCCESS(rcNt))
                     WaitForSingleObject(pThis->Overlapped.hEvent, INFINITE);
+
                 if (GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/))
                 {
@@ -1162,5 +1168,8 @@
                 pThis->fIOPending = false;
                 if (rc != VINF_SUCCESS)
-                    CancelIo(pThis->hPipe);
+                {
+                    IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+                    NtCancelIoFile(pThis->hPipe, &Ios);
+                }
                 DWORD cbRead = 0;
                 GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/);
@@ -1501,5 +1510,7 @@
     if (pThis->fZeroByteRead)
     {
-        CancelIo(pThis->hPipe);
+        IO_STATUS_BLOCK Ios = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+        NtCancelIoFile(pThis->hPipe, &Ios);
+
         DWORD cbRead = 0;
         if (   !GetOverlappedResult(pThis->hPipe, &pThis->Overlapped, &cbRead, TRUE /*fWait*/)
Index: /trunk/src/VBox/Runtime/r3/win/thread-win.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r3/win/thread-win.cpp	(revision 96504)
+++ /trunk/src/VBox/Runtime/r3/win/thread-win.cpp	(revision 96505)
@@ -478,12 +478,18 @@
 RTR3DECL(int) RTThreadSetAffinity(PCRTCPUSET pCpuSet)
 {
-    DWORD_PTR fNewMask = pCpuSet ? RTCpuSetToU64(pCpuSet) : ~(DWORD_PTR)0;
-    DWORD_PTR dwRet = SetThreadAffinityMask(GetCurrentThread(), fNewMask);
-    if (dwRet)
-        return VINF_SUCCESS;
-
-    int iLastError = GetLastError();
-    AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
-    return RTErrConvertFromWin32(iLastError);
+    /* The affinity functionality was added in NT 3.50, so we resolve the APIs
+       dynamically to be able to run on NT 3.1. */
+    if (g_pfnSetThreadAffinityMask)
+    {
+        DWORD_PTR fNewMask = pCpuSet ? RTCpuSetToU64(pCpuSet) : ~(DWORD_PTR)0;
+        DWORD_PTR dwRet = g_pfnSetThreadAffinityMask(GetCurrentThread(), fNewMask);
+        if (dwRet)
+            return VINF_SUCCESS;
+
+        int iLastError = GetLastError();
+        AssertMsgFailed(("SetThreadAffinityMask failed, LastError=%d\n", iLastError));
+        return RTErrConvertFromWin32(iLastError);
+    }
+    return VERR_NOT_SUPPORTED;
 }
 
@@ -491,26 +497,33 @@
 RTR3DECL(int) RTThreadGetAffinity(PRTCPUSET pCpuSet)
 {
-    /*
-     * Haven't found no query api, but the set api returns the old mask, so let's use that.
-     */
-    DWORD_PTR dwIgnored;
-    DWORD_PTR dwProcAff = 0;
-    if (GetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
-    {
-        HANDLE hThread = GetCurrentThread();
-        DWORD_PTR dwRet = SetThreadAffinityMask(hThread, dwProcAff);
-        if (dwRet)
+    /* The affinity functionality was added in NT 3.50, so we resolve the APIs
+       dynamically to be able to run on NT 3.1. */
+    if (   g_pfnSetThreadAffinityMask
+        && g_pfnGetProcessAffinityMask)
+    {
+        /*
+         * Haven't found no query api, but the set api returns the old mask, so let's use that.
+         */
+        DWORD_PTR dwIgnored;
+        DWORD_PTR dwProcAff = 0;
+        if (g_pfnGetProcessAffinityMask(GetCurrentProcess(), &dwProcAff, &dwIgnored))
         {
-            DWORD_PTR dwSet = SetThreadAffinityMask(hThread, dwRet);
-            Assert(dwSet == dwProcAff); NOREF(dwRet);
-
-            RTCpuSetFromU64(pCpuSet, (uint64_t)dwSet);
-            return VINF_SUCCESS;
+            HANDLE hThread = GetCurrentThread();
+            DWORD_PTR dwRet = g_pfnSetThreadAffinityMask(hThread, dwProcAff);
+            if (dwRet)
+            {
+                DWORD_PTR dwSet = g_pfnSetThreadAffinityMask(hThread, dwRet);
+                Assert(dwSet == dwProcAff); NOREF(dwRet);
+
+                RTCpuSetFromU64(pCpuSet, (uint64_t)dwSet);
+                return VINF_SUCCESS;
+            }
         }
-    }
-
-    int iLastError = GetLastError();
-    AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
-    return RTErrConvertFromWin32(iLastError);
+
+        int iLastError = GetLastError();
+        AssertMsgFailed(("SetThreadAffinityMask or GetProcessAffinityMask failed, LastError=%d\n", iLastError));
+        return RTErrConvertFromWin32(iLastError);
+    }
+    return VERR_NOT_SUPPORTED;
 }
 
