#include <stdio.h>
static BOOL (WINAPI *pGetConsoleInputExeNameA)(DWORD, LPSTR);
+static DWORD (WINAPI *pGetConsoleProcessList)(LPDWORD, DWORD);
+static HANDLE (WINAPI *pOpenConsoleW)(LPCWSTR,DWORD,BOOL,DWORD);
static BOOL (WINAPI *pSetConsoleInputExeNameA)(LPCSTR);
/* DEFAULT_ATTRIB is used for all initial filling of the console.
hKernel32 = GetModuleHandleA("kernel32.dll");
KERNEL32_GET_PROC(GetConsoleInputExeNameA);
+ KERNEL32_GET_PROC(GetConsoleProcessList);
+ KERNEL32_GET_PROC(OpenConsoleW);
KERNEL32_GET_PROC(SetConsoleInputExeNameA);
#undef KERNEL32_GET_PROC
ok(GetLastError() == 0xdeadbeef, "GetLastError: expecting %u got %u\n",
0xdeadbeef, GetLastError());
- if (info.dwSize == 12)
- {
- win_skip("NULL CONSOLE_CURSOR_INFO will crash on win9x\n");
- return;
- }
-
- SetLastError(0xdeadbeef);
- ret = GetConsoleCursorInfo(hCon, NULL);
- ok(!ret, "Expected failure\n");
- ok(GetLastError() == ERROR_INVALID_ACCESS, "GetLastError: expecting %u got %u\n",
- ERROR_INVALID_ACCESS, GetLastError());
+ /* Don't test NULL CONSOLE_CURSOR_INFO, it crashes on win9x and win7 */
}
static void testEmptyWrite(HANDLE hCon)
const int mylen = strlen(mytest);
const int mylen2 = strchr(mytest, '\n') - mytest;
int p;
+ WORD attr;
ok(GetConsoleMode(hCon, &mode) && SetConsoleMode(hCon, (mode | ENABLE_PROCESSED_OUTPUT) & ~ENABLE_WRAP_AT_EOL_OUTPUT),
"clearing wrap at EOL & setting processed output\n");
{
okCHAR(hCon, c, mytest[c.X - sbSize.X + 5], TEST_ATTRIB);
}
+
+ ReadConsoleOutputAttribute(hCon, &attr, 1, c, &len);
+ /* Win9x and WinMe change the attribs for '\n' up to 'f' */
+ if (attr == TEST_ATTRIB)
+ {
+ win_skip("Win9x/WinMe don't respect ~ENABLE_WRAP_AT_EOL_OUTPUT\n");
+ return;
+ }
+
okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
c.X = 0; c.Y++;
const char* mytest = "abcd\nf\tg";
const int mylen = strlen(mytest);
int p;
+ WORD attr;
ok(GetConsoleMode(hCon, &mode) && SetConsoleMode(hCon, mode | (ENABLE_WRAP_AT_EOL_OUTPUT|ENABLE_PROCESSED_OUTPUT)),
"setting wrap at EOL & processed output\n");
okCHAR(hCon, c, mytest[p], TEST_ATTRIB);
}
c.X = sbSize.X - 9 + p;
- okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
+ ReadConsoleOutputAttribute(hCon, &attr, 1, c, &len);
+ if (attr == TEST_ATTRIB)
+ win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
+ else
+ okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
c.X = 0; c.Y++;
okCHAR(hCon, c, mytest[5], TEST_ATTRIB);
for (c.X = 1; c.X < 8; c.X++)
c.X = 0; c.Y++;
okCHAR(hCon, c, mytest[3], TEST_ATTRIB);
c.X++;
- okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
+ ReadConsoleOutputAttribute(hCon, &attr, 1, c, &len);
+ if (attr == TEST_ATTRIB)
+ win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
+ else
+ okCHAR(hCon, c, ' ', DEFAULT_ATTRIB);
c.X = 0; c.Y++;
okCHAR(hCon, c, mytest[5], TEST_ATTRIB);
ok(!lstrcmpA(buffer, input_exe), "got %s expected %s\n", buffer, input_exe);
}
+static void test_GetConsoleProcessList(void)
+{
+ DWORD ret, *list = NULL;
+
+ if (!pGetConsoleProcessList)
+ {
+ win_skip("GetConsoleProcessList is not available\n");
+ return;
+ }
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleProcessList(NULL, 0);
+ ok(ret == 0, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleProcessList(NULL, 1);
+ ok(ret == 0, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n",
+ GetLastError());
+
+ /* We should only have 1 process but only for these specific unit tests as
+ * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) would
+ * give us two processes for example.
+ */
+ list = HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD));
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleProcessList(list, 0);
+ ok(ret == 0, "Expected failure\n");
+ ok(GetLastError() == ERROR_INVALID_PARAMETER,
+ "Expected ERROR_INVALID_PARAMETER, got %d\n",
+ GetLastError());
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleProcessList(list, 1);
+ todo_wine
+ ok(ret == 1, "Expected 1, got %d\n", ret);
+
+ HeapFree(GetProcessHeap(), 0, list);
+
+ list = HeapAlloc(GetProcessHeap(), 0, ret * sizeof(DWORD));
+
+ SetLastError(0xdeadbeef);
+ ret = pGetConsoleProcessList(list, ret);
+ todo_wine
+ ok(ret == 1, "Expected 1, got %d\n", ret);
+
+ if (ret == 1)
+ {
+ DWORD pid = GetCurrentProcessId();
+ ok(list[0] == pid, "Expected %d, got %d\n", pid, list[0]);
+ }
+
+ HeapFree(GetProcessHeap(), 0, list);
+}
+
+static void test_OpenConsoleW(void)
+{
+ static const WCHAR coninW[] = {'C','O','N','I','N','$',0};
+ static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0};
+ static const WCHAR emptyW[] = {0};
+ static const WCHAR invalidW[] = {'I','N','V','A','L','I','D',0};
+
+ static const struct
+ {
+ LPCWSTR name;
+ DWORD access;
+ BOOL inherit;
+ DWORD creation;
+ DWORD gle;
+ } invalid_table[] = {
+ {NULL, 0, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {NULL, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER},
+ {NULL, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {NULL, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER},
+ {emptyW, 0, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {emptyW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER},
+ {emptyW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {emptyW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER},
+ {invalidW, 0, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {invalidW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER},
+ {invalidW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_INVALID_PARAMETER},
+ {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {invalidW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING, ERROR_INVALID_PARAMETER},
+ {coninW, 0, FALSE, 0, ERROR_SHARING_VIOLATION},
+ {coninW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER},
+ {coninW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_SHARING_VIOLATION},
+ {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, ERROR_SHARING_VIOLATION},
+ {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, ERROR_SHARING_VIOLATION},
+ {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {coninW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER},
+ {conoutW, 0, FALSE, 0, ERROR_SHARING_VIOLATION},
+ {conoutW, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, ERROR_INVALID_PARAMETER},
+ {conoutW, 0, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, 0, ERROR_SHARING_VIOLATION},
+ {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_NEW, ERROR_SHARING_VIOLATION},
+ {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, CREATE_ALWAYS, ERROR_SHARING_VIOLATION},
+ {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_ALWAYS, ERROR_INVALID_PARAMETER},
+ {conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, TRUNCATE_EXISTING, ERROR_INVALID_PARAMETER},
+ };
+
+ int index;
+ HANDLE ret;
+
+ if (!pOpenConsoleW)
+ {
+ win_skip("OpenConsoleW is not available\n");
+ return;
+ }
+
+ for (index = 0; index < sizeof(invalid_table)/sizeof(invalid_table[0]); index++)
+ {
+ SetLastError(0xdeadbeef);
+ ret = pOpenConsoleW(invalid_table[index].name, invalid_table[index].access,
+ invalid_table[index].inherit, invalid_table[index].creation);
+ ok(ret == INVALID_HANDLE_VALUE,
+ "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
+ index, ret);
+ ok(GetLastError() == invalid_table[index].gle,
+ "Expected GetLastError() to return %u for index %d, got %u\n",
+ invalid_table[index].gle, index, GetLastError());
+ }
+
+ /* OpenConsoleW should not touch the last error on success. */
+ SetLastError(0xdeadbeef);
+ ret = pOpenConsoleW(coninW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING);
+ ok(ret != INVALID_HANDLE_VALUE,
+ "Expected OpenConsoleW to return a valid handle\n");
+ ok(GetLastError() == 0xdeadbeef,
+ "Expected the last error to be untouched, got %u\n", GetLastError());
+ if (ret != INVALID_HANDLE_VALUE)
+ CloseHandle(ret);
+
+ SetLastError(0xdeadbeef);
+ ret = pOpenConsoleW(conoutW, GENERIC_READ | GENERIC_WRITE, FALSE, OPEN_EXISTING);
+ ok(ret != INVALID_HANDLE_VALUE,
+ "Expected OpenConsoleW to return a valid handle\n");
+ ok(GetLastError() == 0xdeadbeef,
+ "Expected the last error to be untouched, got %u\n", GetLastError());
+ if (ret != INVALID_HANDLE_VALUE)
+ CloseHandle(ret);
+}
+
START_TEST(console)
{
HANDLE hConIn, hConOut;
/* still to be done: access rights & access on objects */
if (!pGetConsoleInputExeNameA || !pSetConsoleInputExeNameA)
- {
win_skip("GetConsoleInputExeNameA and/or SetConsoleInputExeNameA is not available\n");
- return;
- }
else
test_GetSetConsoleInputExeName();
+
+ test_GetConsoleProcessList();
+ test_OpenConsoleW();
}