Skip to content

Commit ae31d7e

Browse files
authored
Update TimerResolutionModifier.cpp
1 parent 3ca9b56 commit ae31d7e

File tree

1 file changed

+90
-24
lines changed

1 file changed

+90
-24
lines changed

TimerResolutionModifier.cpp

Lines changed: 90 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,81 @@
44

55
#pragma comment(lib, "Winmm.lib")
66

7-
// =======================================================================
8-
// ↓↓↓ 新增的导出函数 ↓↓↓
9-
// =======================================================================
10-
//
11-
// 这个函数是空的,什么也不做。
12-
// 它的唯一目的就是被“导出”,以满足那些要求DLL至少有一个
13-
// 导出函数的注入器。
14-
// extern "C" 确保函数名不会被C++编译器修改。
15-
// __declspec(dllexport) 告诉编译器将此函数放入DLL的导出表中。
16-
//
7+
// 全局变量,用于线程控制和状态管理
8+
// volatile 关键字确保多线程访问时的可见性,防止编译器过度优化
9+
static volatile bool g_runThread = false; // 控制监控线程运行的标志
10+
static volatile bool g_isTimerHigh = false; // 记录当前计时器是否已处于高精度状态
11+
static HANDLE g_hThread = NULL; // 监控线程的句柄
12+
13+
// 监控线程的主函数
14+
DWORD WINAPI MonitorThread(LPVOID lpParam)
15+
{
16+
// 获取当前进程(即被注入的进程)的ID
17+
const DWORD currentProcessId = GetCurrentProcessId();
18+
19+
while (g_runThread)
20+
{
21+
// 获取当前前台窗口的句柄
22+
HWND hForegroundWnd = GetForegroundWindow();
23+
bool isForeground = false;
24+
25+
if (hForegroundWnd)
26+
{
27+
DWORD foregroundProcessId = 0;
28+
GetWindowThreadProcessId(hForegroundWnd, &foregroundProcessId);
29+
if (foregroundProcessId == currentProcessId)
30+
{
31+
isForeground = true;
32+
}
33+
}
34+
35+
// 如果当前进程是前台进程...
36+
if (isForeground)
37+
{
38+
// ...并且计时器还不是高精度状态,则设置它
39+
if (!g_isTimerHigh)
40+
{
41+
if (timeBeginPeriod(1) == TIMERR_NOERROR)
42+
{
43+
g_isTimerHigh = true;
44+
}
45+
}
46+
}
47+
// 如果当前进程是后台进程...
48+
else
49+
{
50+
// ...并且计时器当前是高精度状态,则恢复它
51+
if (g_isTimerHigh)
52+
{
53+
if (timeEndPeriod(1) == TIMERR_NOERROR)
54+
{
55+
g_isTimerHigh = false;
56+
}
57+
}
58+
}
59+
60+
// 等待一小段时间再进行下一次检查,以避免CPU占用过高
61+
// 250毫秒的检查频率对于前后台切换检测来说绰绰有余
62+
Sleep(250);
63+
}
64+
65+
// 线程退出前,最后检查一次,确保恢复计时器精度
66+
if (g_isTimerHigh)
67+
{
68+
timeEndPeriod(1);
69+
g_isTimerHigh = false;
70+
}
71+
72+
return 0;
73+
}
74+
75+
// 导出函数,以满足某些注入器的要求
1776
extern "C" __declspec(dllexport) void PlaceholderExport()
1877
{
1978
// Do nothing.
2079
}
21-
// =======================================================================
2280

23-
24-
// DllMain 是 DLL 的入口点函数
81+
// DLL入口点
2582
BOOL APIENTRY DllMain( HMODULE hModule,
2683
DWORD ul_reason_for_call,
2784
LPVOID lpReserved
@@ -30,22 +87,31 @@ BOOL APIENTRY DllMain( HMODULE hModule,
3087
switch (ul_reason_for_call)
3188
{
3289
case DLL_PROCESS_ATTACH:
33-
// DLL被注入到进程时,请求1ms的计时器精度
34-
timeBeginPeriod(1);
90+
// 优化:禁止对后续的线程创建/销毁事件调用DllMain,减少开销
91+
DisableThreadLibraryCalls(hModule);
92+
93+
// 设置运行标志并创建监控线程
94+
g_runThread = true;
95+
g_hThread = CreateThread(NULL, 0, MonitorThread, NULL, 0, NULL);
3596
break;
3697

37-
case DLL_THREAD_ATTACH:
38-
// 进程创建新线程时执行,我们此处不需要操作
98+
case DLL_PROCESS_DETACH:
99+
// 通知监控线程停止
100+
if (g_hThread)
101+
{
102+
g_runThread = false;
103+
// 等待线程安全退出(最多等待5秒)
104+
WaitForSingleObject(g_hThread, 5000);
105+
// 关闭线程句柄,释放资源
106+
CloseHandle(g_hThread);
107+
g_hThread = NULL;
108+
}
39109
break;
40110

111+
case DLL_THREAD_ATTACH:
41112
case DLL_THREAD_DETACH:
42-
// 线程退出时执行,我们此处不需要操作
43-
break;
44-
45-
case DLL_PROCESS_DETACH:
46-
// DLL从进程卸载时,释放计时器精度请求
47-
timeEndPeriod(1);
113+
// 不做任何事
48114
break;
49115
}
50-
return TRUE; // 操作成功
116+
return TRUE;
51117
}

0 commit comments

Comments
 (0)