Skip to content

Commit c2cec22

Browse files
feat(injector): stop injecting if crashed for 3 times
1 parent 60954db commit c2cec22

File tree

1 file changed

+134
-8
lines changed

1 file changed

+134
-8
lines changed

src/inject/inject.cc

Lines changed: 134 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,15 @@ void GetDebugPrivilege() {
7878
CloseHandle(hToken);
7979
}
8080

81+
void ShowCrashDialog();
82+
83+
constexpr int MAX_CRASH_COUNT = 3;
8184
int InjectToPID(int targetPID, std::wstring_view dllPath) {
85+
static int crash_count = 0;
86+
87+
if (crash_count >= MAX_CRASH_COUNT) {
88+
return 1;
89+
}
8290

8391
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetPID);
8492
if (hProcess == NULL) {
@@ -118,8 +126,23 @@ int InjectToPID(int targetPID, std::wstring_view dllPath) {
118126

119127
WaitForSingleObject(hThread, INFINITE);
120128
CloseHandle(hThread);
121-
VirtualFreeEx(hProcess, remoteString, 0, MEM_RELEASE);
122-
CloseHandle(hProcess);
129+
130+
std::thread([hProcess]() {
131+
WaitForSingleObject(hProcess, INFINITE);
132+
auto exitCode = 0;
133+
if (!GetExitCodeProcess(hProcess, (LPDWORD)&exitCode)) {
134+
std::cerr << "GetExitCodeProcess failed: " << GetLastError() << std::endl;
135+
}
136+
if (exitCode != 0) {
137+
std::cerr << "Process exited with code: " << exitCode << std::endl;
138+
if (++crash_count >= MAX_CRASH_COUNT) {
139+
ShowCrashDialog();
140+
}
141+
} else {
142+
crash_count = 0; // Reset crash count on successful injection
143+
}
144+
CloseHandle(hProcess);
145+
}).detach();
123146

124147
std::cout << "DLL injected successfully." << std::endl;
125148
return 0;
@@ -386,6 +409,7 @@ void InjectAllConsistent() {
386409

387410
struct inject_all_switch : public button_widget {
388411
bool injecting_all = false;
412+
std::chrono::steady_clock::time_point last_check;
389413
inject_all_switch() : button_widget(english ? "Inject All" : "全局注入") {
390414
check_is_injecting_all();
391415
}
@@ -420,11 +444,6 @@ struct inject_all_switch : public button_widget {
420444
}
421445

422446
restart_explorer();
423-
424-
std::thread([this]() {
425-
Sleep(200);
426-
check_is_injecting_all();
427-
}).detach();
428447
}
429448

430449
void update_colors(bool is_active, bool is_hovered) override {
@@ -437,6 +456,12 @@ struct inject_all_switch : public button_widget {
437456
} else {
438457
button_widget::update_colors(is_active, is_hovered);
439458
}
459+
460+
if (std::chrono::steady_clock::now() - last_check >
461+
std::chrono::seconds(1)) {
462+
check_is_injecting_all();
463+
last_check = std::chrono::steady_clock::now();
464+
}
440465
}
441466
};
442467

@@ -546,10 +571,111 @@ void StartInjectUI() {
546571
return;
547572
}
548573
nvgCreateFont(rt.nvg, "main", "C:\\WINDOWS\\FONTS\\msyh.ttc");
549-
550574
rt.root->emplace_child<injector_ui_main>();
575+
rt.start_loop();
576+
}
577+
578+
void ShowCrashDialog() {
579+
auto show_by_messagebox = []() {
580+
MessageBoxW(
581+
NULL,
582+
english
583+
? L"Explorer has crashed too many times after injection.\nBreeze "
584+
L"Shell will now exit to prevent further crashes."
585+
: L"注入后资源管理器多次崩溃。\nBreeze Shell "
586+
L"将退出以防止进一步崩溃。",
587+
english ? L"Breeze Shell Error" : L"Breeze Shell 错误",
588+
MB_ICONERROR | MB_OK);
589+
};
590+
if (auto r = ui::render_target::init_global(); !r) {
591+
std::cerr << "Failed to initialize global render target." << std::endl;
592+
show_by_messagebox();
593+
return;
594+
}
595+
596+
ui::render_target rt;
597+
rt.acrylic = 0.1;
598+
rt.transparent = true;
599+
rt.width = 400;
600+
rt.height = 230;
601+
rt.title = "";
602+
603+
if (auto r = rt.init(); !r) {
604+
std::cerr << "Failed to initialize render target." << std::endl;
605+
show_by_messagebox();
606+
return;
607+
}
608+
609+
nvgCreateFont(rt.nvg, "main", "C:\\WINDOWS\\FONTS\\msyh.ttc");
610+
611+
// Create error UI
612+
auto error_ui = rt.root->emplace_child<ui::widget_flex>();
613+
error_ui->gap = 15;
614+
error_ui->x->reset_to(20);
615+
error_ui->y->reset_to(0);
616+
617+
// Icon
618+
error_ui->emplace_child<breeze_icon>();
619+
620+
// Error message
621+
auto msg_box = error_ui->emplace_child<ui::widget_flex>();
622+
msg_box->gap = 10;
623+
624+
auto title = msg_box->emplace_child<ui::text_widget>();
625+
title->text = "Breeze Shell Error";
626+
title->font_size = 20;
627+
title->color.reset_to({1, 0.4, 0.4, 1});
628+
629+
auto message = msg_box->emplace_child<ui::text_widget>();
630+
message->text = english
631+
? "Explorer has crashed multiple times after injection."
632+
: "资源管理器在注入后多次崩溃,这可能是 Breeze 的问题。";
633+
message->font_size = 14;
634+
message->color.reset_to({1, 1, 1, 0.9});
635+
636+
auto suggestion = msg_box->emplace_child<ui::text_widget>();
637+
suggestion->text = english ? "Breeze Shell will be temporarily disabled to "
638+
"prevent further crashes."
639+
: "Breeze 将暂时被禁用,以防止持续崩溃。";
640+
suggestion->font_size = 14;
641+
suggestion->color.reset_to({1, 1, 1, 0.9});
642+
643+
auto suggestion2 = msg_box->emplace_child<ui::text_widget>();
644+
suggestion2->text = english
645+
? "If you want to continue using Breeze Shell, "
646+
"please re-enable it in the injector UI."
647+
: "如果您想继续使用 Breeze,请在注入器中重新启用。";
648+
suggestion2->font_size = 14;
649+
suggestion2->color.reset_to({1, 1, 1, 0.9});
650+
651+
auto btn_container = error_ui->emplace_child<ui::widget_flex>();
652+
btn_container->horizontal = true;
653+
btn_container->gap = 10;
654+
655+
class close_button : public button_widget {
656+
public:
657+
close_button() : button_widget(english ? "Close" : "关闭") {}
658+
void on_click() override { exit(1); }
659+
};
660+
661+
class github_button : public button_widget {
662+
public:
663+
github_button() : button_widget(english ? "Check GitHub" : "查看 GitHub") {}
664+
void on_click() override {
665+
ShellExecuteW(
666+
NULL, L"open",
667+
L"https://github.com/std-microblock/breeze-shell/releases/latest",
668+
NULL, NULL, SW_SHOW);
669+
}
670+
};
551671

672+
btn_container->emplace_child<close_button>();
673+
btn_container->emplace_child<github_button>();
552674
rt.start_loop();
675+
HANDLE event =
676+
CreateEventW(NULL, TRUE, FALSE, L"breeze-shell-inject-consistent-exit");
677+
SetEvent(event);
678+
CloseHandle(event);
553679
}
554680

555681
void UpdateDllPath() {

0 commit comments

Comments
 (0)