// SPDX-License-Identifier: LGPL-2.1-or-later // Drive a disposable copy of GoldWave 5.70 using real Wine keyboard input. #include #include static DWORD appPid; static HWND app, dialog; static BOOL CALLBACK dismiss_setup(HWND window, LPARAM unused) { (void)unused; WCHAR text[64] = {0}; GetWindowTextW(window, text, 64); if (!lstrcmpW(text, L"No") || !lstrcmpW(text, L"&No")) PostMessageW(window, BM_CLICK, 0, 0); return TRUE; } static BOOL CALLBACK find_window(HWND window, LPARAM unused) { (void)unused; DWORD pid = 0; WCHAR title[128] = {0}; GetWindowThreadProcessId(window, &pid); GetWindowTextW(window, title, 128); if (pid == appPid && IsWindowVisible(window)) { WCHAR cls[128] = {0}; GetClassNameW(window, cls, 128); if (!lstrcmpW(cls, L"TGWMainForm")) app = window; if (GetDlgItem(window, cmb1)) dialog = window; if (!lstrcmpW(cls, L"TMessageForm")) EnumChildWindows(window, dismiss_setup, 0); } return TRUE; } static void key(WORD vk, BOOL alt, BOOL control) { INPUT input[6] = {0}; UINT count = 0; if (alt) { input[count].ki.wVk = VK_MENU; ++count; } if (control) { input[count].ki.wVk = VK_CONTROL; ++count; } input[count++].ki.wVk = vk; input[count].ki.wVk = vk; input[count++].ki.dwFlags = KEYEVENTF_KEYUP; if (control) { input[count].ki.wVk = VK_CONTROL; input[count++].ki.dwFlags = KEYEVENTF_KEYUP; } if (alt) { input[count].ki.wVk = VK_MENU; input[count++].ki.dwFlags = KEYEVENTF_KEYUP; } for (UINT i = 0; i < count; ++i) input[i].type = INPUT_KEYBOARD; if (SendInput(count, input, sizeof(INPUT)) != count) ExitProcess(3); Sleep(400); } int WINAPI WinMain(HINSTANCE instance, HINSTANCE previous, LPSTR args, int show) { (void)instance; (void)previous; (void)args; (void)show; // The runner supplies a fresh prefix; this setting never touches the user's // configuration. Match the reported Force screen reader mode setup. HKEY options; if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\GoldWave\\GoldWave\\Options", 0, NULL, 0, KEY_SET_VALUE, NULL, &options, NULL) != ERROR_SUCCESS) return 2; DWORD startupOptions = 0x3008; RegSetValueExW(options, L"StartupOptions", 0, REG_DWORD, (BYTE *)&startupOptions, sizeof(startupOptions)); RegCloseKey(options); if (RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\GoldWave\\GoldWave", 0, NULL, 0, KEY_SET_VALUE, NULL, &options, NULL) != ERROR_SUCCESS) return 2; const WCHAR version[] = L"5.70"; RegSetValueExW(options, L"Version", 0, REG_SZ, (const BYTE *)version, sizeof(version)); RegCloseKey(options); WCHAR executable[4096] = {0}; if (!GetEnvironmentVariableW(L"WINE_ACCESS_GOLDWAVE_EXE", executable, 4096)) return 2; STARTUPINFOW startup = {0}; startup.cb = sizeof(startup); PROCESS_INFORMATION process = {0}; if (!CreateProcessW(executable, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &process)) return 2; appPid = process.dwProcessId; for (int i = 0; i < 200 && !app; ++i) { EnumWindows(find_window, 0); Sleep(50); } if (!app) return 2; SetForegroundWindow(app); Sleep(500); key('F', TRUE, FALSE); key(VK_DOWN, FALSE, FALSE); key(VK_DOWN, FALSE, FALSE); key(VK_ESCAPE, FALSE, FALSE); key(VK_ESCAPE, FALSE, FALSE); key('O', FALSE, TRUE); for (int i = 0; i < 100 && !dialog; ++i) { EnumWindows(find_window, 0); Sleep(50); } if (!dialog) return 2; HWND combo = GetDlgItem(dialog, cmb1); SendMessageW(dialog, WM_NEXTDLGCTL, (WPARAM)combo, TRUE); Sleep(500); WCHAR before[512] = {0}, after[512] = {0}; SendMessageW(combo, WM_GETTEXT, 512, (LPARAM)before); key(VK_DOWN, FALSE, FALSE); SendMessageW(combo, WM_GETTEXT, 512, (LPARAM)after); if (!lstrcmpW(before, after)) return 4; GUITHREADINFO info = {0}; info.cbSize = sizeof(info); GetGUIThreadInfo(GetWindowThreadProcessId(dialog, NULL), &info); if (info.hwndFocus != combo) return 4; key(VK_DOWN, FALSE, FALSE); key(VK_UP, FALSE, FALSE); key(VK_ESCAPE, FALSE, FALSE); PostMessageW(app, WM_CLOSE, 0, 0); int result = WaitForSingleObject(process.hProcess, 3000) == WAIT_OBJECT_0 ? 0 : 2; CloseHandle(process.hThread); CloseHandle(process.hProcess); return result; }