From: Hugh McMaster Subject: [PATCH 1/2] cmd/tests: Add tests for console InsertMode Message-Id: Date: Tue, 5 May 2015 22:06:23 +1000 The tests pass on the testbot (https://testbot.winehq.org/JobDetails.pl?Key=13238). They simulate overwrite mode (0) and enabled (positive non-zero). This patch supercedes patch 111063. --- programs/cmd/tests/Makefile.in | 4 +- programs/cmd/tests/insertmode.c | 140 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 programs/cmd/tests/insertmode.c diff --git a/programs/cmd/tests/Makefile.in b/programs/cmd/tests/Makefile.in index 87942fe..4777ac0 100644 --- a/programs/cmd/tests/Makefile.in +++ b/programs/cmd/tests/Makefile.in @@ -1,6 +1,8 @@ TESTDLL = cmd.exe +IMPORTS = advapi32 C_SRCS = \ - batch.c + batch.c \ + insertmode.c RC_SRCS = rsrc.rc diff --git a/programs/cmd/tests/insertmode.c b/programs/cmd/tests/insertmode.c new file mode 100644 index 0000000..0ba6d2b --- /dev/null +++ b/programs/cmd/tests/insertmode.c @@ -0,0 +1,140 @@ +/* + * Copyright 2015 Hugh McMaster + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include "wine/test.h" + +/* AttachConsole is not present on Windows 2000, although the SDK says it should be */ +static BOOL (__cdecl *pAttachConsole)(DWORD process_id); + +static BOOL have_AttachConsole(void) +{ + HMODULE hmod = GetModuleHandleA("kernel32.dll"); + + pAttachConsole = (void *)GetProcAddress(hmod, "AttachConsole"); + if (!pAttachConsole) + return FALSE; + return TRUE; +} + +static LONG reg_get_insertmode(DWORD *value) +{ + HKEY hkey; + DWORD size = sizeof(DWORD); + LONG ret; + + if (!(ret = RegOpenKeyExA(HKEY_CURRENT_USER, "Console", 0, KEY_READ, &hkey))) + { + ret = RegQueryValueExA(hkey, "InsertMode", NULL, NULL, (BYTE *)value, &size); + RegCloseKey(hkey); + } + return ret; +} + +static LONG reg_set_insertmode(DWORD value) +{ + HKEY hkey; + LONG ret; + + if (!(ret = RegOpenKeyExA(HKEY_CURRENT_USER, "Console", 0, KEY_SET_VALUE, &hkey))) + { + ret = RegSetValueExA(hkey, "InsertMode", 0, REG_DWORD, (const BYTE *)&value, sizeof(DWORD)); + RegCloseKey(hkey); + } + return ret; +} + +static BOOL is_insertmode(DWORD mode) +{ + if ((mode & (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS)) == (ENABLE_INSERT_MODE|ENABLE_EXTENDED_FLAGS)) + return TRUE; + else + return FALSE; +} + +static BOOL run_insertmode_test(DWORD reg_value, BOOL *status) +{ + STARTUPINFOA si; + PROCESS_INFORMATION pi; + char cmdline[32]; + DWORD mode, res; + + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.dwFlags |= STARTF_USESHOWWINDOW; + si.wShowWindow = SW_SHOWMINIMIZED; + ZeroMemory(&pi, sizeof(pi)); + + reg_set_insertmode(reg_value); + + strcpy(cmdline, "cmd.exe /c ping 127.0.0.1 -n 4"); + if (!CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { + pAttachConsole(ATTACH_PARENT_PROCESS); + win_skip("Error creating process (%d), skipping InsertMode tests\n", GetLastError()); + return FALSE; + } + Sleep(1000); /* Wait for console to fully initialize */ + + pAttachConsole(pi.dwProcessId); + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + *status = is_insertmode(mode); + FreeConsole(); + + res = WaitForSingleObject(pi.hProcess, 5000); + if (res == WAIT_TIMEOUT) + TerminateProcess(pi.hProcess, 1); + + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + return TRUE; +} + +START_TEST(insertmode) +{ + DWORD mode, reg_value; + BOOL status; + + GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &mode); + status = is_insertmode(mode); + reg_get_insertmode(®_value); + todo_wine ok(status == reg_value, "Console status (%x) does not match registry value (%x)\n", + status, reg_value); + + if (!have_AttachConsole()) { + win_skip("AttachConsole not present in kernel32.dll, skipping InsertMode tests\n"); + return; + } + + FreeConsole(); + + if (!run_insertmode_test(0, &status)) { + reg_set_insertmode(reg_value); /* Restore original InsertMode value */ + return; + } + todo_wine ok(status == 0, "Incorrect console status, got %d, expected 0\n", status); + + run_insertmode_test(1, &status); + todo_wine ok(status == 1, "Incorrect console status, got %d, expected 1\n", status); + + run_insertmode_test(10, &status); + todo_wine ok(status == 1, "Incorrect console status, got %d, expected 1\n", status); + + pAttachConsole(ATTACH_PARENT_PROCESS); + reg_set_insertmode(reg_value); /* Restore original InsertMode value */ +} -- 1.9.1