Index: /trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp	(revision 19968)
+++ /trunk/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp	(revision 19969)
@@ -33,7 +33,8 @@
 *******************************************************************************/
 #include "the-nt-kernel.h"
+#include <iprt/assert.h>
 #include <iprt/err.h>
-#include <iprt/assert.h>
 #include <iprt/mp.h>
+#include <iprt/string.h>
 #include "internal/initterm.h"
 #include "internal-r0drv-nt.h"
@@ -50,10 +51,18 @@
  * and update this variable as CPUs comes online. (The code is done already.)
  */
-RTCPUSET g_rtMpNtCpuSet;
+RTCPUSET                    g_rtMpNtCpuSet;
 
 /** ExSetTimerResolution, introduced in W2K. */
-PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
+PFNMYEXSETTIMERRESOLUTION   g_pfnrtNtExSetTimerResolution;
 /** KeFlushQueuedDpcs, introduced in XP. */
-PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+PFNMYKEFLUSHQUEUEDDPCS      g_pfnrtNtKeFlushQueuedDpcs;
+
+/** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */
+uint32_t                    g_offrtNtPbQuantumEnd;
+/** Size of the _KPRCB::QuantumEnd field. 0 if not found. */
+uint32_t                    g_cbrtNtPbQuantumEnd;
+/** Offset of the _KPRCB::DpcQueueDepth field. 0 if not found. */
+uint32_t                    g_offrtNtPbDpcQueueDepth;
+
 
 
@@ -77,4 +86,72 @@
     g_pfnrtNtKeFlushQueuedDpcs = (PFNMYKEFLUSHQUEUEDDPCS)MmGetSystemRoutineAddress(&RoutineName);
 
+    /*
+     * Get some info that might come in handy below.
+     */
+    ULONG MajorVersion = 0;
+    ULONG MinorVersion = 0;
+    ULONG BuildNumber  = 0;
+    PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL);
+
+    KIRQL OldIrql;
+    KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */
+
+    union
+    {
+        uint32_t auRegs[4];
+        char szVendor[4*3+1];
+    } u;
+    ASMCpuId(0, &u.auRegs[3], &u.auRegs[0], &u.auRegs[2], &u.auRegs[1]);
+    u.szVendor[4*3] = '\0';
+
+    /*
+     * Try find _KPRCB::QuantumEnd and possibly also _KPRCB::DpcQueueDepth.
+     */
+    __try
+    {
+        /* HACK ALERT! The offsets are from poking around in windbg. */
+#if defined(RT_ARCH_X86)
+        PKPCR    pPcr   = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
+        uint8_t *pbPrcb = (uint8_t *)pPcr->Prcb;
+
+        if (    BuildNumber == 2600                             /* XP SP2 */
+            &&  !memcmp(&pbPrcb[0x900], &u.szVendor[0], 4*3))
+        {
+            g_offrtNtPbQuantumEnd    = 0x88c;
+            g_cbrtNtPbQuantumEnd     = 4;
+            g_offrtNtPbDpcQueueDepth = 0x870;
+        }
+        /** @todo more */
+        //pbQuantumEnd = (uint8_t volatile *)pPcr->Prcb + 0x1a41;
+
+#elif defined(RT_ARCH_AMD64)
+        PKPCR    pPcr   = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
+        uint8_t *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
+        /** @todo proper detection! */
+        if (pbPrcb[0x3375] <= 1)
+        {
+            g_offrtNtPbQuantumEnd    = 0x3375;
+            g_cbrtNtPbQuantumEnd     = 1;
+            g_offrtNtPbDpcQueueDepth = 0;
+        }
+
+#else
+# error "port me"
+#endif
+    }
+    __except(EXCEPTION_EXECUTE_HANDLER)
+    {
+        g_offrtNtPbQuantumEnd    = 0;
+        g_cbrtNtPbQuantumEnd     = 0;
+        g_offrtNtPbDpcQueueDepth = 0;
+    }
+
+    KeLowerIrql(OldIrql);
+
+#ifndef IN_GUEST /** @todo fix above for all Nt versions. */
+    if (!g_offrtNtPbQuantumEnd && !g_offrtNtPbDpcQueueDepth)
+        DbgPrint("IPRT: Neither _KPRCB::QuantumEnd nor _KPRCB::DpcQueueDepth was not found!\n");
+#endif
+
     return VINF_SUCCESS;
 }
