Skip to content

Commit 588a70f

Browse files
committed
Fix process hanging upon exit. Fix re-hooking Direct-X when Device is Lost or Reset.
1 parent 2636557 commit 588a70f

File tree

6 files changed

+171
-106
lines changed

6 files changed

+171
-106
lines changed

RemoteInput/Platform/NativeHooks_Windows.cxx

Lines changed: 77 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ std::unique_ptr<Hook> directx_device9_endscene_hook{nullptr};
4646
std::unique_ptr<Hook> directx_device9_reset_hook{nullptr};
4747
std::unique_ptr<Hook> directx_device11_swapchain_present_hook{nullptr};
4848

49-
bool is_dx_hooked = false;
5049
IDirect3DDevice9* current_dx_device = nullptr;
5150
void HookD3D9Device(IDirect3DDevice9* pDevice, bool force = false) noexcept;
5251

@@ -615,7 +614,6 @@ HRESULT __cdecl JavaDirectXCopyImageToIntArgbSurface(IDirect3DSurface9 *pSurface
615614
{
616615
HookD3D9Device(pDevice);
617616
pDevice->Release();
618-
is_dx_hooked = true;
619617
}
620618

621619
return directx_xrgb_hook->call<HRESULT, decltype(JavaDirectXCopyImageToIntArgbSurface)>(pSurface, pDstInfo, srcx, srcy, srcWidth, srcHeight, dstx, dsty);
@@ -649,7 +647,6 @@ HRESULT __cdecl JavaDirectXCopyImageToIntXrgbSurface(SurfaceDataRasInfo *pSrcInf
649647
{
650648
HookD3D9Device(pDevice);
651649
pDevice->Release();
652-
is_dx_hooked = true;
653650
}
654651

655652
return directx_xrgb_hook->call<HRESULT, decltype(JavaDirectXCopyImageToIntXrgbSurface)>(pSrcInfo, srctype, pDstSurfaceRes, srcx, srcy, srcWidth, srcHeight, dstx, dsty);
@@ -1001,10 +998,7 @@ HRESULT __stdcall D3D9_CreateDevice(IDirect3D9* pD3D, UINT Adapter, D3DDEVTYPE D
1001998
HRESULT result = directx_d3d9_createdevice_hook->call<HRESULT, decltype(D3D9_CreateDevice)>(pD3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);
1002999
if (ppReturnedDeviceInterface && *ppReturnedDeviceInterface)
10031000
{
1004-
if (!is_dx_hooked)
1005-
{
1006-
HookD3D9Device(*ppReturnedDeviceInterface);
1007-
}
1001+
HookD3D9Device(*ppReturnedDeviceInterface);
10081002
}
10091003
return result;
10101004
}
@@ -1016,83 +1010,83 @@ HRESULT __stdcall D3D9Device_EndScene(IDirect3DDevice9* device) noexcept
10161010
{
10171011
extern std::unique_ptr<ControlCenter> control_center;
10181012

1019-
if (directx_device9_endscene_hook)
1013+
if (control_center)
10201014
{
1021-
if (control_center)
1015+
D3DVIEWPORT9 viewport;
1016+
if (SUCCEEDED(device->GetViewport(&viewport)))
10221017
{
1023-
D3DVIEWPORT9 viewport;
1024-
if (SUCCEEDED(device->GetViewport(&viewport)))
1025-
{
1026-
std::int32_t width = static_cast<std::int32_t>(viewport.Width);
1027-
std::int32_t height = static_cast<std::int32_t>(viewport.Height);
1018+
std::int32_t width = static_cast<std::int32_t>(viewport.Width);
1019+
std::int32_t height = static_cast<std::int32_t>(viewport.Height);
10281020

1029-
std::int32_t x = 0;
1030-
std::int32_t y = 0;
1031-
std::size_t applet_width = 0;
1032-
std::size_t applet_height = 0;
1021+
std::int32_t x = 0;
1022+
std::int32_t y = 0;
1023+
std::size_t applet_width = 0;
1024+
std::size_t applet_height = 0;
10331025

1034-
control_center->get_applet_dimensions(&x, &y, &applet_width, &applet_height);
1035-
control_center->set_target_dimensions(static_cast<std::int32_t>(applet_width), static_cast<std::int32_t>(applet_height));
1026+
control_center->get_applet_dimensions(&x, &y, &applet_width, &applet_height);
1027+
control_center->set_target_dimensions(static_cast<std::int32_t>(applet_width), static_cast<std::int32_t>(applet_height));
10361028

1037-
/*if (width != applet_width || height != applet_height)
1038-
{
1039-
// Possibly menu open, render normally
1040-
return directx_device9_endscene_hook->call<HRESULT, decltype(D3D9Device_EndScene)>(device);
1041-
}*/
1042-
1043-
control_center->set_target_dimensions(static_cast<std::int32_t>(width), static_cast<std::int32_t>(height));
1044-
1045-
bool minimized = false;
1046-
ImageFormat image_format = control_center->get_image_format();
1047-
dx_read_pixels(device, control_center->get_image(), width, height, minimized, image_format);
1048-
1049-
IDirect3DStateBlock9* block;
1050-
device->CreateStateBlock(D3DSBT_ALL, &block);
1051-
block->Capture();
1052-
1053-
device->SetRenderState(D3DRS_LIGHTING, FALSE);
1054-
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
1055-
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
1056-
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
1057-
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //DISABLED
1058-
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
1059-
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1060-
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1061-
1062-
if (control_center->get_debug_graphics() && !minimized)
1063-
{
1064-
static IDirect3DTexture9* texture = nullptr;
1065-
dx_load_texture(device, texture, image_format, control_center->get_debug_image(), width, height);
1029+
/*if (width != applet_width || height != applet_height)
1030+
{
1031+
// Possibly menu open, render normally
1032+
return directx_device9_endscene_hook->call<HRESULT, decltype(D3D9Device_EndScene)>(device);
1033+
}*/
1034+
1035+
control_center->set_target_dimensions(static_cast<std::int32_t>(width), static_cast<std::int32_t>(height));
1036+
1037+
bool minimized = false;
1038+
ImageFormat image_format = control_center->get_image_format();
1039+
dx_read_pixels(device, control_center->get_image(), width, height, minimized, image_format);
1040+
1041+
IDirect3DStateBlock9* block;
1042+
device->CreateStateBlock(D3DSBT_ALL, &block);
1043+
block->Capture();
1044+
1045+
device->SetRenderState(D3DRS_LIGHTING, FALSE);
1046+
device->SetRenderState(D3DRS_FOGENABLE, FALSE);
1047+
device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
1048+
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
1049+
device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); //DISABLED
1050+
device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
1051+
device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
1052+
device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
1053+
1054+
if (control_center->get_debug_graphics() && !minimized)
1055+
{
1056+
static IDirect3DTexture9* texture = nullptr;
1057+
dx_load_texture(device, texture, image_format, control_center->get_debug_image(), width, height);
10661058

1067-
if (texture)
1068-
{
1069-
dx_draw_texture(device, texture, image_format, 0.0, 0.0, static_cast<float>(width), static_cast<float>(height));
1070-
}
1059+
if (texture)
1060+
{
1061+
dx_draw_texture(device, texture, image_format, 0.0, 0.0, static_cast<float>(width), static_cast<float>(height));
10711062
}
1063+
}
10721064

1073-
//Render Cursor
1074-
if (!minimized)
1075-
{
1076-
x = -1;
1077-
y = -1;
1078-
control_center->get_applet_mouse_position(&x, &y);
1065+
//Render Cursor
1066+
if (!minimized)
1067+
{
1068+
x = -1;
1069+
y = -1;
1070+
control_center->get_applet_mouse_position(&x, &y);
10791071

1080-
if (x > -1 && y > -1 && x <= width && y <= height)
1081-
{
1082-
device->SetTexture(0, nullptr);
1083-
dx_draw_point(device, static_cast<float>(x), static_cast<float>(y), 2.5f, D3DCOLOR_RGBA(0xFF, 0x00, 0x00, 0xFF));
1084-
}
1072+
if (x > -1 && y > -1 && x <= width && y <= height)
1073+
{
1074+
device->SetTexture(0, nullptr);
1075+
dx_draw_point(device, static_cast<float>(x), static_cast<float>(y), 2.5f, D3DCOLOR_RGBA(0xFF, 0x00, 0x00, 0xFF));
10851076
}
1086-
1087-
device->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);
1088-
device->SetTexture(0, nullptr);
1089-
device->SetPixelShader(nullptr);
1090-
device->SetVertexShader(nullptr);
1091-
block->Apply();
1092-
block->Release();
10931077
}
1078+
1079+
device->SetRenderState(D3DRS_ZFUNC,D3DCMP_NEVER);
1080+
device->SetTexture(0, nullptr);
1081+
device->SetPixelShader(nullptr);
1082+
device->SetVertexShader(nullptr);
1083+
block->Apply();
1084+
block->Release();
10941085
}
1086+
}
10951087

1088+
if (directx_device9_endscene_hook)
1089+
{
10961090
return directx_device9_endscene_hook->call<HRESULT, decltype(D3D9Device_EndScene)>(device);
10971091
}
10981092

@@ -1135,6 +1129,18 @@ void HookD3D9Device(IDirect3DDevice9* pDevice, bool force) noexcept
11351129
auto* reset = reinterpret_cast<decltype(D3D9Device_Reset)*>(vTable[16]);
11361130
directx_device9_reset_hook = std::make_unique<Hook>(reinterpret_cast<void*>(reset), reinterpret_cast<void*>(D3D9Device_Reset));
11371131
directx_device9_reset_hook->apply();
1132+
1133+
if (!directx_device9_endscene_hook->is_enabled())
1134+
{
1135+
current_dx_device = nullptr;
1136+
directx_device9_endscene_hook.reset();
1137+
}
1138+
1139+
if (!directx_device9_reset_hook->is_enabled())
1140+
{
1141+
current_dx_device = nullptr;
1142+
directx_device9_reset_hook.reset();
1143+
}
11381144
}
11391145
#endif // defined
11401146

RemoteInput/Plugin/ControlCenter.cxx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@ ControlCenter::ControlCenter(std::int32_t pid, bool is_controller, std::unique_p
118118

119119
ControlCenter::~ControlCenter()
120120
{
121-
terminate();
121+
//terminate();
122+
123+
if (io_controller)
124+
{
125+
io_controller.reset();
126+
}
122127

123128
if (sync_signal)
124129
{

RemoteInput/Plugin/InputOutput.cxx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static java::KeyEvent::KeyCodes control_keys_locations[] = {
9797
java::KeyEvent::KeyCodes::KEY_LOCATION_STANDARD
9898
};
9999

100-
InputOutput::InputOutput(Reflection* reflection) noexcept : vm(nullptr), applet(reflection->getApplet()), mutex(), input_thread(2), event_queue(nullptr), currently_held_key(-1), held_keys(), x(-1), y(-1), w(-1), h(-1), click_count(0), keyboard_speed(0), keyboard_repeat_delay(0), mouse_buttons()
100+
InputOutput::InputOutput(Reflection* reflection) noexcept : vm(nullptr), applet(reflection->getApplet()), mutex(), input_thread(new ThreadPool(2)), event_queue(nullptr), currently_held_key(-1), held_keys(), x(-1), y(-1), w(-1), h(-1), click_count(0), keyboard_speed(0), keyboard_repeat_delay(0), mouse_buttons()
101101
{
102102
reflection->getEnv()->GetJavaVM(&vm);
103103

@@ -158,7 +158,10 @@ InputOutput::InputOutput(Reflection* reflection) noexcept : vm(nullptr), applet(
158158

159159
InputOutput::~InputOutput() noexcept
160160
{
161-
this->input_thread.terminate();
161+
// Purposely do NOT join the thread or reset! This will hang upon dll unload.
162+
// We `release` it instead to prevent this.
163+
//this->input_thread->terminate();
164+
this->input_thread.release();
162165
this->event_queue.reset();
163166
this->vm = nullptr;
164167
this->applet = nullptr;
@@ -316,7 +319,7 @@ void InputOutput::hold_key(std::int32_t code) noexcept
316319

317320
if (this->keyboard_speed >= 0 && this->keyboard_repeat_delay >= 0)
318321
{
319-
input_thread.add_task([&](std::atomic_bool &stopped) {
322+
input_thread->add_task([&](std::atomic_bool &stopped) {
320323
if (this->keyboard_repeat_delay > 0)
321324
{
322325
yield_thread(std::chrono::milliseconds(this->keyboard_repeat_delay));

RemoteInput/Plugin/InputOutput.hxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ private:
2727
JavaVM* vm;
2828
jobject applet;
2929
std::mutex mutex;
30-
ThreadPool input_thread;
30+
std::unique_ptr<ThreadPool> input_thread;
3131
std::unique_ptr<java::RIEventQueue> event_queue;
3232

3333
// MARK: - Input Variables

0 commit comments

Comments
 (0)