Index: trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 70145)
+++ trunk/src/VBox/Additions/common/VBoxGuest/Makefile.kmk	(revision 70146)
@@ -255,10 +255,10 @@
 
 ifeq ($(KBUILD_TARGET),win)
-#
-# VBoxGuestInst - The installer.
-#
-#PROGRAMS += VBoxGuestInst
-VBoxGuestInst_TEMPLATE= VBoxGuestR3Exe
-VBoxGuestInst_SOURCES = win/VBoxGuestInst.cpp
+ #
+ # VBoxGuestInst - The installer.
+ #
+ PROGRAMS.win.x86 += VBoxGuestInstNT
+ VBoxGuestInstNT_TEMPLATE = VBoxGuestR3Exe
+ VBoxGuestInstNT_SOURCES  = win/VBoxGuestInst.cpp
 endif
 
Index: trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp
===================================================================
--- trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp	(revision 70145)
+++ trunk/src/VBox/Additions/common/VBoxGuest/VBoxGuest-win.cpp	(revision 70146)
@@ -38,4 +38,5 @@
 #include <iprt/asm.h>
 #include <iprt/asm-amd64-x86.h>
+#include <iprt/dbg.h>
 #include <iprt/memobj.h>
 #include <iprt/spinlock.h>
@@ -177,12 +178,11 @@
 RT_C_DECLS_BEGIN
 #ifdef TARGET_NT4
+static NTSTATUS vgdrvNt4CreateDevice(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
 static NTSTATUS vgdrvNt4FindPciDevice(PULONG puluBusNumber, PPCI_SLOT_NUMBER puSlotNumber);
-static NTSTATUS vgdrvNt4CreateDevice(PDRIVER_OBJECT pDrvObj, PUNICODE_STRING pRegPath);
-#else
+#endif
 static NTSTATUS vgdrvNtNt5PlusAddDevice(PDRIVER_OBJECT pDrvObj, PDEVICE_OBJECT pDevObj);
 static NTSTATUS vgdrvNtNt5PlusPnP(PDEVICE_OBJECT pDevObj, PIRP pIrp);
 static NTSTATUS vgdrvNtNt5PlusPower(PDEVICE_OBJECT pDevObj, PIRP pIrp);
 static NTSTATUS vgdrvNtNt5PlusSystemControl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
-#endif
 static void     vgdrvNtUnmapVMMDevMemory(PVBOXGUESTDEVEXTWIN pDevExt);
 static NTSTATUS vgdrvNtCleanup(PDEVICE_OBJECT pDevObj);
@@ -229,4 +229,10 @@
 /** The detected NT (windows) version. */
 VGDRVNTVER g_enmVGDrvNtVer = VGDRVNTVER_INVALID;
+/** Pointer to the PoStartNextPowerIrp routine (in the NT kernel).
+ * Introduced in Windows 2000. */
+static decltype(PoStartNextPowerIrp) *g_pfnPoStartNextPowerIrp = NULL;
+/** Pointer to the PoCallDriver routine (in the NT kernel).
+ * Introduced in Windows 2000. */
+static decltype(PoCallDriver)        *g_pfnPoCallDriver = NULL;
 
 
@@ -261,5 +267,5 @@
     vgdrvNtDoTests();
 #endif
-    NTSTATUS rc = STATUS_SUCCESS;
+    NTSTATUS rcNt = STATUS_SUCCESS;
     switch (ulMajorVer)
     {
@@ -328,34 +334,62 @@
                 else
                     LogRelFunc(("Unknown version %u.%u!\n", ulMajorVer, ulMinorVer));
-                rc = STATUS_DRIVER_UNABLE_TO_LOAD;
+                rcNt = STATUS_DRIVER_UNABLE_TO_LOAD;
             }
             break;
     }
-
-    if (NT_SUCCESS(rc))
+    if (NT_SUCCESS(rcNt))
     {
         /*
-         * Setup the driver entry points in pDrvObj.
+         * Dynamically resolve symbols not present in NT4.
          */
-        pDrvObj->DriverUnload                                  = vgdrvNtUnload;
-        pDrvObj->MajorFunction[IRP_MJ_CREATE]                  = vgdrvNtCreate;
-        pDrvObj->MajorFunction[IRP_MJ_CLOSE]                   = vgdrvNtClose;
-        pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]          = vgdrvNtDeviceControl;
-        pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vgdrvNtInternalIOCtl;
-        pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN]                = vgdrvNtShutdown;
-        pDrvObj->MajorFunction[IRP_MJ_READ]                    = vgdrvNtNotSupportedStub;
-        pDrvObj->MajorFunction[IRP_MJ_WRITE]                   = vgdrvNtNotSupportedStub;
+        int rc;
 #ifdef TARGET_NT4
