diff options
Diffstat (limited to 'src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp')
-rw-r--r-- | src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp index b870cb0c7..1615ac7ab 100644 --- a/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp +++ b/src/VBox/Runtime/r0drv/nt/initterm-r0drv-nt.cpp @@ -56,6 +56,14 @@ RTCPUSET g_rtMpNtCpuSet; PFNMYEXSETTIMERRESOLUTION g_pfnrtNtExSetTimerResolution; /** KeFlushQueuedDpcs, introduced in XP. */ PFNMYKEFLUSHQUEUEDDPCS g_pfnrtNtKeFlushQueuedDpcs; +/** HalRequestIpi, introduced in ??. */ +PFNHALREQUESTIPI g_pfnrtNtHalRequestIpi; +/** HalSendSoftwareInterrupt */ +PFNHALSENDSOFTWAREINTERRUPT g_pfnrtNtHalSendSoftwareInterrupt; +/** SendIpi handler based on Windows version */ +PFNRTSENDIPI g_pfnrtSendIpi; +/** KeIpiGenericCall - Windows Server 2003+ only */ +PFNRTKEIPIGENERICCALL g_pfnrtKeIpiGenericCall; /** Offset of the _KPRCB::QuantumEnd field. 0 if not found. */ uint32_t g_offrtNtPbQuantumEnd; @@ -82,6 +90,9 @@ int rtR0InitNative(void) #ifdef IPRT_TARGET_NT4 g_pfnrtNtExSetTimerResolution = NULL; g_pfnrtNtKeFlushQueuedDpcs = NULL; + g_pfnrtNtHalRequestIpi = NULL; + g_pfnrtNtHalSendSoftwareInterrupt = NULL; + g_pfnrtKeIpiGenericCall = NULL; #else /* * Initialize the function pointers. @@ -92,6 +103,15 @@ int rtR0InitNative(void) RtlInitUnicodeString(&RoutineName, L"KeFlushQueuedDpcs"); g_pfnrtNtKeFlushQueuedDpcs = (PFNMYKEFLUSHQUEUEDDPCS)MmGetSystemRoutineAddress(&RoutineName); + + RtlInitUnicodeString(&RoutineName, L"HalRequestIpi"); + g_pfnrtNtHalRequestIpi = (PFNHALREQUESTIPI)MmGetSystemRoutineAddress(&RoutineName); + + RtlInitUnicodeString(&RoutineName, L"HalSendSoftwareInterrupt"); + g_pfnrtNtHalSendSoftwareInterrupt = (PFNHALSENDSOFTWAREINTERRUPT)MmGetSystemRoutineAddress(&RoutineName); + + RtlInitUnicodeString(&RoutineName, L"KeIpiGenericCall"); + g_pfnrtKeIpiGenericCall = (PFNRTKEIPIGENERICCALL)MmGetSystemRoutineAddress(&RoutineName); #endif /* @@ -102,6 +122,25 @@ int rtR0InitNative(void) ULONG BuildNumber = 0; BOOLEAN fChecked = PsGetVersion(&MajorVersion, &MinorVersion, &BuildNumber, NULL); + g_pfnrtSendIpi = rtMpSendIpiDummy; +#ifndef IPRT_TARGET_NT4 + if ( g_pfnrtNtHalRequestIpi + && MajorVersion == 6 + && MinorVersion == 0) + { + /* Vista or Windows Server 2008 */ + g_pfnrtSendIpi = rtMpSendIpiVista; + } + else + if ( g_pfnrtNtHalSendSoftwareInterrupt + && MajorVersion == 6 + && MinorVersion == 1) + { + /* Windows 7 or Windows Server 2008 R2 */ + g_pfnrtSendIpi = rtMpSendIpiWin7; + } + /* Windows XP should send always send an IPI -> VERIFY */ +#endif KIRQL OldIrql; KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); /* make sure we stay on the same cpu */ |