From 202abd6a6ac056ecdfe5fa51e210a7909635c548 Mon Sep 17 00:00:00 2001
From: mingkuang <mingkuang@live.com>
Date: Wed, 8 May 2024 22:45:29 +0800
Subject: [PATCH] =?UTF-8?q?Fea=EF=BC=8C=E6=B7=BB=E5=8A=A0QueryInterruptTim?=
 =?UTF-8?q?e=E3=80=81QueryInterruptTimePrecise=E3=80=81QueryUnbiasedInterr?=
 =?UTF-8?q?uptTimePrecise=E3=80=81QueryIdleProcessorCycleTimeEx?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 ThunksList.md                           |   4 +
 src/Thunks/YY_Thunks.cpp                |   1 +
 src/Thunks/api-ms-win-core-realtime.hpp | 102 ++++++++++++++++++++++++
 3 files changed, 107 insertions(+)

diff --git a/ThunksList.md b/ThunksList.md
index ca2429f..53184aa 100644
--- a/ThunksList.md
+++ b/ThunksList.md
@@ -335,7 +335,10 @@
 | GetQueuedCompletionStatusEx                | 不存在时,调用 GetQueuedCompletionStatus。
 | FindFirstFileEx(W/A)                       | Windows XP、Vista兼容 FIND_FIRST_EX_LARGE_FETCH、FindExInfoStandard参数。
 | GetProcessGroupAffinity                    | 不存在时,始终认为只有一组CPU。
+| QueryInterruptTime                         | 不存在时,读取KUSER_SHARED_DATA::InterruptTime值。
+| QueryInterruptTimePrecise                  | 不存在时,读取KUSER_SHARED_DATA::InterruptTime值。
 | QueryUnbiasedInterruptTime                 | 不存在时,读取KUSER_SHARED_DATA::InterruptTime值模拟UnbiasedInterruptTime。
+| QueryUnbiasedInterruptTimePrecise          | 不存在时,调用QueryUnbiasedInterruptTime。
 | FindStringOrdinal                          | 不存在时,调用CompareStringOrdinal。
 | GetEnabledXStateFeatures                   | 不存在时,调用IsProcessorFeaturePresent。
 | SetXStateFeaturesMask                      | 不存在时,内部实现。
@@ -343,6 +346,7 @@
 | InitializeContext2                         | 不存在时,调用InitializeContext。
 | LocateXStateFeature                        | 不存在时,内部实现。
 | CopyContext                                | 不存在时,内部实现。
+| QueryIdleProcessorCycleTimeEx              | 不存在时,调用QueryIdleProcessorCycleTime。
 | SetThreadIdealProcessorEx                  | 不存在时,调用SetThreadIdealProcessor。
 | GetThreadIdealProcessorEx                  | 不存在时,调用SetThreadIdealProcessor。
 | GetUserPreferredUILanguages                | 不存在时,调用GetThreadPreferredUILanguages。
diff --git a/src/Thunks/YY_Thunks.cpp b/src/Thunks/YY_Thunks.cpp
index 26f9e7e..467ea66 100644
--- a/src/Thunks/YY_Thunks.cpp
+++ b/src/Thunks/YY_Thunks.cpp
@@ -26,6 +26,7 @@
     _APPLY(bluetoothapis,                                "bluetoothapis"                      , 0                 ) \
     _APPLY(netapi32,                                     "netapi32"                           , 0                 ) \
     _APPLY(powrprof,                                     "powrprof"                           , 0                 ) \
+    _APPLY(api_ms_win_core_realtime_l1_1_1,              "api-ms-win-core-realtime-l1-1-1"    , 0                 ) \
     _APPLY(api_ms_win_core_winrt_l1_1_0,                 "api-ms-win-core-winrt-l1-1-0"       , 0                 ) \
     _APPLY(api_ms_win_core_winrt_string_l1_1_0,          "api-ms-win-core-winrt-string-l1-1-0", 0                 ) \
     _APPLY(api_ms_win_core_winrt_error_l1_1_0,           "api-ms-win-core-winrt-error-l1-1-0" , 0                 ) \
diff --git a/src/Thunks/api-ms-win-core-realtime.hpp b/src/Thunks/api-ms-win-core-realtime.hpp
index a426e01..f19ec79 100644
--- a/src/Thunks/api-ms-win-core-realtime.hpp
+++ b/src/Thunks/api-ms-win-core-realtime.hpp
@@ -132,6 +132,108 @@ namespace YY
             return TRUE;
         }
 #endif
