2 * Unit tests for console API
4 * Copyright (c) 2003,2004 Eric Pouech
5 * Copyright (c) 2007 Kirill K. Smirnov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
26 static BOOL (WINAPI
*pGetConsoleInputExeNameA
)(DWORD
, LPSTR
);
27 static DWORD (WINAPI
*pGetConsoleProcessList
)(LPDWORD
, DWORD
);
28 static HANDLE (WINAPI
*pOpenConsoleW
)(LPCWSTR
,DWORD
,BOOL
,DWORD
);
29 static BOOL (WINAPI
*pSetConsoleInputExeNameA
)(LPCSTR
);
30 static BOOL (WINAPI
*pVerifyConsoleIoHandle
)(HANDLE handle
);
32 /* DEFAULT_ATTRIB is used for all initial filling of the console.
33 * all modifications are made with TEST_ATTRIB so that we could check
34 * what has to be modified or not
36 #define TEST_ATTRIB (BACKGROUND_BLUE | FOREGROUND_GREEN)
37 #define DEFAULT_ATTRIB (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED)
38 /* when filling the screen with non-blank chars, this macro defines
39 * what character should be at position 'c'
41 #define CONTENT(c) ('A' + (((c).Y * 17 + (c).X) % 23))
43 #define okCURSOR(hCon, c) do { \
44 CONSOLE_SCREEN_BUFFER_INFO __sbi; \
45 BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
46 __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
47 ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
48 (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
51 #define okCHAR(hCon, c, ch, attr) do { \
52 char __ch; WORD __attr; DWORD __len; BOOL expect; \
53 expect = ReadConsoleOutputCharacterA((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \
54 ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x\n", (c).X, (c).Y, (ch), (ch), __ch, __ch); \
55 expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \
56 ok(expect, "At (%d,%d): expecting attr %04x got %04x\n", (c).X, (c).Y, (attr), __attr); \
59 static void init_function_pointers(void)
63 #define KERNEL32_GET_PROC(func) \
64 p##func = (void *)GetProcAddress(hKernel32, #func); \
65 if(!p##func) trace("GetProcAddress(hKernel32, '%s') failed\n", #func);
67 hKernel32
= GetModuleHandleA("kernel32.dll");
68 KERNEL32_GET_PROC(GetConsoleInputExeNameA
);
69 KERNEL32_GET_PROC(GetConsoleProcessList
);
70 KERNEL32_GET_PROC(OpenConsoleW
);
71 KERNEL32_GET_PROC(SetConsoleInputExeNameA
);
72 KERNEL32_GET_PROC(VerifyConsoleIoHandle
);
74 #undef KERNEL32_GET_PROC
77 /* FIXME: this could be optimized on a speed point of view */
78 static void resetContent(HANDLE hCon
, COORD sbSize
, BOOL content
)
81 WORD attr
= DEFAULT_ATTRIB
;
85 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
87 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
89 ch
= (content
) ? CONTENT(c
) : ' ';
90 WriteConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
91 WriteConsoleOutputCharacterA(hCon
, &ch
, 1, c
, &len
);
96 static void testCursor(HANDLE hCon
, COORD sbSize
)
101 ok(SetConsoleCursorPosition(0, c
) == 0, "No handle\n");
102 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
103 ERROR_INVALID_HANDLE
, GetLastError());
106 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
111 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in lower-right\n");
116 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
117 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
118 ERROR_INVALID_PARAMETER
, GetLastError());
122 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
123 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
124 ERROR_INVALID_PARAMETER
, GetLastError());
128 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
129 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
130 ERROR_INVALID_PARAMETER
, GetLastError());
134 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
135 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
136 ERROR_INVALID_PARAMETER
, GetLastError());
139 static void testCursorInfo(HANDLE hCon
)
142 CONSOLE_CURSOR_INFO info
;
144 SetLastError(0xdeadbeef);
145 ret
= GetConsoleCursorInfo(NULL
, NULL
);
146 ok(!ret
, "Expected failure\n");
147 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
148 ERROR_INVALID_HANDLE
, GetLastError());
150 SetLastError(0xdeadbeef);
152 ret
= GetConsoleCursorInfo(NULL
, &info
);
153 ok(!ret
, "Expected failure\n");
154 ok(info
.dwSize
== -1, "Expected no change for dwSize\n");
155 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
156 ERROR_INVALID_HANDLE
, GetLastError());
158 /* Test the correct call first to distinguish between win9x and the rest */
159 SetLastError(0xdeadbeef);
160 ret
= GetConsoleCursorInfo(hCon
, &info
);
161 ok(ret
, "Expected success\n");
162 ok(info
.dwSize
== 25 ||
163 info
.dwSize
== 12 /* win9x */,
164 "Expected 12 or 25, got %d\n", info
.dwSize
);
165 ok(info
.bVisible
, "Expected the cursor to be visible\n");
166 ok(GetLastError() == 0xdeadbeef, "GetLastError: expecting %u got %u\n",
167 0xdeadbeef, GetLastError());
169 /* Don't test NULL CONSOLE_CURSOR_INFO, it crashes on win9x and win7 */
172 static void testEmptyWrite(HANDLE hCon
)
174 static const char emptybuf
[16];
179 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
182 ok(WriteConsoleA(hCon
, NULL
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
185 /* Passing a NULL lpBuffer with sufficiently large non-zero length succeeds
186 * on native Windows and result in memory-like contents being written to
187 * the console. Calling WriteConsoleW like this will crash on Wine. */
191 ok(!WriteConsoleA(hCon
, NULL
, 16, &len
, NULL
) && len
== -1, "WriteConsole\n");
194 /* Cursor advances for this call. */
196 ok(WriteConsoleA(hCon
, NULL
, 128, &len
, NULL
) != 0 && len
== 128, "WriteConsole\n");
200 ok(WriteConsoleA(hCon
, emptybuf
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
203 /* WriteConsole does not halt on a null terminator and is happy to write
204 * memory contents beyond the actual size of the buffer. */
206 ok(WriteConsoleA(hCon
, emptybuf
, 16, &len
, NULL
) != 0 && len
== 16, "WriteConsole\n");
211 static void testWriteSimple(HANDLE hCon
)
215 const char* mytest
= "abcdefg";
216 const int mylen
= strlen(mytest
);
218 /* single line write */
220 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
222 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
224 for (c
.X
= 0; c
.X
< mylen
; c
.X
++)
226 okCHAR(hCon
, c
, mytest
[c
.X
], TEST_ATTRIB
);
230 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
233 static void testWriteNotWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
237 const char* mytest
= "123";
238 const int mylen
= strlen(mytest
);
242 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
& ~(ENABLE_PROCESSED_OUTPUT
|ENABLE_WRAP_AT_EOL_OUTPUT
)),
243 "clearing wrap at EOL & processed output\n");
245 /* write line, wrapping disabled, buffer exceeds sb width */
246 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
247 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
249 ret
= WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
);
250 ok(ret
!= 0 && len
== mylen
, "Couldn't write, ret = %d, len = %d\n", ret
, len
);
252 for (p
= mylen
- 3; p
< mylen
; p
++)
254 c
.X
= sbSize
.X
- 3 + p
% 3;
255 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
259 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
261 p
= sbSize
.X
- 3 + mylen
% 3;
264 /* write line, wrapping disabled, strings end on end of line */
265 c
.X
= sbSize
.X
- mylen
; c
.Y
= 0;
266 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
268 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
271 static void testWriteNotWrappedProcessed(HANDLE hCon
, COORD sbSize
)
275 const char* mytest
= "abcd\nf\tg";
276 const int mylen
= strlen(mytest
);
277 const int mylen2
= strchr(mytest
, '\n') - mytest
;
281 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, (mode
| ENABLE_PROCESSED_OUTPUT
) & ~ENABLE_WRAP_AT_EOL_OUTPUT
),
282 "clearing wrap at EOL & setting processed output\n");
284 /* write line, wrapping disabled, buffer exceeds sb width */
285 c
.X
= sbSize
.X
- 5; c
.Y
= 0;
286 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-5\n");
288 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
290 for (c
.X
= sbSize
.X
- 5; c
.X
< sbSize
.X
- 1; c
.X
++)
292 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 5], TEST_ATTRIB
);
295 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
296 /* Win9x and WinMe change the attribs for '\n' up to 'f' */
297 if (attr
== TEST_ATTRIB
)
299 win_skip("Win9x/WinMe don't respect ~ENABLE_WRAP_AT_EOL_OUTPUT\n");
303 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
306 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
307 for (c
.X
= 1; c
.X
< 8; c
.X
++)
308 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
309 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
311 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
315 /* write line, wrapping disabled, strings end on end of line */
316 c
.X
= sbSize
.X
- 4; c
.Y
= 0;
317 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
319 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
321 for (c
.X
= sbSize
.X
- 4; c
.X
< sbSize
.X
; c
.X
++)
323 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 4], TEST_ATTRIB
);
326 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
327 for (c
.X
= 1; c
.X
< 8; c
.X
++)
328 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
329 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
331 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
335 /* write line, wrapping disabled, strings end after end of line */
336 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
337 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
339 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
341 for (p
= mylen2
- 3; p
< mylen2
; p
++)
343 c
.X
= sbSize
.X
- 3 + p
% 3;
344 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
347 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
348 for (c
.X
= 1; c
.X
< 8; c
.X
++)
349 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
350 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
352 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
357 static void testWriteWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
361 const char* mytest
= "abcd\nf\tg";
362 const int mylen
= strlen(mytest
);
365 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
,(mode
| ENABLE_WRAP_AT_EOL_OUTPUT
) & ~(ENABLE_PROCESSED_OUTPUT
)),
366 "setting wrap at EOL & clearing processed output\n");
368 /* write line, wrapping enabled, buffer doesn't exceed sb width */
369 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
370 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
372 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
374 for (p
= 0; p
< mylen
; p
++)
376 c
.X
= sbSize
.X
- 9 + p
;
377 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
379 c
.X
= sbSize
.X
- 9 + mylen
;
380 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
382 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
384 /* write line, wrapping enabled, buffer does exceed sb width */
385 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
386 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
390 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
393 static void testWriteWrappedProcessed(HANDLE hCon
, COORD sbSize
)
397 const char* mytest
= "abcd\nf\tg";
398 const int mylen
= strlen(mytest
);
402 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
| (ENABLE_WRAP_AT_EOL_OUTPUT
|ENABLE_PROCESSED_OUTPUT
)),
403 "setting wrap at EOL & processed output\n");
405 /* write line, wrapping enabled, buffer doesn't exceed sb width */
406 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
407 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
409 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
410 for (p
= 0; p
< 4; p
++)
412 c
.X
= sbSize
.X
- 9 + p
;
413 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
415 c
.X
= sbSize
.X
- 9 + p
;
416 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
417 if (attr
== TEST_ATTRIB
)
418 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
420 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
422 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
423 for (c
.X
= 1; c
.X
< 8; c
.X
++)
424 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
425 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
427 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
430 /* write line, wrapping enabled, buffer does exceed sb width */
431 c
.X
= sbSize
.X
- 3; c
.Y
= 2;
432 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
434 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
435 for (p
= 0; p
< 3; p
++)
437 c
.X
= sbSize
.X
- 3 + p
;
438 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
441 okCHAR(hCon
, c
, mytest
[3], TEST_ATTRIB
);
443 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
444 if (attr
== TEST_ATTRIB
)
445 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
447 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
450 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
451 for (c
.X
= 1; c
.X
< 8; c
.X
++)
452 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
453 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
455 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
459 static void testWrite(HANDLE hCon
, COORD sbSize
)
461 /* FIXME: should in fact ensure that the sb is at least 10 characters wide */
462 ok(SetConsoleTextAttribute(hCon
, TEST_ATTRIB
), "Setting default text color\n");
463 resetContent(hCon
, sbSize
, FALSE
);
464 testEmptyWrite(hCon
);
465 resetContent(hCon
, sbSize
, FALSE
);
466 testWriteSimple(hCon
);
467 resetContent(hCon
, sbSize
, FALSE
);
468 testWriteNotWrappedNotProcessed(hCon
, sbSize
);
469 resetContent(hCon
, sbSize
, FALSE
);
470 testWriteNotWrappedProcessed(hCon
, sbSize
);
471 resetContent(hCon
, sbSize
, FALSE
);
472 testWriteWrappedNotProcessed(hCon
, sbSize
);
473 resetContent(hCon
, sbSize
, FALSE
);
474 testWriteWrappedProcessed(hCon
, sbSize
);
477 static void testScroll(HANDLE hCon
, COORD sbSize
)
479 SMALL_RECT scroll
, clip
;
487 #define IN_SRECT(r,c) ((r).Left <= (c).X && (c).X <= (r).Right && (r).Top <= (c).Y && (c).Y <= (r).Bottom)
488 #define IN_SRECT2(r,d,c) ((d).X <= (c).X && (c).X <= (d).X + (r).Right - (r).Left && (d).Y <= (c).Y && (c).Y <= (d).Y + (r).Bottom - (r).Top)
490 /* no clipping, src & dst rect don't overlap */
491 resetContent(hCon
, sbSize
, TRUE
);
494 scroll
.Right
= W
- 1;
496 scroll
.Bottom
= H
- 1;
499 ci
.Char
.UnicodeChar
= '#';
500 ci
.Attributes
= TEST_ATTRIB
;
503 clip
.Right
= sbSize
.X
- 1;
505 clip
.Bottom
= sbSize
.Y
- 1;
507 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
509 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
511 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
513 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
517 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
519 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
520 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
521 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
525 /* no clipping, src & dst rect do overlap */
526 resetContent(hCon
, sbSize
, TRUE
);
529 scroll
.Right
= W
- 1;
531 scroll
.Bottom
= H
- 1;
534 ci
.Char
.UnicodeChar
= '#';
535 ci
.Attributes
= TEST_ATTRIB
;
538 clip
.Right
= sbSize
.X
- 1;
540 clip
.Bottom
= sbSize
.Y
- 1;
542 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
544 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
546 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
548 if (dst
.X
<= c
.X
&& c
.X
< dst
.X
+ W
&& dst
.Y
<= c
.Y
&& c
.Y
< dst
.Y
+ H
)
552 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
554 else if (c
.X
< W
&& c
.Y
< H
) okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
555 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
559 /* clipping, src & dst rect don't overlap */
560 resetContent(hCon
, sbSize
, TRUE
);
563 scroll
.Right
= W
- 1;
565 scroll
.Bottom
= H
- 1;
568 ci
.Char
.UnicodeChar
= '#';
569 ci
.Attributes
= TEST_ATTRIB
;
572 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
574 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
576 SetLastError(0xdeadbeef);
577 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
);
580 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
582 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
584 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
588 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
590 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
591 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
592 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
598 /* Win9x will fail, Only accept ERROR_NOT_ENOUGH_MEMORY */
599 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
,
600 "Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
603 /* clipping, src & dst rect do overlap */
604 resetContent(hCon
, sbSize
, TRUE
);
607 scroll
.Right
= W
- 1;
609 scroll
.Bottom
= H
- 1;
612 ci
.Char
.UnicodeChar
= '#';
613 ci
.Attributes
= TEST_ATTRIB
;
616 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
618 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
620 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
), "Scrolling SB\n");
622 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
624 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
626 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
630 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
632 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
633 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
634 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
639 static int mch_count
;
640 /* we need the event as Wine console event generation isn't synchronous
641 * (ie GenerateConsoleCtrlEvent returns before all ctrl-handlers in all
642 * processes have been called).
644 static HANDLE mch_event
;
645 static BOOL WINAPI
mch(DWORD event
)
652 static void testCtrlHandler(void)
654 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
655 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
656 ok(SetConsoleCtrlHandler(mch
, TRUE
), "Couldn't set handler\n");
657 /* wine requires the event for the test, as we cannot ensure, so far, that
658 * events are processed synchronously in GenerateConsoleCtrlEvent()
660 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
662 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
663 /* FIXME: it isn't synchronous on wine but it can still happen before we test */
664 if (0) ok(mch_count
== 1, "Event isn't synchronous\n");
665 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_OBJECT_0
, "event sending didn't work\n");
666 CloseHandle(mch_event
);
668 /* Turning off ctrl-c handling doesn't work on win9x such way ... */
669 ok(SetConsoleCtrlHandler(NULL
, TRUE
), "Couldn't turn off ctrl-c handling\n");
670 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
672 if(!(GetVersion() & 0x80000000))
673 /* ... and next line leads to an unhandled exception on 9x. Avoid it on 9x. */
674 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
675 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_TIMEOUT
&& mch_count
== 0, "Event shouldn't have been sent\n");
676 CloseHandle(mch_event
);
677 ok(SetConsoleCtrlHandler(mch
, FALSE
), "Couldn't remove handler\n");
678 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
679 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
683 * Test console screen buffer:
684 * 1) Try to set invalid handle.
685 * 2) Try to set non-console handles.
686 * 3) Use CONOUT$ file as active SB.
688 * 5) Test output codepage to show it is not a property of SB.
689 * 6) Test switching to old SB if we close all handles to current SB - works
690 * in Windows, TODO in wine.
692 * What is not tested but should be:
693 * 1) ScreenBufferInfo
695 static void testScreenBuffer(HANDLE hConOut
)
697 HANDLE hConOutRW
, hConOutRO
, hConOutWT
;
698 HANDLE hFileOutRW
, hFileOutRO
, hFileOutWT
;
700 char test_str1
[] = "Test for SB1";
701 char test_str2
[] = "Test for SB2";
702 char test_cp866
[] = {0xe2, 0xa5, 0xe1, 0xe2, 0};
703 char test_cp1251
[] = {0xf2, 0xe5, 0xf1, 0xf2, 0};
704 WCHAR test_unicode
[] = {0x0442, 0x0435, 0x0441, 0x0442, 0};
712 if (!IsValidCodePage(866))
714 skip("Codepage 866 not available\n");
718 /* In the beginning set output codepage to 866 */
719 oldcp
= GetConsoleOutputCP();
720 SetLastError(0xdeadbeef);
721 ret
= SetConsoleOutputCP(866);
722 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
724 win_skip("SetConsoleOutputCP is not implemented\n");
727 ok(ret
, "Cannot set output codepage to 866\n");
729 hConOutRW
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
730 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
731 CONSOLE_TEXTMODE_BUFFER
, NULL
);
732 ok(hConOutRW
!= INVALID_HANDLE_VALUE
,
733 "Cannot create a new screen buffer for ReadWrite\n");
734 hConOutRO
= CreateConsoleScreenBuffer(GENERIC_READ
,
735 FILE_SHARE_READ
, NULL
,
736 CONSOLE_TEXTMODE_BUFFER
, NULL
);
737 ok(hConOutRO
!= INVALID_HANDLE_VALUE
,
738 "Cannot create a new screen buffer for ReadOnly\n");
739 hConOutWT
= CreateConsoleScreenBuffer(GENERIC_WRITE
,
740 FILE_SHARE_WRITE
, NULL
,
741 CONSOLE_TEXTMODE_BUFFER
, NULL
);
742 ok(hConOutWT
!= INVALID_HANDLE_VALUE
,
743 "Cannot create a new screen buffer for WriteOnly\n");
745 hFileOutRW
= CreateFileA("NUL", GENERIC_READ
| GENERIC_WRITE
,
746 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
747 OPEN_EXISTING
, 0, NULL
);
748 ok(hFileOutRW
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadWrite\n");
749 hFileOutRO
= CreateFileA("NUL", GENERIC_READ
, FILE_SHARE_READ
,
750 NULL
, OPEN_EXISTING
, 0, NULL
);
751 ok(hFileOutRO
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadOnly\n");
752 hFileOutWT
= CreateFileA("NUL", GENERIC_WRITE
, FILE_SHARE_WRITE
,
753 NULL
, OPEN_EXISTING
, 0, NULL
);
754 ok(hFileOutWT
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for WriteOnly\n");
756 /* Trying to set invalid handle */
758 ok(!SetConsoleActiveScreenBuffer(INVALID_HANDLE_VALUE
),
759 "Shouldn't succeed\n");
760 ok(GetLastError() == ERROR_INVALID_HANDLE
,
761 "GetLastError: expecting %u got %u\n",
762 ERROR_INVALID_HANDLE
, GetLastError());
764 /* Trying to set non-console handles */
766 ok(!SetConsoleActiveScreenBuffer(hFileOutRW
), "Shouldn't succeed\n");
767 ok(GetLastError() == ERROR_INVALID_HANDLE
,
768 "GetLastError: expecting %u got %u\n",
769 ERROR_INVALID_HANDLE
, GetLastError());
772 ok(!SetConsoleActiveScreenBuffer(hFileOutRO
), "Shouldn't succeed\n");
773 ok(GetLastError() == ERROR_INVALID_HANDLE
,
774 "GetLastError: expecting %u got %u\n",
775 ERROR_INVALID_HANDLE
, GetLastError());
778 ok(!SetConsoleActiveScreenBuffer(hFileOutWT
), "Shouldn't succeed\n");
779 ok(GetLastError() == ERROR_INVALID_HANDLE
,
780 "GetLastError: expecting %u got %u\n",
781 ERROR_INVALID_HANDLE
, GetLastError());
783 /* trying to write non-console handle */
784 SetLastError(0xdeadbeef);
785 ret
= WriteConsoleA(hFileOutRW
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
786 error
= GetLastError();
787 ok(!ret
, "Shouldn't succeed\n");
788 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
789 "GetLastError: got %u\n", error
);
791 SetLastError(0xdeadbeef);
792 ret
= WriteConsoleA(hFileOutRO
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
793 error
= GetLastError();
794 ok(!ret
, "Shouldn't succeed\n");
795 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
796 "GetLastError: got %u\n", error
);
798 SetLastError(0xdeadbeef);
799 ret
= WriteConsoleA(hFileOutWT
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
800 error
= GetLastError();
801 ok(!ret
, "Shouldn't succeed\n");
802 todo_wine
ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
803 "GetLastError: got %u\n", error
);
805 CloseHandle(hFileOutRW
);
806 CloseHandle(hFileOutRO
);
807 CloseHandle(hFileOutWT
);
809 /* Trying to set SB handles with various access modes */
811 ok(!SetConsoleActiveScreenBuffer(hConOutRO
), "Shouldn't succeed\n");
812 ok(GetLastError() == ERROR_INVALID_HANDLE
,
813 "GetLastError: expecting %u got %u\n",
814 ERROR_INVALID_HANDLE
, GetLastError());
816 ok(SetConsoleActiveScreenBuffer(hConOutWT
), "Couldn't set new WriteOnly SB\n");
818 ok(SetConsoleActiveScreenBuffer(hConOutRW
), "Couldn't set new ReadWrite SB\n");
820 CloseHandle(hConOutWT
);
821 CloseHandle(hConOutRO
);
823 /* Now we have two ReadWrite SB, active must be hConOutRW */
824 /* Open current SB via CONOUT$ */
825 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
826 NULL
, OPEN_EXISTING
, 0, 0);
827 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
832 SetConsoleCursorPosition(hConOut
, c
);
834 SetConsoleCursorPosition(hConOutRW
, c
);
835 okCURSOR(hConOutNew
, c
);
837 okCURSOR(hConOut
, c
);
842 /* Write using hConOutNew... */
843 SetConsoleCursorPosition(hConOutNew
, c
);
844 ret
= WriteConsoleA(hConOutNew
, test_str2
, lstrlenA(test_str2
), &len
, NULL
);
845 ok (ret
&& len
== lstrlenA(test_str2
), "WriteConsoleA failed\n");
846 /* ... and read it back via hConOutRW */
847 ret
= ReadConsoleOutputCharacterA(hConOutRW
, str_buf
, lstrlenA(test_str2
), c
, &len
);
848 ok(ret
&& len
== lstrlenA(test_str2
), "ReadConsoleOutputCharacterA failed\n");
849 str_buf
[lstrlenA(test_str2
)] = 0;
850 ok(!lstrcmpA(str_buf
, test_str2
), "got '%s' expected '%s'\n", str_buf
, test_str2
);
853 /* Now test output codepage handling. Current is 866 as we set earlier. */
854 SetConsoleCursorPosition(hConOutRW
, c
);
855 ret
= WriteConsoleA(hConOutRW
, test_cp866
, lstrlenA(test_cp866
), &len
, NULL
);
856 ok(ret
&& len
== lstrlenA(test_cp866
), "WriteConsoleA failed\n");
857 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp866
), c
, &len
);
858 ok(ret
&& len
== lstrlenA(test_cp866
), "ReadConsoleOutputCharacterW failed\n");
859 str_wbuf
[lstrlenA(test_cp866
)] = 0;
860 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
863 * cp866 is OK, let's switch to cp1251.
864 * We expect that this codepage will be used in every SB - active and not.
866 ok(SetConsoleOutputCP(1251), "Cannot set output cp to 1251\n");
867 SetConsoleCursorPosition(hConOutRW
, c
);
868 ret
= WriteConsoleA(hConOutRW
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
869 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
870 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
871 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
872 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
873 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
875 /* Check what has happened to hConOut. */
876 SetConsoleCursorPosition(hConOut
, c
);
877 ret
= WriteConsoleA(hConOut
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
878 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
879 ret
= ReadConsoleOutputCharacterW(hConOut
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
880 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
881 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
882 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
884 /* Close all handles of current console SB */
885 CloseHandle(hConOutNew
);
886 CloseHandle(hConOutRW
);
888 /* Now active SB should be hConOut */
889 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
890 NULL
, OPEN_EXISTING
, 0, 0);
891 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
893 /* Write using hConOutNew... */
894 SetConsoleCursorPosition(hConOutNew
, c
);
895 ret
= WriteConsoleA(hConOutNew
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
896 ok (ret
&& len
== lstrlenA(test_str1
), "WriteConsoleA failed\n");
897 /* ... and read it back via hConOut */
898 ret
= ReadConsoleOutputCharacterA(hConOut
, str_buf
, lstrlenA(test_str1
), c
, &len
);
899 ok(ret
&& len
== lstrlenA(test_str1
), "ReadConsoleOutputCharacterA failed\n");
900 str_buf
[lstrlenA(test_str1
)] = 0;
901 todo_wine
ok(!lstrcmpA(str_buf
, test_str1
), "got '%s' expected '%s'\n", str_buf
, test_str1
);
902 CloseHandle(hConOutNew
);
904 /* This is not really needed under Windows */
905 SetConsoleActiveScreenBuffer(hConOut
);
907 /* restore codepage */
908 SetConsoleOutputCP(oldcp
);
911 static void test_GetSetConsoleInputExeName(void)
915 char buffer
[MAX_PATH
], module
[MAX_PATH
], *p
;
916 static char input_exe
[MAX_PATH
] = "winetest.exe";
918 SetLastError(0xdeadbeef);
919 ret
= pGetConsoleInputExeNameA(0, NULL
);
920 error
= GetLastError();
921 ok(ret
, "GetConsoleInputExeNameA failed\n");
922 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
924 SetLastError(0xdeadbeef);
925 ret
= pGetConsoleInputExeNameA(0, buffer
);
926 error
= GetLastError();
927 ok(ret
, "GetConsoleInputExeNameA failed\n");
928 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
930 GetModuleFileNameA(GetModuleHandleA(NULL
), module
, sizeof(module
));
931 p
= strrchr(module
, '\\') + 1;
933 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
934 ok(ret
, "GetConsoleInputExeNameA failed\n");
935 todo_wine
ok(!lstrcmpA(buffer
, p
), "got %s expected %s\n", buffer
, p
);
937 SetLastError(0xdeadbeef);
938 ret
= pSetConsoleInputExeNameA(NULL
);
939 error
= GetLastError();
940 ok(!ret
, "SetConsoleInputExeNameA failed\n");
941 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
943 SetLastError(0xdeadbeef);
944 ret
= pSetConsoleInputExeNameA("");
945 error
= GetLastError();
946 ok(!ret
, "SetConsoleInputExeNameA failed\n");
947 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
949 ret
= pSetConsoleInputExeNameA(input_exe
);
950 ok(ret
, "SetConsoleInputExeNameA failed\n");
952 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
953 ok(ret
, "GetConsoleInputExeNameA failed\n");
954 ok(!lstrcmpA(buffer
, input_exe
), "got %s expected %s\n", buffer
, input_exe
);
957 static void test_GetConsoleProcessList(void)
959 DWORD ret
, *list
= NULL
;
961 if (!pGetConsoleProcessList
)
963 win_skip("GetConsoleProcessList is not available\n");
967 SetLastError(0xdeadbeef);
968 ret
= pGetConsoleProcessList(NULL
, 0);
969 ok(ret
== 0, "Expected failure\n");
970 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
971 "Expected ERROR_INVALID_PARAMETER, got %d\n",
974 SetLastError(0xdeadbeef);
975 ret
= pGetConsoleProcessList(NULL
, 1);
976 ok(ret
== 0, "Expected failure\n");
977 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
978 "Expected ERROR_INVALID_PARAMETER, got %d\n",
981 /* We should only have 1 process but only for these specific unit tests as
982 * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) would
983 * give us two processes for example.
985 list
= HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD
));
987 SetLastError(0xdeadbeef);
988 ret
= pGetConsoleProcessList(list
, 0);
989 ok(ret
== 0, "Expected failure\n");
990 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
991 "Expected ERROR_INVALID_PARAMETER, got %d\n",
994 SetLastError(0xdeadbeef);
995 ret
= pGetConsoleProcessList(list
, 1);
997 ok(ret
== 1, "Expected 1, got %d\n", ret
);
999 HeapFree(GetProcessHeap(), 0, list
);
1001 list
= HeapAlloc(GetProcessHeap(), 0, ret
* sizeof(DWORD
));
1003 SetLastError(0xdeadbeef);
1004 ret
= pGetConsoleProcessList(list
, ret
);
1006 ok(ret
== 1, "Expected 1, got %d\n", ret
);
1010 DWORD pid
= GetCurrentProcessId();
1011 ok(list
[0] == pid
, "Expected %d, got %d\n", pid
, list
[0]);
1014 HeapFree(GetProcessHeap(), 0, list
);
1017 static void test_OpenCON(void)
1019 static const WCHAR conW
[] = {'C','O','N',0};
1020 static const DWORD accesses
[] = {CREATE_NEW
, CREATE_ALWAYS
, OPEN_EXISTING
,
1021 OPEN_ALWAYS
, TRUNCATE_EXISTING
};
1025 for (i
= 0; i
< sizeof(accesses
) / sizeof(accesses
[0]); i
++)
1027 h
= CreateFileW(conW
, GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1028 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win8 */),
1029 "Expected to open the CON device on write (%x)\n", accesses
[i
]);
1032 h
= CreateFileW(conW
, GENERIC_READ
, 0, NULL
, accesses
[i
], 0, NULL
);
1033 /* Windows versions differ here:
1034 * MSDN states in CreateFile that TRUNCATE_EXISTING requires GENERIC_WRITE
1035 * NT, XP, Vista comply, but Win7 doesn't and allows opening CON with TRUNCATE_EXISTING
1036 * So don't test when disposition is TRUNCATE_EXISTING
1038 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win7+ */),
1039 "Expected to open the CON device on read (%x)\n", accesses
[i
]);
1041 h
= CreateFileW(conW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1042 ok(h
== INVALID_HANDLE_VALUE
, "Expected not to open the CON device on read-write (%x)\n", accesses
[i
]);
1043 ok(GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1044 "Unexpected error %x\n", GetLastError());
1048 static void test_OpenConsoleW(void)
1050 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1051 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1052 static const WCHAR emptyW
[] = {0};
1053 static const WCHAR invalidW
[] = {'I','N','V','A','L','I','D',0};
1063 } invalid_table
[] = {
1064 {NULL
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1065 {NULL
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1066 {NULL
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1067 {NULL
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1068 {NULL
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1069 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1070 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1071 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1072 {emptyW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1073 {emptyW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1074 {emptyW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1075 {emptyW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1076 {emptyW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1077 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1078 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1079 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1080 {invalidW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1081 {invalidW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1082 {invalidW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1083 {invalidW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1084 {invalidW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1085 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1086 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1087 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1088 {coninW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1089 {coninW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1090 {coninW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1091 {conoutW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1092 {conoutW
, 0xceadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1093 {conoutW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1102 {coninW
, 0, FALSE
, 0 },
1103 {coninW
, 0, TRUE
, 0 },
1104 {coninW
, GENERIC_EXECUTE
, TRUE
, 0 },
1105 {coninW
, GENERIC_ALL
, TRUE
, 0 },
1106 {coninW
, 0, FALSE
, OPEN_ALWAYS
},
1107 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1108 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
},
1109 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1110 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1111 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1112 {conoutW
, 0, FALSE
, 0 },
1113 {conoutW
, 0, FALSE
, OPEN_ALWAYS
},
1114 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1115 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, },
1116 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1117 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1118 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1126 win_skip("OpenConsoleW is not available\n");
1130 for (index
= 0; index
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); index
++)
1132 SetLastError(0xdeadbeef);
1133 ret
= pOpenConsoleW(invalid_table
[index
].name
, invalid_table
[index
].access
,
1134 invalid_table
[index
].inherit
, invalid_table
[index
].creation
);
1135 gle
= GetLastError();
1136 ok(ret
== INVALID_HANDLE_VALUE
,
1137 "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
1139 ok(gle
== invalid_table
[index
].gle
|| (gle
!= 0 && gle
== invalid_table
[index
].gle2
),
1140 "Expected GetLastError() to return %u/%u for index %d, got %u\n",
1141 invalid_table
[index
].gle
, invalid_table
[index
].gle2
, index
, gle
);
1144 for (index
= 0; index
< sizeof(valid_table
)/sizeof(valid_table
[0]); index
++)
1146 ret
= pOpenConsoleW(valid_table
[index
].name
, valid_table
[index
].access
,
1147 valid_table
[index
].inherit
, valid_table
[index
].creation
);
1149 ok(ret
!= INVALID_HANDLE_VALUE
|| broken(ret
== INVALID_HANDLE_VALUE
/* until Win7 */),
1150 "Expected OpenConsoleW to succeed for index %d, got %p\n", index
, ret
);
1151 if (ret
!= INVALID_HANDLE_VALUE
)
1155 ret
= pOpenConsoleW(coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1156 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1157 if (ret
!= INVALID_HANDLE_VALUE
)
1160 ret
= pOpenConsoleW(conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1161 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1162 if (ret
!= INVALID_HANDLE_VALUE
)
1166 static void test_CreateFileW(void)
1168 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1169 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1180 {coninW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1181 {coninW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1182 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1183 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1184 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1185 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1186 {conoutW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1187 {conoutW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1188 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1189 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1190 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1191 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1192 /* TRUNCATE_EXISTING is forbidden starting with Windows 8 */
1197 SECURITY_ATTRIBUTES sa
;
1199 for (index
= 0; index
< sizeof(cf_table
)/sizeof(cf_table
[0]); index
++)
1201 SetLastError(0xdeadbeef);
1203 sa
.nLength
= sizeof(sa
);
1204 sa
.lpSecurityDescriptor
= NULL
;
1205 sa
.bInheritHandle
= cf_table
[index
].inherit
;
1207 ret
= CreateFileW(cf_table
[index
].name
, cf_table
[index
].access
,
1208 FILE_SHARE_READ
|FILE_SHARE_WRITE
, &sa
,
1209 cf_table
[index
].creation
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1210 if (ret
== INVALID_HANDLE_VALUE
)
1212 ok(cf_table
[index
].gle
,
1213 "Expected CreateFileW not to return INVALID_HANDLE_VALUE for index %d\n", index
);
1214 ok(GetLastError() == cf_table
[index
].gle
,
1215 "Expected GetLastError() to return %u for index %d, got %u\n",
1216 cf_table
[index
].gle
, index
, GetLastError());
1220 ok(!cf_table
[index
].gle
|| broken(cf_table
[index
].is_broken
) /* Win7 */,
1221 "Expected CreateFileW to succeed for index %d\n", index
);
1227 static void test_VerifyConsoleIoHandle( HANDLE handle
)
1232 if (!pVerifyConsoleIoHandle
)
1234 win_skip("VerifyConsoleIoHandle is not available\n");
1238 /* invalid handle */
1239 SetLastError(0xdeadbeef);
1240 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee0);
1241 error
= GetLastError();
1242 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1243 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1245 /* invalid handle + 1 */
1246 SetLastError(0xdeadbeef);
1247 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee1);
1248 error
= GetLastError();
1249 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1250 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1252 /* invalid handle + 2 */
1253 SetLastError(0xdeadbeef);
1254 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee2);
1255 error
= GetLastError();
1256 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1257 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1259 /* invalid handle + 3 */
1260 SetLastError(0xdeadbeef);
1261 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee3);
1262 error
= GetLastError();
1263 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1264 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1267 SetLastError(0xdeadbeef);
1268 ret
= pVerifyConsoleIoHandle(handle
);
1269 error
= GetLastError();
1270 ok(ret
, "expected VerifyConsoleIoHandle to succeed\n");
1271 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1274 static void test_GetSetStdHandle(void)
1280 /* get invalid std handle */
1281 SetLastError(0xdeadbeef);
1282 handle
= GetStdHandle(42);
1283 error
= GetLastError();
1284 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1285 "wrong GetLastError() %d\n", error
);
1286 ok(handle
== INVALID_HANDLE_VALUE
, "expected INVALID_HANDLE_VALUE\n");
1289 SetLastError(0xdeadbeef);
1290 handle
= GetStdHandle(STD_INPUT_HANDLE
);
1291 error
= GetLastError();
1292 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1294 /* set invalid std handle */
1295 SetLastError(0xdeadbeef);
1296 ret
= SetStdHandle(42, handle
);
1297 error
= GetLastError();
1298 ok(!ret
, "expected SetStdHandle to fail\n");
1299 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1300 "wrong GetLastError() %d\n", error
);
1302 /* set valid (restore old value) */
1303 SetLastError(0xdeadbeef);
1304 ret
= SetStdHandle(STD_INPUT_HANDLE
, handle
);
1305 error
= GetLastError();
1306 ok(ret
, "expected SetStdHandle to succeed\n");
1307 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1310 static void test_GetNumberOfConsoleInputEvents(HANDLE input_handle
)
1323 {NULL
, NULL
, ERROR_INVALID_HANDLE
},
1324 {NULL
, &count
, ERROR_INVALID_HANDLE
},
1325 {INVALID_HANDLE_VALUE
, NULL
, ERROR_INVALID_HANDLE
},
1326 {INVALID_HANDLE_VALUE
, &count
, ERROR_INVALID_HANDLE
},
1329 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1331 SetLastError(0xdeadbeef);
1332 if (invalid_table
[i
].nrofevents
) count
= 0xdeadbeef;
1333 ret
= GetNumberOfConsoleInputEvents(invalid_table
[i
].handle
,
1334 invalid_table
[i
].nrofevents
);
1335 ok(!ret
, "[%d] Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", i
, ret
);
1336 if (invalid_table
[i
].nrofevents
)
1338 ok(count
== 0xdeadbeef,
1339 "[%d] Expected output count to be unmodified, got %u\n", i
, count
);
1341 ok(GetLastError() == invalid_table
[i
].last_error
,
1342 "[%d] Expected last error to be %u, got %u\n",
1343 i
, invalid_table
[i
].last_error
, GetLastError());
1346 /* Test crashes on Windows 7. */
1349 SetLastError(0xdeadbeef);
1350 ret
= GetNumberOfConsoleInputEvents(input_handle
, NULL
);
1351 ok(!ret
, "Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", ret
);
1352 ok(GetLastError() == ERROR_INVALID_ACCESS
,
1353 "Expected last error to be ERROR_INVALID_ACCESS, got %u\n",
1358 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1359 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1360 ok(count
!= 0xdeadbeef, "Expected output count to initialized\n");
1363 static void test_WriteConsoleInputA(HANDLE input_handle
)
1366 INPUT_RECORD event_list
[5];
1367 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1368 KEY_EVENT_RECORD key_event
;
1369 DWORD count
, console_mode
, gle
;
1376 const INPUT_RECORD
*buffer
;
1379 DWORD expected_count
;
1384 {NULL
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1385 {NULL
, NULL
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1386 {NULL
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1387 {NULL
, NULL
, 1, &count
, 0xdeadbeef, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1388 {NULL
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1389 {NULL
, &event
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1390 {NULL
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1391 {NULL
, &event
, 1, &count
, 0, ERROR_INVALID_HANDLE
},
1392 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1393 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1394 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1395 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, 0xdeadbeef, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1396 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1397 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1398 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1399 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, 0, ERROR_INVALID_HANDLE
},
1400 {input_handle
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1401 {input_handle
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1402 {input_handle
, NULL
, 1, &count
, 0xdeadbeef, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1403 {input_handle
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1404 {input_handle
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1407 /* Suppress external sources of input events for the duration of the test. */
1408 ret
= GetConsoleMode(input_handle
, &console_mode
);
1409 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1412 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1416 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1417 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1420 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1424 /* Discard any events queued before the tests. */
1425 ret
= FlushConsoleInputBuffer(input_handle
);
1426 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1428 event
.EventType
= MOUSE_EVENT
;
1429 event
.Event
.MouseEvent
= mouse_event
;
1431 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1433 if (invalid_table
[i
].win_crash
)
1436 SetLastError(0xdeadbeef);
1437 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1438 ret
= WriteConsoleInputA(invalid_table
[i
].handle
,
1439 invalid_table
[i
].buffer
,
1440 invalid_table
[i
].count
,
1441 invalid_table
[i
].written
);
1442 ok(!ret
, "[%d] Expected WriteConsoleInputA to return FALSE, got %d\n", i
, ret
);
1443 if (invalid_table
[i
].written
)
1445 ok(count
== invalid_table
[i
].expected_count
,
1446 "[%d] Expected output count to be %u, got %u\n",
1447 i
, invalid_table
[i
].expected_count
, count
);
1449 gle
= GetLastError();
1450 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1451 "[%d] Expected last error to be %u or %u, got %u\n",
1452 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1456 ret
= WriteConsoleInputA(input_handle
, NULL
, 0, &count
);
1457 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1458 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1461 ret
= WriteConsoleInputA(input_handle
, &event
, 0, &count
);
1462 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1463 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1466 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1467 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1468 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1470 ret
= FlushConsoleInputBuffer(input_handle
);
1471 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1473 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1474 event
.EventType
= MOUSE_EVENT
;
1475 event
.Event
.MouseEvent
= mouse_event
;
1477 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1478 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1479 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1481 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1482 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1483 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1485 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1486 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1487 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1489 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1490 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1492 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1494 ret
= FlushConsoleInputBuffer(input_handle
);
1495 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1497 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1499 event_list
[i
].EventType
= MOUSE_EVENT
;
1500 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1503 /* Writing consecutive chunks of mouse events appears to work. */
1504 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1505 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1506 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1507 "Expected count to be event list length, got %u\n", count
);
1509 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1510 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1511 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1512 "Expected count to be event list length, got %u\n", count
);
1514 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1515 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1516 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1517 "Expected count to be event list length, got %u\n", count
);
1519 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1520 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1521 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1522 "Expected count to be twice event list length, got %u\n", count
);
1524 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1525 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1526 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1527 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1529 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1530 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1532 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1533 "Expected count to be twice event list length, got %u\n", count
);
1535 ret
= FlushConsoleInputBuffer(input_handle
);
1536 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1538 key_event
.bKeyDown
= FALSE
;
1539 key_event
.wRepeatCount
= 0;
1540 key_event
.wVirtualKeyCode
= VK_SPACE
;
1541 key_event
.wVirtualScanCode
= VK_SPACE
;
1542 key_event
.uChar
.AsciiChar
= ' ';
1543 key_event
.dwControlKeyState
= 0;
1545 event
.EventType
= KEY_EVENT
;
1546 event
.Event
.KeyEvent
= key_event
;
1548 /* Key events don't exhibit the same behavior as mouse events. */
1549 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1550 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1551 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1553 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1554 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1555 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1557 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1558 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1559 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1561 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1562 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1563 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1565 ret
= FlushConsoleInputBuffer(input_handle
);
1566 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1568 /* Try interleaving mouse and key events. */
1569 event
.EventType
= MOUSE_EVENT
;
1570 event
.Event
.MouseEvent
= mouse_event
;
1572 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1573 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1574 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1576 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1577 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1578 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1580 event
.EventType
= KEY_EVENT
;
1581 event
.Event
.KeyEvent
= key_event
;
1583 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1584 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1585 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1587 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1588 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1589 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1591 event
.EventType
= MOUSE_EVENT
;
1592 event
.Event
.MouseEvent
= mouse_event
;
1594 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1595 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1596 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1598 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1599 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1600 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1602 /* Restore the old console mode. */
1603 ret
= SetConsoleMode(input_handle
, console_mode
);
1604 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1607 static void test_WriteConsoleInputW(HANDLE input_handle
)
1610 INPUT_RECORD event_list
[5];
1611 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1612 KEY_EVENT_RECORD key_event
;
1613 DWORD count
, console_mode
, gle
;
1620 const INPUT_RECORD
*buffer
;
1623 DWORD expected_count
;
1628 {NULL
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1629 {NULL
, NULL
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1630 {NULL
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1631 {NULL
, NULL
, 1, &count
, 0xdeadbeef, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1632 {NULL
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1633 {NULL
, &event
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1634 {NULL
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1635 {NULL
, &event
, 1, &count
, 0, ERROR_INVALID_HANDLE
},
1636 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1637 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1638 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1639 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, 0xdeadbeef, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1640 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1641 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, 0, ERROR_INVALID_HANDLE
},
1642 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1643 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, 0, ERROR_INVALID_HANDLE
},
1644 {input_handle
, NULL
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1645 {input_handle
, NULL
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1646 {input_handle
, NULL
, 1, &count
, 0xdeadbeef, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1647 {input_handle
, &event
, 0, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1648 {input_handle
, &event
, 1, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 0, 1},
1651 /* Suppress external sources of input events for the duration of the test. */
1652 ret
= GetConsoleMode(input_handle
, &console_mode
);
1653 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1656 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1660 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1661 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1664 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1668 /* Discard any events queued before the tests. */
1669 ret
= FlushConsoleInputBuffer(input_handle
);
1670 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1672 event
.EventType
= MOUSE_EVENT
;
1673 event
.Event
.MouseEvent
= mouse_event
;
1675 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1677 if (invalid_table
[i
].win_crash
)
1680 SetLastError(0xdeadbeef);
1681 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1682 ret
= WriteConsoleInputW(invalid_table
[i
].handle
,
1683 invalid_table
[i
].buffer
,
1684 invalid_table
[i
].count
,
1685 invalid_table
[i
].written
);
1686 ok(!ret
, "[%d] Expected WriteConsoleInputW to return FALSE, got %d\n", i
, ret
);
1687 if (invalid_table
[i
].written
)
1689 ok(count
== invalid_table
[i
].expected_count
,
1690 "[%d] Expected output count to be %u, got %u\n",
1691 i
, invalid_table
[i
].expected_count
, count
);
1693 gle
= GetLastError();
1694 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1695 "[%d] Expected last error to be %u or %u, got %u\n",
1696 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1700 ret
= WriteConsoleInputW(input_handle
, NULL
, 0, &count
);
1701 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1702 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1705 ret
= WriteConsoleInputW(input_handle
, &event
, 0, &count
);
1706 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1707 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1710 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1711 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1712 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1714 ret
= FlushConsoleInputBuffer(input_handle
);
1715 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1717 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1718 event
.EventType
= MOUSE_EVENT
;
1719 event
.Event
.MouseEvent
= mouse_event
;
1721 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1722 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1723 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1725 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1726 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1727 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1729 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1730 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1731 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1733 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1734 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1736 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1738 ret
= FlushConsoleInputBuffer(input_handle
);
1739 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1741 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1743 event_list
[i
].EventType
= MOUSE_EVENT
;
1744 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1747 /* Writing consecutive chunks of mouse events appears to work. */
1748 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1749 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1750 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1751 "Expected count to be event list length, got %u\n", count
);
1753 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1754 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1755 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1756 "Expected count to be event list length, got %u\n", count
);
1758 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1759 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1760 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1761 "Expected count to be event list length, got %u\n", count
);
1763 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1764 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1765 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1766 "Expected count to be twice event list length, got %u\n", count
);
1768 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1769 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1770 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1771 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1773 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1774 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1776 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1777 "Expected count to be twice event list length, got %u\n", count
);
1779 ret
= FlushConsoleInputBuffer(input_handle
);
1780 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1782 key_event
.bKeyDown
= FALSE
;
1783 key_event
.wRepeatCount
= 0;
1784 key_event
.wVirtualKeyCode
= VK_SPACE
;
1785 key_event
.wVirtualScanCode
= VK_SPACE
;
1786 key_event
.uChar
.UnicodeChar
= ' ';
1787 key_event
.dwControlKeyState
= 0;
1789 event
.EventType
= KEY_EVENT
;
1790 event
.Event
.KeyEvent
= key_event
;
1792 /* Key events don't exhibit the same behavior as mouse events. */
1793 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1794 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1795 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1797 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1798 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1799 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1801 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1802 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1803 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1805 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1806 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1807 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1809 ret
= FlushConsoleInputBuffer(input_handle
);
1810 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1812 /* Try interleaving mouse and key events. */
1813 event
.EventType
= MOUSE_EVENT
;
1814 event
.Event
.MouseEvent
= mouse_event
;
1816 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1817 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1818 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1820 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1821 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1822 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1824 event
.EventType
= KEY_EVENT
;
1825 event
.Event
.KeyEvent
= key_event
;
1827 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1828 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1829 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1831 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1832 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1833 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1835 event
.EventType
= MOUSE_EVENT
;
1836 event
.Event
.MouseEvent
= mouse_event
;
1838 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1839 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1840 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1842 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1843 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1844 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1846 /* Restore the old console mode. */
1847 ret
= SetConsoleMode(input_handle
, console_mode
);
1848 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1851 static void test_WriteConsoleOutputCharacterA(HANDLE output_handle
)
1853 static const char output
[] = {'a', 0};
1855 COORD origin
= {0, 0};
1862 HANDLE hConsoleOutput
;
1866 LPDWORD lpNumCharsWritten
;
1867 DWORD expected_count
;
1872 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1873 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1874 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1875 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1876 {NULL
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1877 {NULL
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1878 {NULL
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1879 {NULL
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1880 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1881 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1882 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1883 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1884 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1885 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1886 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1887 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1888 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1889 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1890 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1891 {output_handle
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1892 {output_handle
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1895 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1897 if (invalid_table
[i
].win7_crash
)
1900 SetLastError(0xdeadbeef);
1901 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
1902 ret
= WriteConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
1903 invalid_table
[i
].str
,
1904 invalid_table
[i
].length
,
1905 invalid_table
[i
].coord
,
1906 invalid_table
[i
].lpNumCharsWritten
);
1907 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
1908 if (invalid_table
[i
].lpNumCharsWritten
)
1910 ok(count
== invalid_table
[i
].expected_count
,
1911 "[%d] Expected count to be %u, got %u\n",
1912 i
, invalid_table
[i
].expected_count
, count
);
1914 ok(GetLastError() == invalid_table
[i
].last_error
,
1915 "[%d] Expected last error to be %u, got %u\n",
1916 i
, invalid_table
[i
].last_error
, GetLastError());
1920 ret
= WriteConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
1921 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1922 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1925 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 0, origin
, &count
);
1926 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1927 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1930 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 1, origin
, &count
);
1931 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1932 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1935 static void test_WriteConsoleOutputCharacterW(HANDLE output_handle
)
1937 static const WCHAR outputW
[] = {'a',0};
1939 COORD origin
= {0, 0};
1946 HANDLE hConsoleOutput
;
1950 LPDWORD lpNumCharsWritten
;
1951 DWORD expected_count
;
1956 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1957 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1958 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1959 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1960 {NULL
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1961 {NULL
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1962 {NULL
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1963 {NULL
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1964 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1965 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1966 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1967 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1968 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1969 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1970 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1971 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1972 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1973 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1974 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1975 {output_handle
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1976 {output_handle
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1979 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1981 if (invalid_table
[i
].win7_crash
)
1984 SetLastError(0xdeadbeef);
1985 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
1986 ret
= WriteConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
1987 invalid_table
[i
].str
,
1988 invalid_table
[i
].length
,
1989 invalid_table
[i
].coord
,
1990 invalid_table
[i
].lpNumCharsWritten
);
1991 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
1992 if (invalid_table
[i
].lpNumCharsWritten
)
1994 ok(count
== invalid_table
[i
].expected_count
,
1995 "[%d] Expected count to be %u, got %u\n",
1996 i
, invalid_table
[i
].expected_count
, count
);
1998 ok(GetLastError() == invalid_table
[i
].last_error
,
1999 "[%d] Expected last error to be %u, got %u\n",
2000 i
, invalid_table
[i
].last_error
, GetLastError());
2004 ret
= WriteConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2005 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2006 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2009 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 0, origin
, &count
);
2010 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2011 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2014 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 1, origin
, &count
);
2015 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2016 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2019 static void test_WriteConsoleOutputAttribute(HANDLE output_handle
)
2021 WORD attr
= FOREGROUND_BLUE
;
2022 COORD origin
= {0, 0};
2029 HANDLE hConsoleOutput
;
2033 LPDWORD lpNumAttrsWritten
;
2034 DWORD expected_count
;
2039 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2040 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2041 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2042 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2043 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2044 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2045 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2046 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2047 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2048 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2049 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2050 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2051 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2052 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2053 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2054 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2055 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2056 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2057 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2058 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2059 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2062 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2064 if (invalid_table
[i
].win7_crash
)
2067 SetLastError(0xdeadbeef);
2068 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2069 ret
= WriteConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2070 invalid_table
[i
].attr
,
2071 invalid_table
[i
].length
,
2072 invalid_table
[i
].coord
,
2073 invalid_table
[i
].lpNumAttrsWritten
);
2074 ok(!ret
, "[%d] Expected WriteConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2075 if (invalid_table
[i
].lpNumAttrsWritten
)
2077 ok(count
== invalid_table
[i
].expected_count
,
2078 "[%d] Expected count to be %u, got %u\n",
2079 i
, invalid_table
[i
].expected_count
, count
);
2081 ok(GetLastError() == invalid_table
[i
].last_error
,
2082 "[%d] Expected last error to be %u, got %u\n",
2083 i
, invalid_table
[i
].last_error
, GetLastError());
2087 ret
= WriteConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2088 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2089 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2092 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2093 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2094 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2097 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2098 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2099 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2102 static void test_FillConsoleOutputCharacterA(HANDLE output_handle
)
2104 COORD origin
= {0, 0};
2111 HANDLE hConsoleOutput
;
2115 LPDWORD lpNumCharsWritten
;
2116 DWORD expected_count
;
2121 {NULL
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2122 {NULL
, 'a', 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2123 {NULL
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2124 {NULL
, 'a', 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2125 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2126 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2127 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2128 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2129 {output_handle
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2130 {output_handle
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2133 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2135 if (invalid_table
[i
].win7_crash
)
2138 SetLastError(0xdeadbeef);
2139 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2140 ret
= FillConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2141 invalid_table
[i
].ch
,
2142 invalid_table
[i
].length
,
2143 invalid_table
[i
].coord
,
2144 invalid_table
[i
].lpNumCharsWritten
);
2145 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2146 if (invalid_table
[i
].lpNumCharsWritten
)
2148 ok(count
== invalid_table
[i
].expected_count
,
2149 "[%d] Expected count to be %u, got %u\n",
2150 i
, invalid_table
[i
].expected_count
, count
);
2152 ok(GetLastError() == invalid_table
[i
].last_error
,
2153 "[%d] Expected last error to be %u, got %u\n",
2154 i
, invalid_table
[i
].last_error
, GetLastError());
2158 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 0, origin
, &count
);
2159 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2160 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2163 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 1, origin
, &count
);
2164 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2165 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2168 static void test_FillConsoleOutputCharacterW(HANDLE output_handle
)
2170 COORD origin
= {0, 0};
2177 HANDLE hConsoleOutput
;
2181 LPDWORD lpNumCharsWritten
;
2182 DWORD expected_count
;
2187 {NULL
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2188 {NULL
, 'a', 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2189 {NULL
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2190 {NULL
, 'a', 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2191 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2192 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2193 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2194 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2195 {output_handle
, 'a', 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2196 {output_handle
, 'a', 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2199 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2201 if (invalid_table
[i
].win7_crash
)
2204 SetLastError(0xdeadbeef);
2205 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2206 ret
= FillConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2207 invalid_table
[i
].ch
,
2208 invalid_table
[i
].length
,
2209 invalid_table
[i
].coord
,
2210 invalid_table
[i
].lpNumCharsWritten
);
2211 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2212 if (invalid_table
[i
].lpNumCharsWritten
)
2214 ok(count
== invalid_table
[i
].expected_count
,
2215 "[%d] Expected count to be %u, got %u\n",
2216 i
, invalid_table
[i
].expected_count
, count
);
2218 ok(GetLastError() == invalid_table
[i
].last_error
,
2219 "[%d] Expected last error to be %u, got %u\n",
2220 i
, invalid_table
[i
].last_error
, GetLastError());
2224 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 0, origin
, &count
);
2225 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2226 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2229 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 1, origin
, &count
);
2230 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2231 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2234 static void test_FillConsoleOutputAttribute(HANDLE output_handle
)
2236 COORD origin
= {0, 0};
2243 HANDLE hConsoleOutput
;
2247 LPDWORD lpNumAttrsWritten
;
2248 DWORD expected_count
;
2253 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2254 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2255 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2256 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2257 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2258 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2259 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2260 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2261 {output_handle
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2262 {output_handle
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2265 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2267 if (invalid_table
[i
].win7_crash
)
2270 SetLastError(0xdeadbeef);
2271 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2272 ret
= FillConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2273 invalid_table
[i
].attr
,
2274 invalid_table
[i
].length
,
2275 invalid_table
[i
].coord
,
2276 invalid_table
[i
].lpNumAttrsWritten
);
2277 ok(!ret
, "[%d] Expected FillConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2278 if (invalid_table
[i
].lpNumAttrsWritten
)
2280 ok(count
== invalid_table
[i
].expected_count
,
2281 "[%d] Expected count to be %u, got %u\n",
2282 i
, invalid_table
[i
].expected_count
, count
);
2284 ok(GetLastError() == invalid_table
[i
].last_error
,
2285 "[%d] Expected last error to be %u, got %u\n",
2286 i
, invalid_table
[i
].last_error
, GetLastError());
2290 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 0, origin
, &count
);
2291 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2292 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2295 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 1, origin
, &count
);
2296 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2297 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2300 ret
= FillConsoleOutputAttribute(output_handle
, ~0, 1, origin
, &count
);
2301 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2302 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2305 static void test_ReadConsoleOutputCharacterA(HANDLE output_handle
)
2308 COORD origin
= {0, 0};
2315 HANDLE hConsoleOutput
;
2320 DWORD expected_count
;
2325 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2326 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2327 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2328 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2329 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2330 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2331 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2332 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2333 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2334 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2335 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2336 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2337 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2338 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2339 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2340 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2341 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2342 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2343 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2344 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2345 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2346 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2349 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2351 if (invalid_table
[i
].win7_crash
)
2354 SetLastError(0xdeadbeef);
2355 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2356 ret
= ReadConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2357 invalid_table
[i
].lpstr
,
2358 invalid_table
[i
].length
,
2359 invalid_table
[i
].coord
,
2360 invalid_table
[i
].read_count
);
2361 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2362 if (invalid_table
[i
].read_count
)
2364 ok(count
== invalid_table
[i
].expected_count
,
2365 "[%d] Expected count to be %u, got %u\n",
2366 i
, invalid_table
[i
].expected_count
, count
);
2368 ok(GetLastError() == invalid_table
[i
].last_error
,
2369 "[%d] Expected last error to be %u, got %u\n",
2370 i
, invalid_table
[i
].last_error
, GetLastError());
2374 ret
= ReadConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
2375 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2376 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2379 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 0, origin
, &count
);
2380 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2381 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2384 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 1, origin
, &count
);
2385 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2386 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2389 static void test_ReadConsoleOutputCharacterW(HANDLE output_handle
)
2392 COORD origin
= {0, 0};
2399 HANDLE hConsoleOutput
;
2404 DWORD expected_count
;
2409 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2410 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2411 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2412 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2413 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2414 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2415 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2416 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2417 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2418 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2419 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2420 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2421 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2422 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2423 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2424 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2425 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2426 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2427 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2428 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2429 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2430 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2433 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2435 if (invalid_table
[i
].win7_crash
)
2438 SetLastError(0xdeadbeef);
2439 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2440 ret
= ReadConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2441 invalid_table
[i
].buffer
,
2442 invalid_table
[i
].length
,
2443 invalid_table
[i
].coord
,
2444 invalid_table
[i
].read_count
);
2445 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2446 if (invalid_table
[i
].read_count
)
2448 ok(count
== invalid_table
[i
].expected_count
,
2449 "[%d] Expected count to be %u, got %u\n",
2450 i
, invalid_table
[i
].expected_count
, count
);
2452 ok(GetLastError() == invalid_table
[i
].last_error
,
2453 "[%d] Expected last error to be %u, got %u\n",
2454 i
, invalid_table
[i
].last_error
, GetLastError());
2458 ret
= ReadConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2459 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2460 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2463 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 0, origin
, &count
);
2464 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2465 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2468 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 1, origin
, &count
);
2469 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2470 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2473 static void test_ReadConsoleOutputAttribute(HANDLE output_handle
)
2476 COORD origin
= {0, 0};
2483 HANDLE hConsoleOutput
;
2488 DWORD expected_count
;
2493 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2494 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2495 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2496 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2497 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2498 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2499 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2500 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2501 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2502 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2503 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2504 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2505 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2506 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2507 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2508 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2509 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2510 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2511 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2512 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2513 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2516 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2518 if (invalid_table
[i
].win7_crash
)
2521 SetLastError(0xdeadbeef);
2522 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2523 ret
= ReadConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2524 invalid_table
[i
].lpAttribute
,
2525 invalid_table
[i
].length
,
2526 invalid_table
[i
].coord
,
2527 invalid_table
[i
].read_count
);
2528 ok(!ret
, "[%d] Expected ReadConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2529 if (invalid_table
[i
].read_count
)
2531 ok(count
== invalid_table
[i
].expected_count
,
2532 "[%d] Expected count to be %u, got %u\n",
2533 i
, invalid_table
[i
].expected_count
, count
);
2535 ok(GetLastError() == invalid_table
[i
].last_error
,
2536 "[%d] Expected last error to be %u, got %u\n",
2537 i
, invalid_table
[i
].last_error
, GetLastError());
2541 ret
= ReadConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2542 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2543 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2546 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2547 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2548 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2551 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2552 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2553 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2556 static void test_ReadConsole(void)
2562 std_input
= GetStdHandle(STD_INPUT_HANDLE
);
2564 SetLastError(0xdeadbeef);
2565 ret
= GetFileSize(std_input
, NULL
);
2566 ok(ret
== INVALID_FILE_SIZE
, "expected INVALID_FILE_SIZE, got %#x\n", ret
);
2567 ok(GetLastError() == ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
2570 SetLastError(0xdeadbeef);
2571 ret
= ReadFile(std_input
, buf
, -128, &bytes
, NULL
);
2572 ok(!ret
, "expected 0, got %u\n", ret
);
2573 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2574 ok(!bytes
, "expected 0, got %u\n", bytes
);
2577 SetLastError(0xdeadbeef);
2578 ret
= ReadConsoleA(std_input
, buf
, -128, &bytes
, NULL
);
2579 ok(!ret
, "expected 0, got %u\n", ret
);
2580 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2581 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2584 SetLastError(0xdeadbeef);
2585 ret
= ReadConsoleW(std_input
, buf
, -128, &bytes
, NULL
);
2586 ok(!ret
, "expected 0, got %u\n", ret
);
2587 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
, "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2588 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2593 static const char font_name
[] = "Lucida Console";
2594 HANDLE hConIn
, hConOut
;
2596 CONSOLE_SCREEN_BUFFER_INFO sbi
;
2599 char old_font
[LF_FACESIZE
];
2600 BOOL
delete = FALSE
;
2603 init_function_pointers();
2605 /* be sure we have a clean console (and that's our own)
2606 * FIXME: this will make the test fail (currently) if we don't run
2608 * Another solution would be to rerun the test under wineconsole with
2609 * the curses backend
2612 /* ReadConsoleOutputW doesn't retrieve characters from the output buffer
2613 * correctly for characters that don't have a glyph in the console font. So,
2614 * we first set the console font to Lucida Console (which has a wider
2615 * selection of glyphs available than the default raster fonts). We want
2616 * to be able to restore the original font afterwards, so don't change
2617 * if we can't read the original font.
2619 err
= RegOpenKeyExA(HKEY_CURRENT_USER
, "Console", 0,
2620 KEY_QUERY_VALUE
| KEY_SET_VALUE
, &console_key
);
2621 if (err
== ERROR_SUCCESS
)
2623 size
= sizeof(old_font
);
2624 err
= RegQueryValueExA(console_key
, "FaceName", NULL
, NULL
,
2625 (LPBYTE
) old_font
, &size
);
2626 if (err
== ERROR_SUCCESS
|| err
== ERROR_FILE_NOT_FOUND
)
2628 delete = (err
== ERROR_FILE_NOT_FOUND
);
2629 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
2630 (const BYTE
*) font_name
, sizeof(font_name
));
2631 if (err
!= ERROR_SUCCESS
)
2632 trace("Unable to change default console font, error %d\n", err
);
2636 trace("Unable to query default console font, error %d\n", err
);
2637 RegCloseKey(console_key
);
2643 trace("Unable to open HKCU\\Console, error %d\n", err
);
2647 /* Now detach and open a fresh console to play with */
2649 ok(AllocConsole(), "Couldn't alloc console\n");
2651 /* Restore default console font if needed */
2652 if (console_key
!= NULL
)
2655 err
= RegDeleteValueA(console_key
, "FaceName");
2657 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
2658 (const BYTE
*) old_font
, strlen(old_font
) + 1);
2659 ok(err
== ERROR_SUCCESS
, "Unable to restore default console font, error %d\n", err
);
2661 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2662 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
2664 /* now verify everything's ok */
2665 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
2666 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
2668 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
2669 ok(ret
, "Getting sb info\n");
2672 /* Reduce the size of the buffer to the visible area plus 3 lines to speed
2675 trace("Visible area: %dx%d - %dx%d Buffer size: %dx%d\n", sbi
.srWindow
.Left
, sbi
.srWindow
.Top
, sbi
.srWindow
.Right
, sbi
.srWindow
.Bottom
, sbi
.dwSize
.X
, sbi
.dwSize
.Y
);
2676 sbi
.dwSize
.Y
= size
= (sbi
.srWindow
.Bottom
+ 1) + 3;
2677 ret
= SetConsoleScreenBufferSize(hConOut
, sbi
.dwSize
);
2678 ok(ret
, "Setting sb info\n");
2679 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
2680 ok(ret
, "Getting sb info\n");
2681 ok(sbi
.dwSize
.Y
== size
, "Unexpected buffer size: %d instead of %d\n", sbi
.dwSize
.Y
, size
);
2685 /* Non interactive tests */
2686 testCursor(hConOut
, sbi
.dwSize
);
2687 /* test parameters (FIXME: test functionality) */
2688 testCursorInfo(hConOut
);
2689 /* will test wrapped (on/off) & processed (on/off) strings output */
2690 testWrite(hConOut
, sbi
.dwSize
);
2691 /* will test line scrolling at the bottom of the screen */
2692 /* testBottomScroll(); */
2693 /* will test all the scrolling operations */
2694 testScroll(hConOut
, sbi
.dwSize
);
2695 /* will test sb creation / modification / codepage handling */
2696 testScreenBuffer(hConOut
);
2698 /* still to be done: access rights & access on objects */
2700 if (!pGetConsoleInputExeNameA
|| !pSetConsoleInputExeNameA
)
2701 win_skip("GetConsoleInputExeNameA and/or SetConsoleInputExeNameA is not available\n");
2703 test_GetSetConsoleInputExeName();
2705 test_GetConsoleProcessList();
2706 test_OpenConsoleW();
2709 test_VerifyConsoleIoHandle(hConOut
);
2710 test_GetSetStdHandle();
2711 test_GetNumberOfConsoleInputEvents(hConIn
);
2712 test_WriteConsoleInputA(hConIn
);
2713 test_WriteConsoleInputW(hConIn
);
2714 test_WriteConsoleOutputCharacterA(hConOut
);
2715 test_WriteConsoleOutputCharacterW(hConOut
);
2716 test_WriteConsoleOutputAttribute(hConOut
);
2717 test_FillConsoleOutputCharacterA(hConOut
);
2718 test_FillConsoleOutputCharacterW(hConOut
);
2719 test_FillConsoleOutputAttribute(hConOut
);
2720 test_ReadConsoleOutputCharacterA(hConOut
);
2721 test_ReadConsoleOutputCharacterW(hConOut
);
2722 test_ReadConsoleOutputAttribute(hConOut
);