v1.8.31: fix SetWindowLongW overflow — unsigned 32-bit style mask
GetWindowLongW returns signed int; bitwise ops with WS_POPUP (0x80000000) overflow ctypes c_long. Fixed with & 0xFFFFFFFF mask + ctypes.c_long() cast. Also tightened window class filter: pid_match now requires known mstsc class. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -397,7 +397,7 @@ class EmbeddedRDP:
|
||||
)
|
||||
is_dialog = class_name == "#32770"
|
||||
|
||||
if pid_match or (title_match and (is_mstsc_class or is_dialog)):
|
||||
if (pid_match or title_match) and (is_mstsc_class or is_dialog):
|
||||
found_windows.append((hwnd, class_name, title, win_pid))
|
||||
return True
|
||||
|
||||
@@ -524,12 +524,13 @@ class EmbeddedRDP:
|
||||
|
||||
try:
|
||||
# Remove decorations, make child
|
||||
style = user32.GetWindowLongW(hwnd, GWL_STYLE)
|
||||
# Use unsigned 32-bit mask to avoid ctypes overflow
|
||||
style = user32.GetWindowLongW(hwnd, GWL_STYLE) & 0xFFFFFFFF
|
||||
style = (style | WS_CHILD | WS_VISIBLE) & ~(
|
||||
WS_POPUP | WS_CAPTION | WS_THICKFRAME |
|
||||
WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX
|
||||
)
|
||||
user32.SetWindowLongW(hwnd, GWL_STYLE, style)
|
||||
) & 0xFFFFFFFF
|
||||
user32.SetWindowLongW(hwnd, GWL_STYLE, ctypes.c_long(style).value)
|
||||
|
||||
# Reparent
|
||||
user32.SetParent(hwnd, parent_hwnd)
|
||||
@@ -657,31 +658,18 @@ class EmbeddedRDP:
|
||||
"""Check if mstsc process is still running (parent or children)."""
|
||||
if not self._process:
|
||||
return False
|
||||
# Parent still alive
|
||||
if self._process.poll() is None:
|
||||
return True
|
||||
# Parent exited but child mstsc may be alive
|
||||
if _HAS_PSUTIL:
|
||||
try:
|
||||
pids = _find_mstsc_pids(self._process.pid)
|
||||
for pid in pids:
|
||||
if pid == self._process.pid:
|
||||
continue
|
||||
try:
|
||||
p = psutil.Process(pid)
|
||||
if p.is_running():
|
||||
return True
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||
pass
|
||||
except Exception:
|
||||
pass
|
||||
# Check if embedded window still exists
|
||||
# Primary check: is the embedded window still valid?
|
||||
# This is the most reliable indicator — works regardless of PID tracking
|
||||
if self._mstsc_hwnd:
|
||||
try:
|
||||
import ctypes
|
||||
return bool(ctypes.windll.user32.IsWindow(self._mstsc_hwnd))
|
||||
if ctypes.windll.user32.IsWindow(self._mstsc_hwnd):
|
||||
return True
|
||||
except Exception:
|
||||
pass
|
||||
# Fallback: parent process still running
|
||||
if self._process.poll() is None:
|
||||
return True
|
||||
return False
|
||||
|
||||
@property
|
||||
|
||||
BIN
releases/ServerManager-v1.8.31-win-x64.exe
Normal file
BIN
releases/ServerManager-v1.8.31-win-x64.exe
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
"""Version info for ServerManager."""
|
||||
|
||||
__version__ = "1.8.29"
|
||||
__version__ = "1.8.31"
|
||||
__app_name__ = "ServerManager"
|
||||
__author__ = "aibot777"
|
||||
__description__ = "Desktop GUI for managing remote servers"
|
||||
|
||||
Reference in New Issue
Block a user