Index: /trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h	(revision 19968)
+++ /trunk/src/VBox/Runtime/r0drv/nt/internal-r0drv-nt.h	(revision 19969)
@@ -46,7 +46,10 @@
 *   Global Variables                                                           *
 *******************************************************************************/
-extern RTCPUSET g_rtMpNtCpuSet;
-extern PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution;
-extern PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs;
+extern RTCPUSET                     g_rtMpNtCpuSet;
+extern PFNMYEXSETTIMERRESOLUTION    g_pfnrtNtExSetTimerResolution;
+extern PFNMYKEFLUSHQUEUEDDPCS       g_pfnrtNtKeFlushQueuedDpcs;
+extern uint32_t                     g_offrtNtPbQuantumEnd;
+extern uint32_t                     g_cbrtNtPbQuantumEnd;
+extern uint32_t                     g_offrtNtPbDpcQueueDepth;
 
 
Index: /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp	(revision 19968)
+++ /trunk/src/VBox/Runtime/r0drv/nt/thread-r0drv-nt.cpp	(revision 19969)
@@ -38,4 +38,6 @@
 #include <iprt/assert.h>
 #include <iprt/asm.h>
+
+#include "internal-r0drv-nt.h"
 
 __BEGIN_DECLS
@@ -92,25 +94,55 @@
     Assert(hThread == NIL_RTTHREAD);
 
-    uint8_t volatile *pbQuantumEnd;
-    RTCCUINTREG       fSavedFlags  = ASMIntDisableFlags();
+    /*
+     * Read the globals and check if they are useful.
+     */
+    uint32_t const offQuantumEnd     = g_offrtNtPbQuantumEnd;
+    uint32_t const cbQuantumEnd      = g_cbrtNtPbQuantumEnd;
+    uint32_t const offDpcQueueDepth  = g_offrtNtPbDpcQueueDepth;
+    if (!offQuantumEnd && !cbQuantumEnd && !offDpcQueueDepth)
+        return false;
+    Assert((offQuantumEnd && cbQuantumEnd) || (!offQuantumEnd && !cbQuantumEnd));
 
-#if   defined(RT_ARCH_X86)
-    /* HACK ALERT! The offset is from ks386.inc. */
-    PKPCR pPcr = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
-    pbQuantumEnd = (uint8_t volatile *)pPcr->Prcb + 0x1a41;
+    /*
+     * Disable interrupts so we won't be messed around.
+     */
+    bool            fPending;
+    RTCCUINTREG     fSavedFlags  = ASMIntDisableFlags();
+
+#ifdef RT_ARCH_X86
+    PKPCR       pPcr   = (PKPCR)__readfsdword(RT_OFFSETOF(KPCR,SelfPcr));
+    uint8_t    *pbPrcb = (uint8_t *)pPcr->Prcb;
 
 #elif defined(RT_ARCH_AMD64)
     /* HACK ALERT! The offset is from windbg/vista64. */
-    PKPCR pPcr = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
-    pbQuantumEnd = (uint8_t volatile *)pPcr->CurrentPrcb + 0x3375;
+    PKPCR       pPcr   = (PKPCR)__readgsqword(RT_OFFSETOF(KPCR,Self));
+    uint8_t    *pbPrcb = (uint8_t *)pPcr->CurrentPrcb;
 
 #else
 # error "port me"
 #endif
-    uint8_t QuantumEnd = *pbQuantumEnd;
+
+    /* Check QuantumEnd. */
+    if (cbQuantumEnd == 1)
+    {
+        uint8_t volatile *pbQuantumEnd = (uint8_t volatile *)(pbPrcb + offQuantumEnd);
+        fPending = *pbQuantumEnd == TRUE;
+    }
+    else if (cbQuantumEnd == sizeof(uint32_t))
+    {
+        uint32_t volatile *pu32QuantumEnd = (uint32_t volatile *)(pbPrcb + offQuantumEnd);
+        fPending = *pu32QuantumEnd != 0;
+    }
+
+    /* Check DpcQueueDepth. */
+    if (    !fPending
+        &&  offDpcQueueDepth)
+    {
+        uint32_t volatile *pu32DpcQueueDepth = (uint32_t volatile *)(pbPrcb + offDpcQueueDepth);
+        fPending = *pu32DpcQueueDepth > 0;
+    }
+
     ASMSetFlags(fSavedFlags);
-
-    AssertMsg(QuantumEnd == FALSE || QuantumEnd == TRUE, ("%x\n", QuantumEnd));
-    return QuantumEnd == TRUE;
+    return fPending;
 }
 
