Add files via upload

This commit is contained in:
87owo authored and GitHub committed 2026-10-10 22:33:14 +08:00
1 parent 6d088d05c2
commit 7d8ce16235
2 files changed
+125 -66

No files matched your search

+10 -3
View File
@@ -70,6 +70,8 @@ PYAS_MESSAGE_QUIT = 4
PYAS_MESSAGE_DRIVER_UNLOAD = 5
PYAS_MESSAGE_DRIVER_UNINSTALL = 6
PYAS_MAINTENANCE_MESSAGE = 0x8000 + 0x501
MSGFLT_REMOVE = 2
MSGFLT_DISALLOW = 2
PYAS_MAINTENANCE_COMMANDS = frozenset(
{
PYAS_MESSAGE_CLOSE,
@@ -1103,6 +1105,8 @@ class WindowHook:
self.old_wndproc = self.GetWindowLong(hwnd, self.GWLP_WNDPROC)
self.SetWindowLong(hwnd, self.GWLP_WNDPROC, self.new_wndproc_cb)
self.maintenance_channel_ready = False
try:
self.user32.ChangeWindowMessageFilterEx.argtypes = [
ctypes.c_void_p,
@@ -1113,14 +1117,17 @@ class WindowHook:
self.user32.ChangeWindowMessageFilter.argtypes = [ctypes.c_uint, ctypes.c_uint]
self.user32.ChangeWindowMessageFilter.restype = ctypes.wintypes.BOOL
if not self.user32.ChangeWindowMessageFilter(PYAS_MAINTENANCE_MESSAGE, 0):
raise OSError("Could not remove process-wide maintenance message allowance")
self.user32.ChangeWindowMessageFilter(PYAS_MAINTENANCE_MESSAGE, MSGFLT_REMOVE)
filter_info = (ctypes.wintypes.DWORD * 2)(8, 0)
if not self.user32.ChangeWindowMessageFilterEx(
hwnd, PYAS_MAINTENANCE_MESSAGE, 2, None
hwnd, PYAS_MAINTENANCE_MESSAGE, MSGFLT_DISALLOW, ctypes.byref(filter_info)
):
raise OSError("Could not protect maintenance message channel")
if filter_info[1] == 3:
raise OSError("Maintenance message remains allowed by a wider filter")
self.maintenance_channel_ready = True
self.user32.ChangeWindowMessageFilterEx(hwnd, self.WM_COPYDATA, 1, None)
except Exception:
+115 -63
View File
@@ -1,4 +1,4 @@
#define AppId "{{a7d7bac3-93b8-4630-8308-c7a56bf7fdf4}"
#define AppId "{{a7d7bac3-93b8-4630-8308-c7a56bf7fdf4}"
#define AppName "PYAS"
#define AppVersion "3.7.1.0"
#define AppPublisher "PYAS Security"
@@ -39,6 +39,8 @@ OutputDir=Output
OutputBaseFilename=PYAS_Setup
UsePreviousTasks=no
SetupLogging=yes
CloseApplications=no
RestartApplications=no
[Languages]
Name: "english"; MessagesFile: "compiler:Default.isl"
@@ -62,7 +64,7 @@ Source: "Redist\MicrosoftEdgeWebview2Setup.exe"; Flags: dontcopy noencryption
Source: "Payload\Engine\*"; DestDir: "{app}\Engine"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\Interface\*"; DestDir: "{app}\Interface"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\License\*"; DestDir: "{app}\License"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "Payload\PYAS.exe"; DestDir: "{app}"; Flags: ignoreversion; AfterInstall: FinalizeDriverRemoval
Source: "Payload\PYAS.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "Payload\Plugins\*"; DestDir: "{app}\Plugins"; Flags: ignoreversion recursesubdirs createallsubdirs
[Registry]
@@ -98,7 +100,9 @@ english.InstallVCRedist=Install Microsoft Visual C++ Runtime
chinesesimplified.InstallVCRedist=安装 Microsoft Visual C++ 运行库
chinesetraditional.InstallVCRedist=安裝 Microsoft Visual C++ 執行庫
english.LegacyVersionDetected=An older version of PYAS was detected. Please uninstall it manually before installing.
english.QuitFailed=PYAS or its driver could not be stopped safely. Restart Windows and run Setup again.
english.QuitFailed=PYAS is still running or did not respond to the exit request. Exit PYAS from its tray menu, then retry Setup.
chinesesimplified.QuitFailed=PYAS 仍在运行或未响应退出请求。请从托盘菜单退出 PYAS,然后重试安装。
chinesetraditional.QuitFailed=PYAS 仍在運作或未回應退出請求。請從系統匣選單退出 PYAS,再重試安裝。
english.DependencyInstallFailed=Required Microsoft runtime installation failed. Setup cannot continue.
english.WebView2InstallFailed=Microsoft Edge WebView2 Runtime could not be detected. Check your connection or install the Evergreen Runtime manually, then retry Setup.%n%nDetails: %1
chinesesimplified.WebView2InstallFailed=无法检测到 Microsoft Edge WebView2 运行环境。请检查网络或手动安装 Evergreen 运行环境,然后重试安装。%n%n详细信息:%1
@@ -111,8 +115,21 @@ var
DependencyRestartRequired: Boolean;
DependenciesReady: Boolean;
function FindWindow(lpClassName: LongWord; lpWindowName: string): HWND;
external 'FindWindowW@user32.dll stdcall';
function GetWindowThreadProcessId(Wnd: HWND; var ProcessId: Cardinal): Cardinal;
external 'GetWindowThreadProcessId@user32.dll stdcall';
function OpenProcess(Access: Cardinal; InheritHandle: Boolean; ProcessId: Cardinal): THandle;
external '[email protected] stdcall';
function WaitForSingleObject(Handle: THandle; Timeout: Cardinal): Cardinal;
external '[email protected] stdcall';
function CloseHandle(Handle: THandle): Boolean;
external '[email protected] stdcall';
function SendMessageTimeout(Wnd: HWND; Msg: Cardinal; WParam, LParam: Longint;
Flags, Timeout: Cardinal; var MessageResult: LongWord): Longint;
external '[email protected] stdcall';
function GetTickCount: Cardinal;
external '[email protected] stdcall';
@@ -247,9 +264,98 @@ begin
Result := FmtMessage(CustomMessage('WebView2InstallFailed'), [Detail]);
end;
function QuitRunningInstance: Boolean;
var
Wnd: HWND;
ProcessId, Started, WaitResult: Cardinal;
ProcessHandle: THandle;
MessageResult: LongWord;
begin
Result := True;
Started := GetTickCount;
repeat
Wnd := FindWindowByWindowName('PYAS Security');
if Wnd <> 0 then Break;
if not CheckForMutexes('PYAS_Security_Mutex,PYAS_Security_Recovery_Mutex') then
begin
Log('PYAS is not running; no exit request is needed');
Exit;
end;
Sleep(100);
until GetTickCount - Started >= 10000;
Result := False;
if Wnd = 0 then
begin
Log('PYAS is running but its exit message window is not available');
Exit;
end;
ProcessId := 0;
GetWindowThreadProcessId(Wnd, ProcessId);
if ProcessId = 0 then
begin
Result := FindWindowByWindowName('PYAS Security') = 0;
Exit;
end;
ProcessHandle := OpenProcess($00100000, False, ProcessId);
if ProcessHandle = 0 then
begin
Result := (FindWindowByWindowName('PYAS Security') = 0) and
not CheckForMutexes('PYAS_Security_Mutex,PYAS_Security_Recovery_Mutex');
Log('Could not open the PYAS process for exit monitoring');
Exit;
end;
try
if WaitForSingleObject(ProcessHandle, 0) = 0 then
begin
Result := True;
Exit;
end;
Log('Sending an exit request to PYAS; the application owns driver shutdown');
MessageResult := 0;
if SendMessageTimeout(Wnd, $8501, 4, 0, $0022, 5000, MessageResult) = 0 then
Log('PYAS exit message delivery failed or timed out')
else if MessageResult <> 1 then
Log('PYAS rejected the exit request; its maintenance channel may not be ready')
else
Log('PYAS accepted the exit request; waiting for process termination');
Started := GetTickCount;
repeat
WaitResult := WaitForSingleObject(ProcessHandle, 0);
if WaitResult = 0 then
begin
Result := (FindWindowByWindowName('PYAS Security') = 0) and
not CheckForMutexes('PYAS_Security_Mutex,PYAS_Security_Recovery_Mutex');
if Result then Log('PYAS process exited');
Exit;
end;
if WaitResult <> $00000102 then
begin
Log('PYAS process exit monitoring failed');
Exit;
end;
Sleep(100);
until GetTickCount - Started >= 30000;
Log('PYAS is still running after the exit request');
finally
CloseHandle(ProcessHandle);
end;
end;
function PrepareToInstall(var NeedsRestart: Boolean): string;
begin
DependenciesReady := False;
NeedsRestart := DependencyRestartRequired;
if not QuitRunningInstance then
begin
Result := CustomMessage('QuitFailed');
Exit;
end;
try
Result := EnsureWebView2;
except
@@ -260,53 +366,8 @@ begin
NeedsRestart := DependencyRestartRequired;
end;
function WaitForMainWindowToClose(TimeoutMs: Cardinal): Boolean;
var
Deadline: Cardinal;
begin
Deadline := GetTickCount + TimeoutMs;
repeat
if FindWindow(0, 'PYAS Security') = 0 then
begin
Result := True;
Exit;
end;
Sleep(100);
until GetTickCount >= Deadline;
Result := False;
end;
function QuitOldInstance(InstallPath: string): Boolean;
var
ResultCode: Integer;
ExePath: string;
begin
Result := True;
ExePath := InstallPath + '\{#AppExeName}';
if not FileExists(ExePath) then Exit;
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) then
begin
Result := False;
Exit;
end;
Result := (ResultCode = 0) and WaitForMainWindowToClose(30000);
end;
procedure FinalizeDriverRemoval;
var
ResultCode: Integer;
ExePath: string;
begin
ExePath := ExpandConstant('{app}\{#AppExeName}');
if not Exec(ExePath, '-quit', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) or (ResultCode <> 0) then
RaiseException(CustomMessage('QuitFailed'));
end;
function InitializeSetup(): Boolean;
var
OldInstallPath: string;
LegacyPath: string;
begin
DependencyRestartRequired := False;
@@ -319,23 +380,14 @@ begin
Exit;
end;
if RegQueryStringValue(HKLM, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) or
RegQueryStringValue(HKCU, 'Software\Microsoft\Windows\CurrentVersion\Uninstall\' + ExpandConstant('{#AppId}') + '_is1', 'InstallLocation', OldInstallPath) then
begin
if not QuitOldInstance(OldInstallPath) then
begin
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
Result := False;
Exit;
end;
end;
Result := True;
Result := QuitRunningInstance;
if not Result then
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
end;
function InitializeUninstall(): Boolean;
begin
Result := QuitOldInstance(ExpandConstant('{app}'));
Result := QuitRunningInstance;
if not Result then
MsgBox(CustomMessage('QuitFailed'), mbCriticalError, MB_OK);
end;