+
+
+#if (YY_Thunks_Support_Version < NTDDI_WIN10)
+
+		// 最低受支持的客户端	Windows 10 [桌面应用 |UWP 应用]
+        // 最低受支持的服务器	Windows Server 2016[桌面应用 | UWP 应用]
+		__DEFINE_THUNK(
+		api_ms_win_core_realtime_l1_1_1,
+		4,
+		VOID,
+        WINAPI,
+        QueryUnbiasedInterruptTimePrecise,
+            _Out_ PULONGLONG _puUnbiasedInterruptTimePrecise
+			)
+		{
+			if (const auto _pfnQueryUnbiasedInterruptTimePrecise = try_get_QueryUnbiasedInterruptTimePrecise())
+			{
+				return _pfnQueryUnbiasedInterruptTimePrecise(_puUnbiasedInterruptTimePrecise);
+			}
+
+            // 用中断时间模拟非中断时间,凑合一下吧。
+            QueryInterruptTimeDownlevel(_puUnbiasedInterruptTimePrecise);
+        }
+#endif
+
+
+#if (YY_Thunks_Support_Version < NTDDI_WIN10)
+
+		// 最低受支持的客户端	Windows 10 [桌面应用 |UWP 应用]
+        // 最低受支持的服务器	Windows Server 2016[桌面应用 | UWP 应用]
+		__DEFINE_THUNK(
+		api_ms_win_core_realtime_l1_1_1,
+		4,
+		VOID,
+        WINAPI,
+        QueryInterruptTime,
+            _Out_ PULONGLONG _puInterruptTime
+			)
+		{
+			if (const auto _pfnQueryInterruptTime = try_get_QueryInterruptTime())
+			{
+				return _pfnQueryInterruptTime(_puInterruptTime);
+			}
+
+            QueryInterruptTimeDownlevel(_puInterruptTime);
+        }
+#endif
+
+
+#if (YY_Thunks_Support_Version < NTDDI_WIN10)
+
+		// 最低受支持的客户端	Windows 10 [桌面应用 |UWP 应用]
+        // 最低受支持的服务器	Windows Server 2016[桌面应用 | UWP 应用]
+		__DEFINE_THUNK(
+		api_ms_win_core_realtime_l1_1_1,
+		4,
+		VOID,
+        WINAPI,
+        QueryInterruptTimePrecise,
+            _Out_ PULONGLONG _puInterruptTimePrecise
+			)
+		{
+			if (const auto _pfnQueryInterruptTimePrecise = try_get_QueryInterruptTimePrecise())
+			{
+				return _pfnQueryInterruptTimePrecise(_puInterruptTimePrecise);
+			}
+
+            QueryInterruptTimeDownlevel(_puInterruptTimePrecise);
+        }
+#endif
+
+
+#if (YY_Thunks_Support_Version < NTDDI_WIN7)
+
+		// 最低受支持的客户端	Windows 7 [仅限桌面应用]
+        // 最低受支持的服务器	Windows Server 2008 R2[仅限桌面应用]
+		__DEFINE_THUNK(
+		kernel32,
+		12,
+		BOOL,
+        WINAPI,
+        QueryIdleProcessorCycleTimeEx,
+            _In_ USHORT _uGroup,
+            _Inout_ PULONG _puBufferLength,
+            _Out_writes_bytes_opt_(*_puBufferLength) PULONG64 _puProcessorIdleCycleTime
+			)
+		{
+			if (const auto _pfnQueryIdleProcessorCycleTimeEx = try_get_QueryIdleProcessorCycleTimeEx())
+			{
+				return _pfnQueryIdleProcessorCycleTimeEx(_uGroup, _puBufferLength, _puProcessorIdleCycleTime);
+			}
+            
+            // 不支持的平台统一认为只有1组CPU可用
+            if (_uGroup != 0)
+            {
+                SetLastError(ERROR_INVALID_PARAMETER);
+                return FALSE;
+            }
+
+            return QueryIdleProcessorCycleTime(_puBufferLength, _puProcessorIdleCycleTime);
+        }
+#endif
 	}//namespace Thunks
 
 } //namespace YY