-        rc = vgdrvNt4CreateDevice(pDrvObj, pRegPath);
-#else
-        pDrvObj->MajorFunction[IRP_MJ_PNP]                     = vgdrvNtNt5PlusPnP;
-        pDrvObj->MajorFunction[IRP_MJ_POWER]                   = vgdrvNtNt5PlusPower;
-        pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL]          = vgdrvNtNt5PlusSystemControl;
-        pDrvObj->DriverExtension->AddDevice                    = (PDRIVER_ADD_DEVICE)vgdrvNtNt5PlusAddDevice;
+        if (g_enmVGDrvNtVer <= VGDRVNTVER_WINNT4)
+            rc = VINF_SUCCESS;
+        else
 #endif
-    }
-
-    LogFlowFunc(("Returning %#x\n", rc));
-    return rc;
+        {
+            RTDBGKRNLINFO hKrnlInfo;
+            rc = RTR0DbgKrnlInfoOpen(&hKrnlInfo, 0 /*fFlags*/);
+            if (RT_SUCCESS(rc))
+            {
+                int rc1 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "PoCallDriver",        (void **)&g_pfnPoCallDriver);
+                int rc2 = RTR0DbgKrnlInfoQuerySymbol(hKrnlInfo, NULL, "PoStartNextPowerIrp", (void **)&g_pfnPoStartNextPowerIrp);
+                if (g_enmVGDrvNtVer > VGDRVNTVER_WINNT4 && RT_FAILURE(rc1))
+                    rc = rc1;
+                if (g_enmVGDrvNtVer > VGDRVNTVER_WINNT4 && RT_FAILURE(rc2))
+                    rc = rc2;
+                RTR0DbgKrnlInfoRelease(hKrnlInfo);
+            }
+        }
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * Setup the driver entry points in pDrvObj.
+             */
+            pDrvObj->DriverUnload                                  = vgdrvNtUnload;
+            pDrvObj->MajorFunction[IRP_MJ_CREATE]                  = vgdrvNtCreate;
+            pDrvObj->MajorFunction[IRP_MJ_CLOSE]                   = vgdrvNtClose;
+            pDrvObj->MajorFunction[IRP_MJ_DEVICE_CONTROL]          = vgdrvNtDeviceControl;
+            pDrvObj->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = vgdrvNtInternalIOCtl;
+            pDrvObj->MajorFunction[IRP_MJ_SHUTDOWN]                = vgdrvNtShutdown;
+            pDrvObj->MajorFunction[IRP_MJ_READ]                    = vgdrvNtNotSupportedStub;
+            pDrvObj->MajorFunction[IRP_MJ_WRITE]                   = vgdrvNtNotSupportedStub;
+#ifdef TARGET_NT4
+            if (g_enmVGDrvNtVer <= VGDRVNTVER_WINNT4)
+                rcNt = vgdrvNt4CreateDevice(pDrvObj, pRegPath);
+            else
+#endif
+            {
+                pDrvObj->MajorFunction[IRP_MJ_PNP]                     = vgdrvNtNt5PlusPnP;
+                pDrvObj->MajorFunction[IRP_MJ_POWER]                   = vgdrvNtNt5PlusPower;
+                pDrvObj->MajorFunction[IRP_MJ_SYSTEM_CONTROL]          = vgdrvNtNt5PlusSystemControl;
+                pDrvObj->DriverExtension->AddDevice                    = (PDRIVER_ADD_DEVICE)vgdrvNtNt5PlusAddDevice;
+            }
+        }
+    }
+
+    LogFlowFunc(("Returning %#x\n", rcNt));
+    return rcNt;
 }
 
@@ -518,5 +552,5 @@
     if (!pIrp)
     {
-#if ARCH_BITS == 32
+#ifdef TARGET_NT4
         /*
          * NT4: Let's have a look at what our PCI adapter offers.
@@ -536,8 +570,9 @@
         if (NT_SUCCESS(rcNt))
             rcNt = vgdrvNtScanPCIResourceList(pResourceList, pDevExt);
-# else  /* ARCH_BITS != 32 */
+# else  /* !TARGET_NT4 */
+        AssertFailed();
         RT_NOREF(pDevObj, pDrvObj, pRegPath);
         rcNt = STATUS_INTERNAL_ERROR;
-# endif /* ARCH_BITS != 32 */
+# endif /* !TARGET_NT4 */
     }
     else
@@ -609,7 +644,7 @@
         ULONG uInterruptVector = pDevExt->uInterruptVector;
         KIRQL uHandlerIrql     = (KIRQL)pDevExt->uInterruptLevel;
+#ifdef TARGET_NT4
         if (!pIrp)
         {
-#if ARCH_BITS == 32
             /* NT4: Get an interrupt vector.  Only proceed if the device provides an interrupt. */
             if (   uInterruptVector
@@ -628,6 +663,6 @@
             else
                 LogFunc(("Device does not provide an interrupt!\n"));
+        }
 #endif
-        }
         if (uInterruptVector)
         {
@@ -825,5 +860,5 @@
 }
 
-#else /* !TARGET_NT4 */
+#endif /* TARGET_NT4 */
 
 /**
@@ -877,7 +912,7 @@
                  * so continue to init our own things.
                  */
-# ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
+#ifdef VBOX_WITH_GUEST_BUGCHECK_DETECTION
                 vgdrvNtBugCheckCallback(pDevExt); /* Ignore failure! */
-# endif
+#endif
                 if (NT_SUCCESS(rc))
                 {
@@ -976,5 +1011,5 @@
     PIO_STACK_LOCATION  pStack  = IoGetCurrentIrpStackLocation(pIrp);
 
-# ifdef LOG_ENABLED
+#ifdef LOG_ENABLED
     static char const * const s_apszFnctName[] =
     {
@@ -1006,5 +1041,5 @@
     Log(("vgdrvNtNt5PlusPnP: MinorFunction: %s\n",
          pStack->MinorFunction < RT_ELEMENTS(s_apszFnctName) ? s_apszFnctName[pStack->MinorFunction] : "Unknown"));
-# endif
+#endif
 
     NTSTATUS rc = STATUS_SUCCESS;
@@ -1088,8 +1123,8 @@
             Log(("vgdrvNtNt5PlusPnP: QUERY_REMOVE_DEVICE\n"));
 
-# ifdef VBOX_REBOOT_ON_UNINSTALL
+#ifdef VBOX_REBOOT_ON_UNINSTALL
             Log(("vgdrvNtNt5PlusPnP: QUERY_REMOVE_DEVICE: Device cannot be removed without a reboot.\n"));
             rc = STATUS_UNSUCCESSFUL;
-# endif
+#endif
 
             if (NT_SUCCESS(rc))
@@ -1184,8 +1219,8 @@
             Log(("vgdrvNtNt5PlusPnP: QUERY_STOP_DEVICE\n"));
 
-# ifdef VBOX_REBOOT_ON_UNINSTALL /** @todo  r=bird: this code and log msg is pointless as rc = success and status will be overwritten below. */
+#ifdef VBOX_REBOOT_ON_UNINSTALL /** @todo  r=bird: this code and log msg is pointless as rc = success and status will be overwritten below. */
             Log(("vgdrvNtNt5PlusPnP: QUERY_STOP_DEVICE: Device cannot be stopped without a reboot!\n"));
             pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-# endif
+#endif
 
             if (NT_SUCCESS(rc))
@@ -1260,5 +1295,5 @@
 static NTSTATUS vgdrvNtNt5PlusPowerComplete(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp, IN PVOID pContext)
 {
-# ifdef VBOX_STRICT
+#ifdef VBOX_STRICT
     RT_NOREF1(pDevObj);
     PVBOXGUESTDEVEXTWIN pDevExt = (PVBOXGUESTDEVEXTWIN)pContext;
@@ -1293,7 +1328,7 @@
         }
     }
-# else
+#else
     RT_NOREF3(pDevObj, pIrp, pContext);
-# endif
+#endif
 
     return STATUS_SUCCESS;
@@ -1356,5 +1391,5 @@
                             VMMDevReqMouseStatus *pReq = NULL;
                             int vrc = VbglR0GRAlloc((VMMDevRequestHeader **)&pReq, sizeof (VMMDevReqMouseStatus),
-                                                  VMMDevReq_SetMouseStatus);
+                                                    VMMDevReq_SetMouseStatus);
                             if (RT_SUCCESS(vrc))
                             {
@@ -1404,5 +1439,4 @@
 
                         case PowerActionHibernate:
-
                             Log(("vgdrvNtNt5PlusPower: Power action hibernate!\n"));
                             break;
@@ -1439,5 +1473,5 @@
      * we must call PoStartNextPowerIrp.
      */
-    PoStartNextPowerIrp(pIrp);
+    g_pfnPoStartNextPowerIrp(pIrp);
 
     /*
@@ -1452,5 +1486,5 @@
                            TRUE,
                            TRUE);
-    return PoCallDriver(pDevExt->pNextLowerDriver, pIrp);
+    return g_pfnPoCallDriver(pDevExt->pNextLowerDriver, pIrp);
 }
 
@@ -1475,5 +1509,4 @@
 }
 
-#endif /* !TARGET_NT4 */
 
 
