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
24 static BOOL (WINAPI
*pGetConsoleInputExeNameA
)(DWORD
, LPSTR
);
25 static DWORD (WINAPI
*pGetConsoleProcessList
)(LPDWORD
, DWORD
);
26 static HANDLE (WINAPI
*pOpenConsoleW
)(LPCWSTR
,DWORD
,BOOL
,DWORD
);
27 static BOOL (WINAPI
*pSetConsoleInputExeNameA
)(LPCSTR
);
28 static BOOL (WINAPI
*pVerifyConsoleIoHandle
)(HANDLE handle
);
30 /* DEFAULT_ATTRIB is used for all initial filling of the console.
31 * all modifications are made with TEST_ATTRIB so that we could check
32 * what has to be modified or not
34 #define TEST_ATTRIB (BACKGROUND_BLUE | FOREGROUND_GREEN)
35 #define DEFAULT_ATTRIB (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED)
36 /* when filling the screen with non-blank chars, this macro defines
37 * what character should be at position 'c'
39 #define CONTENT(c) ('A' + (((c).Y * 17 + (c).X) % 23))
41 #define okCURSOR(hCon, c) do { \
42 CONSOLE_SCREEN_BUFFER_INFO __sbi; \
43 BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
44 __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
45 ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
46 (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
49 #define okCHAR(hCon, c, ch, attr) do { \
50 char __ch; WORD __attr; DWORD __len; BOOL expect; \
51 expect = ReadConsoleOutputCharacterA((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \
52 ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x\n", (c).X, (c).Y, (ch), (ch), __ch, __ch); \
53 expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \
54 ok(expect, "At (%d,%d): expecting attr %04x got %04x\n", (c).X, (c).Y, (attr), __attr); \
57 static void init_function_pointers(void)
61 #define KERNEL32_GET_PROC(func) \
62 p##func = (void *)GetProcAddress(hKernel32, #func); \
63 if(!p##func) trace("GetProcAddress(hKernel32, '%s') failed\n", #func);
65 hKernel32
= GetModuleHandleA("kernel32.dll");
66 KERNEL32_GET_PROC(GetConsoleInputExeNameA
);
67 KERNEL32_GET_PROC(GetConsoleProcessList
);
68 KERNEL32_GET_PROC(OpenConsoleW
);
69 KERNEL32_GET_PROC(SetConsoleInputExeNameA
);
70 KERNEL32_GET_PROC(VerifyConsoleIoHandle
);
72 #undef KERNEL32_GET_PROC
75 /* FIXME: this could be optimized on a speed point of view */
76 static void resetContent(HANDLE hCon
, COORD sbSize
, BOOL content
)
79 WORD attr
= DEFAULT_ATTRIB
;
83 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
85 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
87 ch
= (content
) ? CONTENT(c
) : ' ';
88 WriteConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
89 WriteConsoleOutputCharacterA(hCon
, &ch
, 1, c
, &len
);
94 static void testCursor(HANDLE hCon
, COORD sbSize
)
99 ok(SetConsoleCursorPosition(0, c
) == 0, "No handle\n");
100 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
101 ERROR_INVALID_HANDLE
, GetLastError());
104 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
109 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in lower-right\n");
114 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
115 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
116 ERROR_INVALID_PARAMETER
, GetLastError());
120 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
121 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
122 ERROR_INVALID_PARAMETER
, GetLastError());
126 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
127 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
128 ERROR_INVALID_PARAMETER
, GetLastError());
132 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
133 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
134 ERROR_INVALID_PARAMETER
, GetLastError());
137 static void testCursorInfo(HANDLE hCon
)
140 CONSOLE_CURSOR_INFO info
;
142 SetLastError(0xdeadbeef);
143 ret
= GetConsoleCursorInfo(NULL
, NULL
);
144 ok(!ret
, "Expected failure\n");
145 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
146 ERROR_INVALID_HANDLE
, GetLastError());
148 SetLastError(0xdeadbeef);
150 ret
= GetConsoleCursorInfo(NULL
, &info
);
151 ok(!ret
, "Expected failure\n");
152 ok(info
.dwSize
== -1, "Expected no change for dwSize\n");
153 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
154 ERROR_INVALID_HANDLE
, GetLastError());
156 /* Test the correct call first to distinguish between win9x and the rest */
157 SetLastError(0xdeadbeef);
158 ret
= GetConsoleCursorInfo(hCon
, &info
);
159 ok(ret
, "Expected success\n");
160 ok(info
.dwSize
== 25 ||
161 info
.dwSize
== 12 /* win9x */,
162 "Expected 12 or 25, got %d\n", info
.dwSize
);
163 ok(info
.bVisible
, "Expected the cursor to be visible\n");
164 ok(GetLastError() == 0xdeadbeef, "GetLastError: expecting %u got %u\n",
165 0xdeadbeef, GetLastError());
167 /* Don't test NULL CONSOLE_CURSOR_INFO, it crashes on win9x and win7 */
170 static void testEmptyWrite(HANDLE hCon
)
172 static const char emptybuf
[16];
177 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
180 ok(WriteConsoleA(hCon
, NULL
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
183 /* Passing a NULL lpBuffer with sufficiently large non-zero length succeeds
184 * on native Windows and result in memory-like contents being written to
185 * the console. Calling WriteConsoleW like this will crash on Wine. */
189 ok(!WriteConsoleA(hCon
, NULL
, 16, &len
, NULL
) && len
== -1, "WriteConsole\n");
192 /* Cursor advances for this call. */
194 ok(WriteConsoleA(hCon
, NULL
, 128, &len
, NULL
) != 0 && len
== 128, "WriteConsole\n");
198 ok(WriteConsoleA(hCon
, emptybuf
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
201 /* WriteConsole does not halt on a null terminator and is happy to write
202 * memory contents beyond the actual size of the buffer. */
204 ok(WriteConsoleA(hCon
, emptybuf
, 16, &len
, NULL
) != 0 && len
== 16, "WriteConsole\n");
209 static void testWriteSimple(HANDLE hCon
)
213 const char* mytest
= "abcdefg";
214 const int mylen
= strlen(mytest
);
216 /* single line write */
218 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
220 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
222 for (c
.X
= 0; c
.X
< mylen
; c
.X
++)
224 okCHAR(hCon
, c
, mytest
[c
.X
], TEST_ATTRIB
);
228 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
231 static void testWriteNotWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
235 const char* mytest
= "123";
236 const int mylen
= strlen(mytest
);
240 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
& ~(ENABLE_PROCESSED_OUTPUT
|ENABLE_WRAP_AT_EOL_OUTPUT
)),
241 "clearing wrap at EOL & processed output\n");
243 /* write line, wrapping disabled, buffer exceeds sb width */
244 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
245 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
247 ret
= WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
);
248 ok(ret
!= 0 && len
== mylen
, "Couldn't write, ret = %d, len = %d\n", ret
, len
);
250 for (p
= mylen
- 3; p
< mylen
; p
++)
252 c
.X
= sbSize
.X
- 3 + p
% 3;
253 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
257 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
259 p
= sbSize
.X
- 3 + mylen
% 3;
262 /* write line, wrapping disabled, strings end on end of line */
263 c
.X
= sbSize
.X
- mylen
; c
.Y
= 0;
264 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
266 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
269 static void testWriteNotWrappedProcessed(HANDLE hCon
, COORD sbSize
)
273 const char* mytest
= "abcd\nf\tg";
274 const int mylen
= strlen(mytest
);
275 const int mylen2
= strchr(mytest
, '\n') - mytest
;
279 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, (mode
| ENABLE_PROCESSED_OUTPUT
) & ~ENABLE_WRAP_AT_EOL_OUTPUT
),
280 "clearing wrap at EOL & setting processed output\n");
282 /* write line, wrapping disabled, buffer exceeds sb width */
283 c
.X
= sbSize
.X
- 5; c
.Y
= 0;
284 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-5\n");
286 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
288 for (c
.X
= sbSize
.X
- 5; c
.X
< sbSize
.X
- 1; c
.X
++)
290 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 5], TEST_ATTRIB
);
293 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
294 /* Win9x and WinMe change the attribs for '\n' up to 'f' */
295 if (attr
== TEST_ATTRIB
)
297 win_skip("Win9x/WinMe don't respect ~ENABLE_WRAP_AT_EOL_OUTPUT\n");
301 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
304 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
305 for (c
.X
= 1; c
.X
< 8; c
.X
++)
306 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
307 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
309 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
313 /* write line, wrapping disabled, strings end on end of line */
314 c
.X
= sbSize
.X
- 4; c
.Y
= 0;
315 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
317 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
319 for (c
.X
= sbSize
.X
- 4; c
.X
< sbSize
.X
; c
.X
++)
321 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 4], TEST_ATTRIB
);
324 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
325 for (c
.X
= 1; c
.X
< 8; c
.X
++)
326 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
327 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
329 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
333 /* write line, wrapping disabled, strings end after end of line */
334 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
335 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
337 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
339 for (p
= mylen2
- 3; p
< mylen2
; p
++)
341 c
.X
= sbSize
.X
- 3 + p
% 3;
342 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
345 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
346 for (c
.X
= 1; c
.X
< 8; c
.X
++)
347 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
348 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
350 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
355 static void testWriteWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
359 const char* mytest
= "abcd\nf\tg";
360 const int mylen
= strlen(mytest
);
363 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
,(mode
| ENABLE_WRAP_AT_EOL_OUTPUT
) & ~(ENABLE_PROCESSED_OUTPUT
)),
364 "setting wrap at EOL & clearing processed output\n");
366 /* write line, wrapping enabled, buffer doesn't exceed sb width */
367 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
368 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
370 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
372 for (p
= 0; p
< mylen
; p
++)
374 c
.X
= sbSize
.X
- 9 + p
;
375 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
377 c
.X
= sbSize
.X
- 9 + mylen
;
378 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
380 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
382 /* write line, wrapping enabled, buffer does exceed sb width */
383 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
384 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
388 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
391 static void testWriteWrappedProcessed(HANDLE hCon
, COORD sbSize
)
395 const char* mytest
= "abcd\nf\tg";
396 const int mylen
= strlen(mytest
);
400 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
| (ENABLE_WRAP_AT_EOL_OUTPUT
|ENABLE_PROCESSED_OUTPUT
)),
401 "setting wrap at EOL & processed output\n");
403 /* write line, wrapping enabled, buffer doesn't exceed sb width */
404 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
405 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
407 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
408 for (p
= 0; p
< 4; p
++)
410 c
.X
= sbSize
.X
- 9 + p
;
411 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
413 c
.X
= sbSize
.X
- 9 + p
;
414 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
415 if (attr
== TEST_ATTRIB
)
416 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
418 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
420 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
421 for (c
.X
= 1; c
.X
< 8; c
.X
++)
422 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
423 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
425 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
428 /* write line, wrapping enabled, buffer does exceed sb width */
429 c
.X
= sbSize
.X
- 3; c
.Y
= 2;
430 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
432 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
433 for (p
= 0; p
< 3; p
++)
435 c
.X
= sbSize
.X
- 3 + p
;
436 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
439 okCHAR(hCon
, c
, mytest
[3], TEST_ATTRIB
);
441 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
442 if (attr
== TEST_ATTRIB
)
443 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
445 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
448 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
449 for (c
.X
= 1; c
.X
< 8; c
.X
++)
450 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
451 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
453 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
457 static void testWrite(HANDLE hCon
, COORD sbSize
)
459 /* FIXME: should in fact ensure that the sb is at least 10 characters wide */
460 ok(SetConsoleTextAttribute(hCon
, TEST_ATTRIB
), "Setting default text color\n");
461 resetContent(hCon
, sbSize
, FALSE
);
462 testEmptyWrite(hCon
);
463 resetContent(hCon
, sbSize
, FALSE
);
464 testWriteSimple(hCon
);
465 resetContent(hCon
, sbSize
, FALSE
);
466 testWriteNotWrappedNotProcessed(hCon
, sbSize
);
467 resetContent(hCon
, sbSize
, FALSE
);
468 testWriteNotWrappedProcessed(hCon
, sbSize
);
469 resetContent(hCon
, sbSize
, FALSE
);
470 testWriteWrappedNotProcessed(hCon
, sbSize
);
471 resetContent(hCon
, sbSize
, FALSE
);
472 testWriteWrappedProcessed(hCon
, sbSize
);
475 static void testScroll(HANDLE hCon
, COORD sbSize
)
477 SMALL_RECT scroll
, clip
;
485 #define IN_SRECT(r,c) ((r).Left <= (c).X && (c).X <= (r).Right && (r).Top <= (c).Y && (c).Y <= (r).Bottom)
486 #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)
488 /* no clipping, src & dst rect don't overlap */
489 resetContent(hCon
, sbSize
, TRUE
);
492 scroll
.Right
= W
- 1;
494 scroll
.Bottom
= H
- 1;
497 ci
.Char
.UnicodeChar
= '#';
498 ci
.Attributes
= TEST_ATTRIB
;
501 clip
.Right
= sbSize
.X
- 1;
503 clip
.Bottom
= sbSize
.Y
- 1;
505 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
507 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
509 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
511 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
515 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
517 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
518 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
519 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
523 /* no clipping, src & dst rect do overlap */
524 resetContent(hCon
, sbSize
, TRUE
);
527 scroll
.Right
= W
- 1;
529 scroll
.Bottom
= H
- 1;
532 ci
.Char
.UnicodeChar
= '#';
533 ci
.Attributes
= TEST_ATTRIB
;
536 clip
.Right
= sbSize
.X
- 1;
538 clip
.Bottom
= sbSize
.Y
- 1;
540 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
542 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
544 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
546 if (dst
.X
<= c
.X
&& c
.X
< dst
.X
+ W
&& dst
.Y
<= c
.Y
&& c
.Y
< dst
.Y
+ H
)
550 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
552 else if (c
.X
< W
&& c
.Y
< H
) okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
553 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
557 /* clipping, src & dst rect don't overlap */
558 resetContent(hCon
, sbSize
, TRUE
);
561 scroll
.Right
= W
- 1;
563 scroll
.Bottom
= H
- 1;
566 ci
.Char
.UnicodeChar
= '#';
567 ci
.Attributes
= TEST_ATTRIB
;
570 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
572 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
574 SetLastError(0xdeadbeef);
575 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
);
578 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
580 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
582 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
586 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
588 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
589 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
590 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
596 /* Win9x will fail, Only accept ERROR_NOT_ENOUGH_MEMORY */
597 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
,
598 "Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
601 /* clipping, src & dst rect do overlap */
602 resetContent(hCon
, sbSize
, TRUE
);
605 scroll
.Right
= W
- 1;
607 scroll
.Bottom
= H
- 1;
610 ci
.Char
.UnicodeChar
= '#';
611 ci
.Attributes
= TEST_ATTRIB
;
614 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
616 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
618 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
), "Scrolling SB\n");
620 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
622 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
624 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
628 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
630 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
631 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
632 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
637 static int mch_count
;
638 /* we need the event as Wine console event generation isn't synchronous
639 * (ie GenerateConsoleCtrlEvent returns before all ctrl-handlers in all
640 * processes have been called).
642 static HANDLE mch_event
;
643 static BOOL WINAPI
mch(DWORD event
)
650 static void testCtrlHandler(void)
652 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
653 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
654 ok(SetConsoleCtrlHandler(mch
, TRUE
), "Couldn't set handler\n");
655 /* wine requires the event for the test, as we cannot ensure, so far, that
656 * events are processed synchronously in GenerateConsoleCtrlEvent()
658 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
660 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
661 /* FIXME: it isn't synchronous on wine but it can still happen before we test */
662 if (0) ok(mch_count
== 1, "Event isn't synchronous\n");
663 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_OBJECT_0
, "event sending didn't work\n");
664 CloseHandle(mch_event
);
666 /* Turning off ctrl-c handling doesn't work on win9x such way ... */
667 ok(SetConsoleCtrlHandler(NULL
, TRUE
), "Couldn't turn off ctrl-c handling\n");
668 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
670 if(!(GetVersion() & 0x80000000))
671 /* ... and next line leads to an unhandled exception on 9x. Avoid it on 9x. */
672 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
673 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_TIMEOUT
&& mch_count
== 0, "Event shouldn't have been sent\n");
674 CloseHandle(mch_event
);
675 ok(SetConsoleCtrlHandler(mch
, FALSE
), "Couldn't remove handler\n");
676 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
677 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
681 * Test console screen buffer:
682 * 1) Try to set invalid handle.
683 * 2) Try to set non-console handles.
684 * 3) Use CONOUT$ file as active SB.
686 * 5) Test output codepage to show it is not a property of SB.
687 * 6) Test switching to old SB if we close all handles to current SB - works
688 * in Windows, TODO in wine.
690 * What is not tested but should be:
691 * 1) ScreenBufferInfo
693 static void testScreenBuffer(HANDLE hConOut
)
695 HANDLE hConOutRW
, hConOutRO
, hConOutWT
;
696 HANDLE hFileOutRW
, hFileOutRO
, hFileOutWT
;
698 char test_str1
[] = "Test for SB1";
699 char test_str2
[] = "Test for SB2";
700 char test_cp866
[] = {0xe2, 0xa5, 0xe1, 0xe2, 0};
701 char test_cp1251
[] = {0xf2, 0xe5, 0xf1, 0xf2, 0};
702 WCHAR test_unicode
[] = {0x0442, 0x0435, 0x0441, 0x0442, 0};
710 if (!IsValidCodePage(866))
712 skip("Codepage 866 not available\n");
716 /* In the beginning set output codepage to 866 */
717 oldcp
= GetConsoleOutputCP();
718 SetLastError(0xdeadbeef);
719 ret
= SetConsoleOutputCP(866);
720 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
722 win_skip("SetConsoleOutputCP is not implemented\n");
725 ok(ret
, "Cannot set output codepage to 866\n");
727 hConOutRW
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
728 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
729 CONSOLE_TEXTMODE_BUFFER
, NULL
);
730 ok(hConOutRW
!= INVALID_HANDLE_VALUE
,
731 "Cannot create a new screen buffer for ReadWrite\n");
732 hConOutRO
= CreateConsoleScreenBuffer(GENERIC_READ
,
733 FILE_SHARE_READ
, NULL
,
734 CONSOLE_TEXTMODE_BUFFER
, NULL
);
735 ok(hConOutRO
!= INVALID_HANDLE_VALUE
,
736 "Cannot create a new screen buffer for ReadOnly\n");
737 hConOutWT
= CreateConsoleScreenBuffer(GENERIC_WRITE
,
738 FILE_SHARE_WRITE
, NULL
,
739 CONSOLE_TEXTMODE_BUFFER
, NULL
);
740 ok(hConOutWT
!= INVALID_HANDLE_VALUE
,
741 "Cannot create a new screen buffer for WriteOnly\n");
743 hFileOutRW
= CreateFileA("NUL", GENERIC_READ
| GENERIC_WRITE
,
744 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
745 OPEN_EXISTING
, 0, NULL
);
746 ok(hFileOutRW
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadWrite\n");
747 hFileOutRO
= CreateFileA("NUL", GENERIC_READ
, FILE_SHARE_READ
,
748 NULL
, OPEN_EXISTING
, 0, NULL
);
749 ok(hFileOutRO
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadOnly\n");
750 hFileOutWT
= CreateFileA("NUL", GENERIC_WRITE
, FILE_SHARE_WRITE
,
751 NULL
, OPEN_EXISTING
, 0, NULL
);
752 ok(hFileOutWT
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for WriteOnly\n");
754 /* Trying to set invalid handle */
756 ok(!SetConsoleActiveScreenBuffer(INVALID_HANDLE_VALUE
),
757 "Shouldn't succeed\n");
758 ok(GetLastError() == ERROR_INVALID_HANDLE
,
759 "GetLastError: expecting %u got %u\n",
760 ERROR_INVALID_HANDLE
, GetLastError());
762 /* Trying to set non-console handles */
764 ok(!SetConsoleActiveScreenBuffer(hFileOutRW
), "Shouldn't succeed\n");
765 ok(GetLastError() == ERROR_INVALID_HANDLE
,
766 "GetLastError: expecting %u got %u\n",
767 ERROR_INVALID_HANDLE
, GetLastError());
770 ok(!SetConsoleActiveScreenBuffer(hFileOutRO
), "Shouldn't succeed\n");
771 ok(GetLastError() == ERROR_INVALID_HANDLE
,
772 "GetLastError: expecting %u got %u\n",
773 ERROR_INVALID_HANDLE
, GetLastError());
776 ok(!SetConsoleActiveScreenBuffer(hFileOutWT
), "Shouldn't succeed\n");
777 ok(GetLastError() == ERROR_INVALID_HANDLE
,
778 "GetLastError: expecting %u got %u\n",
779 ERROR_INVALID_HANDLE
, GetLastError());
781 /* trying to write non-console handle */
782 SetLastError(0xdeadbeef);
783 ret
= WriteConsoleA(hFileOutRW
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
784 error
= GetLastError();
785 ok(!ret
, "Shouldn't succeed\n");
786 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
787 "GetLastError: got %u\n", error
);
789 SetLastError(0xdeadbeef);
790 ret
= WriteConsoleA(hFileOutRO
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
791 error
= GetLastError();
792 ok(!ret
, "Shouldn't succeed\n");
793 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
794 "GetLastError: got %u\n", error
);
796 SetLastError(0xdeadbeef);
797 ret
= WriteConsoleA(hFileOutWT
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
798 error
= GetLastError();
799 ok(!ret
, "Shouldn't succeed\n");
800 todo_wine
ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
801 "GetLastError: got %u\n", error
);
803 CloseHandle(hFileOutRW
);
804 CloseHandle(hFileOutRO
);
805 CloseHandle(hFileOutWT
);
807 /* Trying to set SB handles with various access modes */
809 ok(!SetConsoleActiveScreenBuffer(hConOutRO
), "Shouldn't succeed\n");
810 ok(GetLastError() == ERROR_INVALID_HANDLE
,
811 "GetLastError: expecting %u got %u\n",
812 ERROR_INVALID_HANDLE
, GetLastError());
814 ok(SetConsoleActiveScreenBuffer(hConOutWT
), "Couldn't set new WriteOnly SB\n");
816 ok(SetConsoleActiveScreenBuffer(hConOutRW
), "Couldn't set new ReadWrite SB\n");
818 CloseHandle(hConOutWT
);
819 CloseHandle(hConOutRO
);
821 /* Now we have two ReadWrite SB, active must be hConOutRW */
822 /* Open current SB via CONOUT$ */
823 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
824 NULL
, OPEN_EXISTING
, 0, 0);
825 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
830 SetConsoleCursorPosition(hConOut
, c
);
832 SetConsoleCursorPosition(hConOutRW
, c
);
833 okCURSOR(hConOutNew
, c
);
835 okCURSOR(hConOut
, c
);
840 /* Write using hConOutNew... */
841 SetConsoleCursorPosition(hConOutNew
, c
);
842 ret
= WriteConsoleA(hConOutNew
, test_str2
, lstrlenA(test_str2
), &len
, NULL
);
843 ok (ret
&& len
== lstrlenA(test_str2
), "WriteConsoleA failed\n");
844 /* ... and read it back via hConOutRW */
845 ret
= ReadConsoleOutputCharacterA(hConOutRW
, str_buf
, lstrlenA(test_str2
), c
, &len
);
846 ok(ret
&& len
== lstrlenA(test_str2
), "ReadConsoleOutputCharacterA failed\n");
847 str_buf
[lstrlenA(test_str2
)] = 0;
848 ok(!lstrcmpA(str_buf
, test_str2
), "got '%s' expected '%s'\n", str_buf
, test_str2
);
851 /* Now test output codepage handling. Current is 866 as we set earlier. */
852 SetConsoleCursorPosition(hConOutRW
, c
);
853 ret
= WriteConsoleA(hConOutRW
, test_cp866
, lstrlenA(test_cp866
), &len
, NULL
);
854 ok(ret
&& len
== lstrlenA(test_cp866
), "WriteConsoleA failed\n");
855 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp866
), c
, &len
);
856 ok(ret
&& len
== lstrlenA(test_cp866
), "ReadConsoleOutputCharacterW failed\n");
857 str_wbuf
[lstrlenA(test_cp866
)] = 0;
858 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
861 * cp866 is OK, let's switch to cp1251.
862 * We expect that this codepage will be used in every SB - active and not.
864 ok(SetConsoleOutputCP(1251), "Cannot set output cp to 1251\n");
865 SetConsoleCursorPosition(hConOutRW
, c
);
866 ret
= WriteConsoleA(hConOutRW
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
867 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
868 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
869 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
870 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
871 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
873 /* Check what has happened to hConOut. */
874 SetConsoleCursorPosition(hConOut
, c
);
875 ret
= WriteConsoleA(hConOut
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
876 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
877 ret
= ReadConsoleOutputCharacterW(hConOut
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
878 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
879 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
880 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
882 /* Close all handles of current console SB */
883 CloseHandle(hConOutNew
);
884 CloseHandle(hConOutRW
);
886 /* Now active SB should be hConOut */
887 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
888 NULL
, OPEN_EXISTING
, 0, 0);
889 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
891 /* Write using hConOutNew... */
892 SetConsoleCursorPosition(hConOutNew
, c
);
893 ret
= WriteConsoleA(hConOutNew
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
894 ok (ret
&& len
== lstrlenA(test_str1
), "WriteConsoleA failed\n");
895 /* ... and read it back via hConOut */
896 ret
= ReadConsoleOutputCharacterA(hConOut
, str_buf
, lstrlenA(test_str1
), c
, &len
);
897 ok(ret
&& len
== lstrlenA(test_str1
), "ReadConsoleOutputCharacterA failed\n");
898 str_buf
[lstrlenA(test_str1
)] = 0;
899 todo_wine
ok(!lstrcmpA(str_buf
, test_str1
), "got '%s' expected '%s'\n", str_buf
, test_str1
);
900 CloseHandle(hConOutNew
);
902 /* This is not really needed under Windows */
903 SetConsoleActiveScreenBuffer(hConOut
);
905 /* restore codepage */
906 SetConsoleOutputCP(oldcp
);
909 static void CALLBACK
signaled_function(void *p
, BOOLEAN timeout
)
913 ok(!timeout
, "wait shouldn't have timed out\n");
916 static void testWaitForConsoleInput(HANDLE input_handle
)
919 HANDLE complete_event
;
921 DWORD events_written
;
925 complete_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
927 /* Test success case */
928 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
929 ok(ret
== TRUE
, "Expected RegisterWaitForSingleObject to return TRUE, got %d\n", ret
);
930 /* give worker thread a chance to start up */
932 record
.EventType
= KEY_EVENT
;
933 record
.Event
.KeyEvent
.bKeyDown
= 1;
934 record
.Event
.KeyEvent
.wRepeatCount
= 1;
935 record
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
936 record
.Event
.KeyEvent
.wVirtualScanCode
= VK_RETURN
;
937 record
.Event
.KeyEvent
.uChar
.UnicodeChar
= '\r';
938 record
.Event
.KeyEvent
.dwControlKeyState
= 0;
939 ret
= WriteConsoleInputW(input_handle
, &record
, 1, &events_written
);
940 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
941 wait_ret
= WaitForSingleObject(complete_event
, INFINITE
);
942 ok(wait_ret
== WAIT_OBJECT_0
, "Expected the handle to be signaled\n");
943 ret
= UnregisterWait(wait_handle
);
944 /* If the callback is still running, this fails with ERROR_IO_PENDING, but
945 that's ok and expected. */
946 ok(ret
!= 0 || GetLastError() == ERROR_IO_PENDING
,
947 "UnregisterWait failed with error %d\n", GetLastError());
949 /* Test timeout case */
950 FlushConsoleInputBuffer(input_handle
);
951 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
952 wait_ret
= WaitForSingleObject(complete_event
, 100);
953 ok(wait_ret
== WAIT_TIMEOUT
, "Expected the wait to time out\n");
954 ret
= UnregisterWait(wait_handle
);
955 ok(ret
, "UnregisterWait failed with error %d\n", GetLastError());
958 CloseHandle(complete_event
);
961 static void test_GetSetConsoleInputExeName(void)
965 char buffer
[MAX_PATH
], module
[MAX_PATH
], *p
;
966 static char input_exe
[MAX_PATH
] = "winetest.exe";
968 SetLastError(0xdeadbeef);
969 ret
= pGetConsoleInputExeNameA(0, NULL
);
970 error
= GetLastError();
971 ok(ret
, "GetConsoleInputExeNameA failed\n");
972 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
974 SetLastError(0xdeadbeef);
975 ret
= pGetConsoleInputExeNameA(0, buffer
);
976 error
= GetLastError();
977 ok(ret
, "GetConsoleInputExeNameA failed\n");
978 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
980 GetModuleFileNameA(GetModuleHandleA(NULL
), module
, sizeof(module
));
981 p
= strrchr(module
, '\\') + 1;
983 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
984 ok(ret
, "GetConsoleInputExeNameA failed\n");
985 todo_wine
ok(!lstrcmpA(buffer
, p
), "got %s expected %s\n", buffer
, p
);
987 SetLastError(0xdeadbeef);
988 ret
= pSetConsoleInputExeNameA(NULL
);
989 error
= GetLastError();
990 ok(!ret
, "SetConsoleInputExeNameA failed\n");
991 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
993 SetLastError(0xdeadbeef);
994 ret
= pSetConsoleInputExeNameA("");
995 error
= GetLastError();
996 ok(!ret
, "SetConsoleInputExeNameA failed\n");
997 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
999 ret
= pSetConsoleInputExeNameA(input_exe
);
1000 ok(ret
, "SetConsoleInputExeNameA failed\n");
1002 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
1003 ok(ret
, "GetConsoleInputExeNameA failed\n");
1004 ok(!lstrcmpA(buffer
, input_exe
), "got %s expected %s\n", buffer
, input_exe
);
1007 static void test_GetConsoleProcessList(void)
1009 DWORD ret
, *list
= NULL
;
1011 if (!pGetConsoleProcessList
)
1013 win_skip("GetConsoleProcessList is not available\n");
1017 SetLastError(0xdeadbeef);
1018 ret
= pGetConsoleProcessList(NULL
, 0);
1019 ok(ret
== 0, "Expected failure\n");
1020 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1021 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1024 SetLastError(0xdeadbeef);
1025 ret
= pGetConsoleProcessList(NULL
, 1);
1026 ok(ret
== 0, "Expected failure\n");
1027 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1028 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1031 /* We should only have 1 process but only for these specific unit tests as
1032 * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) would
1033 * give us two processes for example.
1035 list
= HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD
));
1037 SetLastError(0xdeadbeef);
1038 ret
= pGetConsoleProcessList(list
, 0);
1039 ok(ret
== 0, "Expected failure\n");
1040 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1041 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1044 SetLastError(0xdeadbeef);
1045 ret
= pGetConsoleProcessList(list
, 1);
1047 ok(ret
== 1, "Expected 1, got %d\n", ret
);
1049 HeapFree(GetProcessHeap(), 0, list
);
1051 list
= HeapAlloc(GetProcessHeap(), 0, ret
* sizeof(DWORD
));
1053 SetLastError(0xdeadbeef);
1054 ret
= pGetConsoleProcessList(list
, ret
);
1056 ok(ret
== 1, "Expected 1, got %d\n", ret
);
1060 DWORD pid
= GetCurrentProcessId();
1061 ok(list
[0] == pid
, "Expected %d, got %d\n", pid
, list
[0]);
1064 HeapFree(GetProcessHeap(), 0, list
);
1067 static void test_OpenCON(void)
1069 static const WCHAR conW
[] = {'C','O','N',0};
1070 static const DWORD accesses
[] = {CREATE_NEW
, CREATE_ALWAYS
, OPEN_EXISTING
,
1071 OPEN_ALWAYS
, TRUNCATE_EXISTING
};
1075 for (i
= 0; i
< sizeof(accesses
) / sizeof(accesses
[0]); i
++)
1077 h
= CreateFileW(conW
, GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1078 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win8 */),
1079 "Expected to open the CON device on write (%x)\n", accesses
[i
]);
1082 h
= CreateFileW(conW
, GENERIC_READ
, 0, NULL
, accesses
[i
], 0, NULL
);
1083 /* Windows versions differ here:
1084 * MSDN states in CreateFile that TRUNCATE_EXISTING requires GENERIC_WRITE
1085 * NT, XP, Vista comply, but Win7 doesn't and allows opening CON with TRUNCATE_EXISTING
1086 * So don't test when disposition is TRUNCATE_EXISTING
1088 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win7+ */),
1089 "Expected to open the CON device on read (%x)\n", accesses
[i
]);
1091 h
= CreateFileW(conW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1092 ok(h
== INVALID_HANDLE_VALUE
, "Expected not to open the CON device on read-write (%x)\n", accesses
[i
]);
1093 ok(GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1094 "Unexpected error %x\n", GetLastError());
1098 static void test_OpenConsoleW(void)
1100 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1101 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1102 static const WCHAR emptyW
[] = {0};
1103 static const WCHAR invalidW
[] = {'I','N','V','A','L','I','D',0};
1113 } invalid_table
[] = {
1114 {NULL
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1115 {NULL
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1116 {NULL
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1117 {NULL
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1118 {NULL
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1119 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1120 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1121 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1122 {emptyW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1123 {emptyW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1124 {emptyW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1125 {emptyW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1126 {emptyW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1127 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1128 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1129 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1130 {invalidW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1131 {invalidW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1132 {invalidW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1133 {invalidW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1134 {invalidW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1135 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1136 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1137 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1138 {coninW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1139 {coninW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1140 {coninW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1141 {conoutW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1142 {conoutW
, 0xceadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1143 {conoutW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1152 {coninW
, 0, FALSE
, 0 },
1153 {coninW
, 0, TRUE
, 0 },
1154 {coninW
, GENERIC_EXECUTE
, TRUE
, 0 },
1155 {coninW
, GENERIC_ALL
, TRUE
, 0 },
1156 {coninW
, 0, FALSE
, OPEN_ALWAYS
},
1157 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1158 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
},
1159 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1160 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1161 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1162 {conoutW
, 0, FALSE
, 0 },
1163 {conoutW
, 0, FALSE
, OPEN_ALWAYS
},
1164 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1165 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, },
1166 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1167 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1168 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1176 win_skip("OpenConsoleW is not available\n");
1180 for (index
= 0; index
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); index
++)
1182 SetLastError(0xdeadbeef);
1183 ret
= pOpenConsoleW(invalid_table
[index
].name
, invalid_table
[index
].access
,
1184 invalid_table
[index
].inherit
, invalid_table
[index
].creation
);
1185 gle
= GetLastError();
1186 ok(ret
== INVALID_HANDLE_VALUE
,
1187 "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
1189 ok(gle
== invalid_table
[index
].gle
|| (gle
!= 0 && gle
== invalid_table
[index
].gle2
),
1190 "Expected GetLastError() to return %u/%u for index %d, got %u\n",
1191 invalid_table
[index
].gle
, invalid_table
[index
].gle2
, index
, gle
);
1194 for (index
= 0; index
< sizeof(valid_table
)/sizeof(valid_table
[0]); index
++)
1196 ret
= pOpenConsoleW(valid_table
[index
].name
, valid_table
[index
].access
,
1197 valid_table
[index
].inherit
, valid_table
[index
].creation
);
1199 ok(ret
!= INVALID_HANDLE_VALUE
|| broken(ret
== INVALID_HANDLE_VALUE
/* until Win7 */),
1200 "Expected OpenConsoleW to succeed for index %d, got %p\n", index
, ret
);
1201 if (ret
!= INVALID_HANDLE_VALUE
)
1205 ret
= pOpenConsoleW(coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1206 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1207 if (ret
!= INVALID_HANDLE_VALUE
)
1210 ret
= pOpenConsoleW(conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1211 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1212 if (ret
!= INVALID_HANDLE_VALUE
)
1216 static void test_CreateFileW(void)
1218 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1219 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1230 {coninW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1231 {coninW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1232 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1233 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1234 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1235 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1236 {conoutW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1237 {conoutW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1238 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1239 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1240 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1241 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1242 /* TRUNCATE_EXISTING is forbidden starting with Windows 8 */
1247 SECURITY_ATTRIBUTES sa
;
1249 for (index
= 0; index
< sizeof(cf_table
)/sizeof(cf_table
[0]); index
++)
1251 SetLastError(0xdeadbeef);
1253 sa
.nLength
= sizeof(sa
);
1254 sa
.lpSecurityDescriptor
= NULL
;
1255 sa
.bInheritHandle
= cf_table
[index
].inherit
;
1257 ret
= CreateFileW(cf_table
[index
].name
, cf_table
[index
].access
,
1258 FILE_SHARE_READ
|FILE_SHARE_WRITE
, &sa
,
1259 cf_table
[index
].creation
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1260 if (ret
== INVALID_HANDLE_VALUE
)
1262 ok(cf_table
[index
].gle
,
1263 "Expected CreateFileW not to return INVALID_HANDLE_VALUE for index %d\n", index
);
1264 ok(GetLastError() == cf_table
[index
].gle
,
1265 "Expected GetLastError() to return %u for index %d, got %u\n",
1266 cf_table
[index
].gle
, index
, GetLastError());
1270 ok(!cf_table
[index
].gle
|| broken(cf_table
[index
].is_broken
) /* Win7 */,
1271 "Expected CreateFileW to succeed for index %d\n", index
);
1277 static void test_VerifyConsoleIoHandle( HANDLE handle
)
1282 if (!pVerifyConsoleIoHandle
)
1284 win_skip("VerifyConsoleIoHandle is not available\n");
1288 /* invalid handle */
1289 SetLastError(0xdeadbeef);
1290 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee0);
1291 error
= GetLastError();
1292 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1293 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1295 /* invalid handle + 1 */
1296 SetLastError(0xdeadbeef);
1297 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee1);
1298 error
= GetLastError();
1299 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1300 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1302 /* invalid handle + 2 */
1303 SetLastError(0xdeadbeef);
1304 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee2);
1305 error
= GetLastError();
1306 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1307 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1309 /* invalid handle + 3 */
1310 SetLastError(0xdeadbeef);
1311 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee3);
1312 error
= GetLastError();
1313 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1314 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1317 SetLastError(0xdeadbeef);
1318 ret
= pVerifyConsoleIoHandle(handle
);
1319 error
= GetLastError();
1321 broken(!ret
), /* Windows 8 and 10 */
1322 "expected VerifyConsoleIoHandle to succeed\n");
1323 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1326 static void test_GetSetStdHandle(void)
1332 /* get invalid std handle */
1333 SetLastError(0xdeadbeef);
1334 handle
= GetStdHandle(42);
1335 error
= GetLastError();
1336 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1337 "wrong GetLastError() %d\n", error
);
1338 ok(handle
== INVALID_HANDLE_VALUE
, "expected INVALID_HANDLE_VALUE\n");
1341 SetLastError(0xdeadbeef);
1342 handle
= GetStdHandle(STD_INPUT_HANDLE
);
1343 error
= GetLastError();
1344 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1346 /* set invalid std handle */
1347 SetLastError(0xdeadbeef);
1348 ret
= SetStdHandle(42, handle
);
1349 error
= GetLastError();
1350 ok(!ret
, "expected SetStdHandle to fail\n");
1351 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1352 "wrong GetLastError() %d\n", error
);
1354 /* set valid (restore old value) */
1355 SetLastError(0xdeadbeef);
1356 ret
= SetStdHandle(STD_INPUT_HANDLE
, handle
);
1357 error
= GetLastError();
1358 ok(ret
, "expected SetStdHandle to succeed\n");
1359 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1362 static void test_GetNumberOfConsoleInputEvents(HANDLE input_handle
)
1375 {NULL
, NULL
, ERROR_INVALID_HANDLE
},
1376 {NULL
, &count
, ERROR_INVALID_HANDLE
},
1377 {INVALID_HANDLE_VALUE
, NULL
, ERROR_INVALID_HANDLE
},
1378 {INVALID_HANDLE_VALUE
, &count
, ERROR_INVALID_HANDLE
},
1381 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1383 SetLastError(0xdeadbeef);
1384 if (invalid_table
[i
].nrofevents
) count
= 0xdeadbeef;
1385 ret
= GetNumberOfConsoleInputEvents(invalid_table
[i
].handle
,
1386 invalid_table
[i
].nrofevents
);
1387 ok(!ret
, "[%d] Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", i
, ret
);
1388 if (invalid_table
[i
].nrofevents
)
1390 ok(count
== 0xdeadbeef,
1391 "[%d] Expected output count to be unmodified, got %u\n", i
, count
);
1393 ok(GetLastError() == invalid_table
[i
].last_error
,
1394 "[%d] Expected last error to be %u, got %u\n",
1395 i
, invalid_table
[i
].last_error
, GetLastError());
1398 /* Test crashes on Windows 7. */
1401 SetLastError(0xdeadbeef);
1402 ret
= GetNumberOfConsoleInputEvents(input_handle
, NULL
);
1403 ok(!ret
, "Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", ret
);
1404 ok(GetLastError() == ERROR_INVALID_ACCESS
,
1405 "Expected last error to be ERROR_INVALID_ACCESS, got %u\n",
1410 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1411 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1412 ok(count
!= 0xdeadbeef, "Expected output count to initialized\n");
1415 static void test_WriteConsoleInputA(HANDLE input_handle
)
1418 INPUT_RECORD event_list
[5];
1419 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1420 KEY_EVENT_RECORD key_event
;
1421 DWORD count
, console_mode
, gle
;
1428 const INPUT_RECORD
*buffer
;
1435 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1436 {NULL
, NULL
, 0, &count
,ERROR_INVALID_HANDLE
},
1437 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1438 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1439 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1440 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1441 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1442 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1443 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1444 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1445 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1446 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1447 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1448 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1449 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1450 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1451 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1452 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1453 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1454 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1455 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1458 /* Suppress external sources of input events for the duration of the test. */
1459 ret
= GetConsoleMode(input_handle
, &console_mode
);
1460 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1463 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1467 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1468 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1471 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1475 /* Discard any events queued before the tests. */
1476 ret
= FlushConsoleInputBuffer(input_handle
);
1477 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1479 event
.EventType
= MOUSE_EVENT
;
1480 event
.Event
.MouseEvent
= mouse_event
;
1482 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1484 if (invalid_table
[i
].win_crash
)
1487 SetLastError(0xdeadbeef);
1488 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1489 ret
= WriteConsoleInputA(invalid_table
[i
].handle
,
1490 invalid_table
[i
].buffer
,
1491 invalid_table
[i
].count
,
1492 invalid_table
[i
].written
);
1493 ok(!ret
, "[%d] Expected WriteConsoleInputA to return FALSE, got %d\n", i
, ret
);
1494 gle
= GetLastError();
1495 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1496 "[%d] Expected last error to be %u or %u, got %u\n",
1497 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1501 ret
= WriteConsoleInputA(input_handle
, NULL
, 0, &count
);
1502 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1503 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1506 ret
= WriteConsoleInputA(input_handle
, &event
, 0, &count
);
1507 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1508 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1511 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1512 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1513 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1515 ret
= FlushConsoleInputBuffer(input_handle
);
1516 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1518 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1519 event
.EventType
= MOUSE_EVENT
;
1520 event
.Event
.MouseEvent
= mouse_event
;
1522 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1523 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1524 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1526 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1527 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1528 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1530 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1531 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1532 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1534 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1535 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1537 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1539 ret
= FlushConsoleInputBuffer(input_handle
);
1540 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1542 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1544 event_list
[i
].EventType
= MOUSE_EVENT
;
1545 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1548 /* Writing consecutive chunks of mouse events appears to work. */
1549 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1550 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1551 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1552 "Expected count to be event list length, got %u\n", count
);
1554 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1555 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1556 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1557 "Expected count to be event list length, got %u\n", count
);
1559 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1560 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1561 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1562 "Expected count to be event list length, got %u\n", count
);
1564 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1565 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1566 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1567 "Expected count to be twice event list length, got %u\n", count
);
1569 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1570 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1571 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1572 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1574 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1575 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1577 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1578 "Expected count to be twice event list length, got %u\n", count
);
1580 ret
= FlushConsoleInputBuffer(input_handle
);
1581 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1583 key_event
.bKeyDown
= FALSE
;
1584 key_event
.wRepeatCount
= 0;
1585 key_event
.wVirtualKeyCode
= VK_SPACE
;
1586 key_event
.wVirtualScanCode
= VK_SPACE
;
1587 key_event
.uChar
.AsciiChar
= ' ';
1588 key_event
.dwControlKeyState
= 0;
1590 event
.EventType
= KEY_EVENT
;
1591 event
.Event
.KeyEvent
= key_event
;
1593 /* Key events don't exhibit the same behavior as mouse events. */
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
== 1, "Expected count to be 1, got %u\n", count
);
1602 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1603 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1604 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1606 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1607 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1608 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1610 ret
= FlushConsoleInputBuffer(input_handle
);
1611 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1613 /* Try interleaving mouse and key events. */
1614 event
.EventType
= MOUSE_EVENT
;
1615 event
.Event
.MouseEvent
= mouse_event
;
1617 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1618 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1619 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1621 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1622 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1623 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1625 event
.EventType
= KEY_EVENT
;
1626 event
.Event
.KeyEvent
= key_event
;
1628 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1629 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1630 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1632 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1633 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1634 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1636 event
.EventType
= MOUSE_EVENT
;
1637 event
.Event
.MouseEvent
= mouse_event
;
1639 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1640 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1641 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1643 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1644 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1645 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1647 /* Restore the old console mode. */
1648 ret
= SetConsoleMode(input_handle
, console_mode
);
1649 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1652 static void test_WriteConsoleInputW(HANDLE input_handle
)
1655 INPUT_RECORD event_list
[5];
1656 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1657 KEY_EVENT_RECORD key_event
;
1658 DWORD count
, console_mode
, gle
;
1665 const INPUT_RECORD
*buffer
;
1672 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1673 {NULL
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1674 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1675 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1676 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1677 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1678 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1679 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1680 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1681 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1682 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1683 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1684 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1685 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1686 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1687 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1688 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1689 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1690 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1691 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1692 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1695 /* Suppress external sources of input events for the duration of the test. */
1696 ret
= GetConsoleMode(input_handle
, &console_mode
);
1697 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1700 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1704 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1705 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1708 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1712 /* Discard any events queued before the tests. */
1713 ret
= FlushConsoleInputBuffer(input_handle
);
1714 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1716 event
.EventType
= MOUSE_EVENT
;
1717 event
.Event
.MouseEvent
= mouse_event
;
1719 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1721 if (invalid_table
[i
].win_crash
)
1724 SetLastError(0xdeadbeef);
1725 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1726 ret
= WriteConsoleInputW(invalid_table
[i
].handle
,
1727 invalid_table
[i
].buffer
,
1728 invalid_table
[i
].count
,
1729 invalid_table
[i
].written
);
1730 ok(!ret
, "[%d] Expected WriteConsoleInputW to return FALSE, got %d\n", i
, ret
);
1731 gle
= GetLastError();
1732 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1733 "[%d] Expected last error to be %u or %u, got %u\n",
1734 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1738 ret
= WriteConsoleInputW(input_handle
, NULL
, 0, &count
);
1739 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1740 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1743 ret
= WriteConsoleInputW(input_handle
, &event
, 0, &count
);
1744 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1745 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1748 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1749 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1750 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1752 ret
= FlushConsoleInputBuffer(input_handle
);
1753 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1755 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1756 event
.EventType
= MOUSE_EVENT
;
1757 event
.Event
.MouseEvent
= mouse_event
;
1759 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1760 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1761 ok(count
== 1, "Expected count to be 1, 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
== 1, "Expected count to be 1, got %u\n", count
);
1767 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1768 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1769 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1771 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1772 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1774 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1776 ret
= FlushConsoleInputBuffer(input_handle
);
1777 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1779 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1781 event_list
[i
].EventType
= MOUSE_EVENT
;
1782 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1785 /* Writing consecutive chunks of mouse events appears to work. */
1786 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1787 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1788 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1789 "Expected count to be event list length, got %u\n", count
);
1791 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1792 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1793 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1794 "Expected count to be event list length, got %u\n", count
);
1796 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1797 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1798 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1799 "Expected count to be event list length, got %u\n", count
);
1801 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1802 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1803 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1804 "Expected count to be twice event list length, got %u\n", count
);
1806 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1807 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1808 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1809 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1811 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1812 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1814 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1815 "Expected count to be twice event list length, got %u\n", count
);
1817 ret
= FlushConsoleInputBuffer(input_handle
);
1818 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1820 key_event
.bKeyDown
= FALSE
;
1821 key_event
.wRepeatCount
= 0;
1822 key_event
.wVirtualKeyCode
= VK_SPACE
;
1823 key_event
.wVirtualScanCode
= VK_SPACE
;
1824 key_event
.uChar
.UnicodeChar
= ' ';
1825 key_event
.dwControlKeyState
= 0;
1827 event
.EventType
= KEY_EVENT
;
1828 event
.Event
.KeyEvent
= key_event
;
1830 /* Key events don't exhibit the same behavior as mouse events. */
1831 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1832 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1833 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1835 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1836 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1837 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1839 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1840 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1841 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1843 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1844 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1845 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1847 ret
= FlushConsoleInputBuffer(input_handle
);
1848 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1850 /* Try interleaving mouse and key events. */
1851 event
.EventType
= MOUSE_EVENT
;
1852 event
.Event
.MouseEvent
= mouse_event
;
1854 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1855 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1856 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1858 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1859 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1860 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1862 event
.EventType
= KEY_EVENT
;
1863 event
.Event
.KeyEvent
= key_event
;
1865 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1866 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1867 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1869 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1870 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1871 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1873 event
.EventType
= MOUSE_EVENT
;
1874 event
.Event
.MouseEvent
= mouse_event
;
1876 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1877 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1878 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1880 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1881 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1882 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1884 /* Restore the old console mode. */
1885 ret
= SetConsoleMode(input_handle
, console_mode
);
1886 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1889 static void test_WriteConsoleOutputCharacterA(HANDLE output_handle
)
1891 static const char output
[] = {'a', 0};
1893 COORD origin
= {0, 0};
1900 HANDLE hConsoleOutput
;
1904 LPDWORD lpNumCharsWritten
;
1905 DWORD expected_count
;
1910 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1911 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1912 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1913 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1914 {NULL
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1915 {NULL
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1916 {NULL
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1917 {NULL
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1918 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1919 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1920 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1921 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1922 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1923 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1924 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1925 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1926 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1927 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1928 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1929 {output_handle
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1930 {output_handle
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1933 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1935 if (invalid_table
[i
].win7_crash
)
1938 SetLastError(0xdeadbeef);
1939 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
1940 ret
= WriteConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
1941 invalid_table
[i
].str
,
1942 invalid_table
[i
].length
,
1943 invalid_table
[i
].coord
,
1944 invalid_table
[i
].lpNumCharsWritten
);
1945 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
1946 if (invalid_table
[i
].lpNumCharsWritten
)
1948 ok(count
== invalid_table
[i
].expected_count
,
1949 "[%d] Expected count to be %u, got %u\n",
1950 i
, invalid_table
[i
].expected_count
, count
);
1952 ok(GetLastError() == invalid_table
[i
].last_error
,
1953 "[%d] Expected last error to be %u, got %u\n",
1954 i
, invalid_table
[i
].last_error
, GetLastError());
1958 ret
= WriteConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
1959 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1960 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1963 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 0, origin
, &count
);
1964 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1965 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1968 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 1, origin
, &count
);
1969 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1970 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1973 static void test_WriteConsoleOutputCharacterW(HANDLE output_handle
)
1975 static const WCHAR outputW
[] = {'a',0};
1977 COORD origin
= {0, 0};
1984 HANDLE hConsoleOutput
;
1988 LPDWORD lpNumCharsWritten
;
1989 DWORD expected_count
;
1994 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1995 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1996 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1997 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1998 {NULL
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1999 {NULL
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2000 {NULL
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2001 {NULL
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2002 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2003 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2004 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2005 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2006 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2007 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2008 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2009 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2010 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2011 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2012 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2013 {output_handle
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2014 {output_handle
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2017 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2019 if (invalid_table
[i
].win7_crash
)
2022 SetLastError(0xdeadbeef);
2023 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2024 ret
= WriteConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2025 invalid_table
[i
].str
,
2026 invalid_table
[i
].length
,
2027 invalid_table
[i
].coord
,
2028 invalid_table
[i
].lpNumCharsWritten
);
2029 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2030 if (invalid_table
[i
].lpNumCharsWritten
)
2032 ok(count
== invalid_table
[i
].expected_count
,
2033 "[%d] Expected count to be %u, got %u\n",
2034 i
, invalid_table
[i
].expected_count
, count
);
2036 ok(GetLastError() == invalid_table
[i
].last_error
,
2037 "[%d] Expected last error to be %u, got %u\n",
2038 i
, invalid_table
[i
].last_error
, GetLastError());
2042 ret
= WriteConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2043 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2044 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2047 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 0, origin
, &count
);
2048 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2049 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2052 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 1, origin
, &count
);
2053 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2054 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2057 static void test_WriteConsoleOutputAttribute(HANDLE output_handle
)
2059 WORD attr
= FOREGROUND_BLUE
;
2060 COORD origin
= {0, 0};
2067 HANDLE hConsoleOutput
;
2071 LPDWORD lpNumAttrsWritten
;
2072 DWORD expected_count
;
2077 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2078 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2079 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2080 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2081 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2082 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2083 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2084 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2085 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2086 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2087 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2088 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2089 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2090 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2091 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2092 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2093 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2094 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2095 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2096 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2097 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2100 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2102 if (invalid_table
[i
].win7_crash
)
2105 SetLastError(0xdeadbeef);
2106 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2107 ret
= WriteConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2108 invalid_table
[i
].attr
,
2109 invalid_table
[i
].length
,
2110 invalid_table
[i
].coord
,
2111 invalid_table
[i
].lpNumAttrsWritten
);
2112 ok(!ret
, "[%d] Expected WriteConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2113 if (invalid_table
[i
].lpNumAttrsWritten
)
2115 ok(count
== invalid_table
[i
].expected_count
,
2116 "[%d] Expected count to be %u, got %u\n",
2117 i
, invalid_table
[i
].expected_count
, count
);
2119 ok(GetLastError() == invalid_table
[i
].last_error
,
2120 "[%d] Expected last error to be %u, got %u\n",
2121 i
, invalid_table
[i
].last_error
, GetLastError());
2125 ret
= WriteConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2126 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2127 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2130 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2131 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2132 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2135 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2136 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2137 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2140 static void test_FillConsoleOutputCharacterA(HANDLE output_handle
)
2142 COORD origin
= {0, 0};
2149 HANDLE hConsoleOutput
;
2153 LPDWORD lpNumCharsWritten
;
2158 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2159 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2160 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2161 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2162 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2163 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2164 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2165 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2166 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2167 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2170 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2172 if (invalid_table
[i
].win7_crash
)
2175 SetLastError(0xdeadbeef);
2176 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2177 ret
= FillConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2178 invalid_table
[i
].ch
,
2179 invalid_table
[i
].length
,
2180 invalid_table
[i
].coord
,
2181 invalid_table
[i
].lpNumCharsWritten
);
2182 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2183 ok(GetLastError() == invalid_table
[i
].last_error
,
2184 "[%d] Expected last error to be %u, got %u\n",
2185 i
, invalid_table
[i
].last_error
, GetLastError());
2189 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 0, origin
, &count
);
2190 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2191 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2194 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 1, origin
, &count
);
2195 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2196 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2199 static void test_FillConsoleOutputCharacterW(HANDLE output_handle
)
2201 COORD origin
= {0, 0};
2208 HANDLE hConsoleOutput
;
2212 LPDWORD lpNumCharsWritten
;
2217 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2218 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2219 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2220 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2221 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2222 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2223 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2224 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2225 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2226 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2229 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2231 if (invalid_table
[i
].win7_crash
)
2234 SetLastError(0xdeadbeef);
2235 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2236 ret
= FillConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2237 invalid_table
[i
].ch
,
2238 invalid_table
[i
].length
,
2239 invalid_table
[i
].coord
,
2240 invalid_table
[i
].lpNumCharsWritten
);
2241 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2242 ok(GetLastError() == invalid_table
[i
].last_error
,
2243 "[%d] Expected last error to be %u, got %u\n",
2244 i
, invalid_table
[i
].last_error
, GetLastError());
2248 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 0, origin
, &count
);
2249 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2250 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2253 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 1, origin
, &count
);
2254 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2255 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2258 static void test_FillConsoleOutputAttribute(HANDLE output_handle
)
2260 COORD origin
= {0, 0};
2267 HANDLE hConsoleOutput
;
2271 LPDWORD lpNumAttrsWritten
;
2276 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2277 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2278 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2279 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2280 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2281 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2282 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2283 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2284 {output_handle
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2285 {output_handle
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2288 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2290 if (invalid_table
[i
].win7_crash
)
2293 SetLastError(0xdeadbeef);
2294 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2295 ret
= FillConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2296 invalid_table
[i
].attr
,
2297 invalid_table
[i
].length
,
2298 invalid_table
[i
].coord
,
2299 invalid_table
[i
].lpNumAttrsWritten
);
2300 ok(!ret
, "[%d] Expected FillConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2301 ok(GetLastError() == invalid_table
[i
].last_error
,
2302 "[%d] Expected last error to be %u, got %u\n",
2303 i
, invalid_table
[i
].last_error
, GetLastError());
2307 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 0, origin
, &count
);
2308 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2309 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2312 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 1, origin
, &count
);
2313 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2314 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2317 ret
= FillConsoleOutputAttribute(output_handle
, ~0, 1, origin
, &count
);
2318 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2319 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2322 static void test_ReadConsoleOutputCharacterA(HANDLE output_handle
)
2325 COORD origin
= {0, 0};
2332 HANDLE hConsoleOutput
;
2337 DWORD expected_count
;
2342 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2343 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2344 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2345 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2346 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2347 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2348 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2349 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2350 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2351 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2352 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2353 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2354 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2355 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2356 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2357 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2358 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2359 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2360 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2361 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2362 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2363 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2366 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2368 if (invalid_table
[i
].win7_crash
)
2371 SetLastError(0xdeadbeef);
2372 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2373 ret
= ReadConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2374 invalid_table
[i
].lpstr
,
2375 invalid_table
[i
].length
,
2376 invalid_table
[i
].coord
,
2377 invalid_table
[i
].read_count
);
2378 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2379 if (invalid_table
[i
].read_count
)
2381 ok(count
== invalid_table
[i
].expected_count
,
2382 "[%d] Expected count to be %u, got %u\n",
2383 i
, invalid_table
[i
].expected_count
, count
);
2385 ok(GetLastError() == invalid_table
[i
].last_error
,
2386 "[%d] Expected last error to be %u, got %u\n",
2387 i
, invalid_table
[i
].last_error
, GetLastError());
2391 ret
= ReadConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
2392 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2393 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2396 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 0, origin
, &count
);
2397 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2398 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2401 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 1, origin
, &count
);
2402 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2403 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2406 static void test_ReadConsoleOutputCharacterW(HANDLE output_handle
)
2409 COORD origin
= {0, 0};
2416 HANDLE hConsoleOutput
;
2421 DWORD expected_count
;
2426 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2427 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2428 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2429 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2430 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2431 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2432 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2433 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2434 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2435 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2436 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2437 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2438 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2439 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2440 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2441 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2442 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2443 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2444 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2445 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2446 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2447 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2450 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2452 if (invalid_table
[i
].win7_crash
)
2455 SetLastError(0xdeadbeef);
2456 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2457 ret
= ReadConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2458 invalid_table
[i
].buffer
,
2459 invalid_table
[i
].length
,
2460 invalid_table
[i
].coord
,
2461 invalid_table
[i
].read_count
);
2462 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2463 if (invalid_table
[i
].read_count
)
2465 ok(count
== invalid_table
[i
].expected_count
,
2466 "[%d] Expected count to be %u, got %u\n",
2467 i
, invalid_table
[i
].expected_count
, count
);
2469 ok(GetLastError() == invalid_table
[i
].last_error
,
2470 "[%d] Expected last error to be %u, got %u\n",
2471 i
, invalid_table
[i
].last_error
, GetLastError());
2475 ret
= ReadConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2476 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2477 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2480 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 0, origin
, &count
);
2481 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2482 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2485 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 1, origin
, &count
);
2486 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2487 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2490 static void test_ReadConsoleOutputAttribute(HANDLE output_handle
)
2493 COORD origin
= {0, 0};
2500 HANDLE hConsoleOutput
;
2505 DWORD expected_count
;
2510 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2511 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2512 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2513 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2514 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2515 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2516 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2517 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2518 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2519 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2520 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2521 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2522 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2523 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2524 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2525 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2526 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2527 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2528 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2529 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2530 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2533 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2535 if (invalid_table
[i
].win7_crash
)
2538 SetLastError(0xdeadbeef);
2539 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2540 ret
= ReadConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2541 invalid_table
[i
].lpAttribute
,
2542 invalid_table
[i
].length
,
2543 invalid_table
[i
].coord
,
2544 invalid_table
[i
].read_count
);
2545 ok(!ret
, "[%d] Expected ReadConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2546 if (invalid_table
[i
].read_count
)
2548 ok(count
== invalid_table
[i
].expected_count
,
2549 "[%d] Expected count to be %u, got %u\n",
2550 i
, invalid_table
[i
].expected_count
, count
);
2552 ok(GetLastError() == invalid_table
[i
].last_error
,
2553 "[%d] Expected last error to be %u, got %u\n",
2554 i
, invalid_table
[i
].last_error
, GetLastError());
2558 ret
= ReadConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2559 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2560 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2563 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2564 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2565 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2568 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2569 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2570 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2573 static void test_ReadConsole(void)
2579 std_input
= GetStdHandle(STD_INPUT_HANDLE
);
2581 SetLastError(0xdeadbeef);
2582 ret
= GetFileSize(std_input
, NULL
);
2583 ok(ret
== INVALID_FILE_SIZE
, "expected INVALID_FILE_SIZE, got %#x\n", ret
);
2584 ok(GetLastError() == ERROR_INVALID_HANDLE
||
2585 GetLastError() == ERROR_INVALID_FUNCTION
, /* Win 8, 10 */
2586 "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
2589 SetLastError(0xdeadbeef);
2590 ret
= ReadFile(std_input
, buf
, -128, &bytes
, NULL
);
2591 ok(!ret
, "expected 0, got %u\n", ret
);
2592 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2593 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2594 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2595 ok(!bytes
, "expected 0, got %u\n", bytes
);
2598 SetLastError(0xdeadbeef);
2599 ret
= ReadConsoleA(std_input
, buf
, -128, &bytes
, NULL
);
2600 ok(!ret
, "expected 0, got %u\n", ret
);
2601 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2602 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2603 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2604 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2607 SetLastError(0xdeadbeef);
2608 ret
= ReadConsoleW(std_input
, buf
, -128, &bytes
, NULL
);
2609 ok(!ret
, "expected 0, got %u\n", ret
);
2610 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2611 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2612 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2613 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2616 static void test_GetCurrentConsoleFont(HANDLE std_output
)
2619 CONSOLE_FONT_INFO cfi
;
2620 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2621 short int width
, height
;
2624 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2625 SetLastError(0xdeadbeef);
2626 ret
= GetCurrentConsoleFont(NULL
, FALSE
, &cfi
);
2627 ok(!ret
, "got %d, expected 0\n", ret
);
2628 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2629 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2630 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2632 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2633 SetLastError(0xdeadbeef);
2634 ret
= GetCurrentConsoleFont(NULL
, TRUE
, &cfi
);
2635 ok(!ret
, "got %d, expected 0\n", ret
);
2636 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2637 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2638 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2640 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2641 SetLastError(0xdeadbeef);
2642 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, &cfi
);
2643 ok(!ret
, "got %d, expected 0\n", ret
);
2644 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2645 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2646 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2648 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2649 SetLastError(0xdeadbeef);
2650 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, &cfi
);
2651 ok(!ret
, "got %d, expected 0\n", ret
);
2652 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2653 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2654 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2656 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2657 SetLastError(0xdeadbeef);
2658 ret
= GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2659 ok(ret
, "got %d, expected non-zero\n", ret
);
2660 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2661 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2662 width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
2663 height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
2664 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2665 ok(cfi
.dwFontSize
.X
== width
|| cfi
.dwFontSize
.X
== c
.X
/* Vista and higher */,
2666 "got %d, expected %d\n", cfi
.dwFontSize
.X
, width
);
2667 ok(cfi
.dwFontSize
.Y
== height
|| cfi
.dwFontSize
.Y
== c
.Y
/* Vista and higher */,
2668 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, height
);
2670 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2671 SetLastError(0xdeadbeef);
2672 ret
= GetCurrentConsoleFont(std_output
, TRUE
, &cfi
);
2673 ok(ret
, "got %d, expected non-zero\n", ret
);
2674 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2675 ok(cfi
.dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
,
2676 "got %d, expected %d\n", cfi
.dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
2677 ok(cfi
.dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
,
2678 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
2681 static void test_GetConsoleFontSize(HANDLE std_output
)
2685 CONSOLE_FONT_INFO cfi
;
2687 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2688 LONG font_width
, font_height
;
2690 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2692 memset(&c
, 10, sizeof(COORD
));
2693 SetLastError(0xdeadbeef);
2694 c
= GetConsoleFontSize(NULL
, index
);
2695 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2696 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2697 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2699 memset(&c
, 10, sizeof(COORD
));
2700 SetLastError(0xdeadbeef);
2701 c
= GetConsoleFontSize(GetStdHandle(STD_INPUT_HANDLE
), index
);
2702 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2703 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2704 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2706 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2707 memset(&c
, 10, sizeof(COORD
));
2708 SetLastError(0xdeadbeef);
2709 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2710 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2711 GetClientRect(GetConsoleWindow(), &r
);
2712 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2713 font_width
= (r
.right
- r
.left
+ 1) / csbi
.srWindow
.Right
;
2714 font_height
= (r
.bottom
- r
.top
+ 1) / csbi
.srWindow
.Bottom
;
2715 ok(c
.X
== font_width
, "got %d, expected %d\n", c
.X
, font_width
);
2716 ok(c
.Y
== font_height
, "got %d, expected %d\n", c
.Y
, font_height
);
2718 hmod
= GetModuleHandleA("kernel32.dll");
2719 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2720 if (!pGetNumberOfConsoleFonts
)
2722 win_skip("GetNumberOfConsoleFonts is not available\n");
2725 index
= pGetNumberOfConsoleFonts();
2727 memset(&c
, 10, sizeof(COORD
));
2728 SetLastError(0xdeadbeef);
2729 c
= GetConsoleFontSize(std_output
, index
);
2730 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2731 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2732 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2735 static void test_GetLargestConsoleWindowSize(HANDLE std_output
)
2739 LONG workarea_w
, workarea_h
, maxcon_w
, maxcon_h
;
2740 CONSOLE_SCREEN_BUFFER_INFO sbi
;
2741 CONSOLE_FONT_INFO cfi
;
2745 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2746 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
2748 memset(&c
, 10, sizeof(COORD
));
2749 SetLastError(0xdeadbeef);
2750 c
= GetLargestConsoleWindowSize(NULL
);
2751 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2752 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2753 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2755 memset(&c
, 10, sizeof(COORD
));
2756 SetLastError(0xdeadbeef);
2757 c
= GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE
));
2758 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2759 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2760 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2762 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &r
, 0);
2763 workarea_w
= r
.right
- r
.left
;
2764 workarea_h
= r
.bottom
- r
.top
- GetSystemMetrics(SM_CYCAPTION
);
2766 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2767 index
= cfi
.nFont
; /* save current font index */
2769 hmod
= GetModuleHandleA("kernel32.dll");
2770 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2771 if (!pGetNumberOfConsoleFonts
)
2773 win_skip("GetNumberOfConsoleFonts is not available\n");
2776 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
2777 if (!pSetConsoleFont
)
2779 win_skip("SetConsoleFont is not available\n");
2783 for (i
= 0; i
< pGetNumberOfConsoleFonts(); i
++)
2785 pSetConsoleFont(std_output
, i
);
2786 memset(&c
, 10, sizeof(COORD
));
2787 SetLastError(0xdeadbeef);
2788 c
= GetLargestConsoleWindowSize(std_output
);
2789 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2790 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2791 font
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2792 maxcon_w
= workarea_w
/ font
.X
;
2793 maxcon_h
= workarea_h
/ font
.Y
;
2794 ok(c
.X
== maxcon_w
|| c
.X
== maxcon_w
- 1 /* Win10 */, "got %d, expected %d\n", c
.X
, maxcon_w
);
2795 ok(c
.Y
== maxcon_h
|| c
.Y
== maxcon_h
- 1 /* Win10 */, "got %d, expected %d\n", c
.Y
, maxcon_h
);
2797 ret
= GetConsoleScreenBufferInfo(std_output
, &sbi
);
2798 ok(ret
, "GetConsoleScreenBufferInfo failed %u\n", GetLastError());
2799 ok(sbi
.dwMaximumWindowSize
.X
== min(c
.X
, sbi
.dwSize
.X
), "got %d, expected %d\n",
2800 sbi
.dwMaximumWindowSize
.X
, min(c
.X
, sbi
.dwSize
.X
));
2801 ok(sbi
.dwMaximumWindowSize
.Y
== min(c
.Y
, sbi
.dwSize
.Y
), "got %d, expected %d\n",
2802 sbi
.dwMaximumWindowSize
.Y
, min(c
.Y
, sbi
.dwSize
.Y
));
2804 pSetConsoleFont(std_output
, index
); /* restore original font size */
2807 static void test_GetConsoleFontInfo(HANDLE std_output
)
2810 BOOL (WINAPI
*pGetConsoleFontInfo
)(HANDLE
, BOOL
, DWORD
, CONSOLE_FONT_INFO
*);
2811 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2812 DWORD num_fonts
, index
, i
;
2813 int memsize
, win_width
, win_height
, tmp_w
, tmp_h
;
2814 CONSOLE_FONT_INFO
*cfi
;
2816 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2817 COORD orig_sb_size
, tmp_sb_size
, orig_font
, tmp_font
;
2819 hmod
= GetModuleHandleA("kernel32.dll");
2820 pGetConsoleFontInfo
= (void *)GetProcAddress(hmod
, "GetConsoleFontInfo");
2821 if (!pGetConsoleFontInfo
)
2823 win_skip("GetConsoleFontInfo is not available\n");
2827 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2828 if (!pGetNumberOfConsoleFonts
)
2830 win_skip("GetNumberOfConsoleFonts is not available\n");
2834 num_fonts
= pGetNumberOfConsoleFonts();
2835 memsize
= num_fonts
* sizeof(CONSOLE_FONT_INFO
);
2836 cfi
= HeapAlloc(GetProcessHeap(), 0, memsize
);
2837 memset(cfi
, 0, memsize
);
2839 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2840 orig_sb_size
= csbi
.dwSize
;
2841 tmp_sb_size
.X
= csbi
.dwSize
.X
+ 3;
2842 tmp_sb_size
.Y
= csbi
.dwSize
.Y
+ 5;
2843 SetConsoleScreenBufferSize(std_output
, tmp_sb_size
);
2845 SetLastError(0xdeadbeef);
2846 ret
= pGetConsoleFontInfo(NULL
, FALSE
, 0, cfi
);
2847 ok(!ret
, "got %d, expected zero\n", ret
);
2848 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2850 SetLastError(0xdeadbeef);
2851 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, 0, cfi
);
2852 ok(!ret
, "got %d, expected zero\n", ret
);
2853 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2855 SetLastError(0xdeadbeef);
2856 ret
= pGetConsoleFontInfo(std_output
, FALSE
, 0, cfi
);
2857 ok(!ret
, "got %d, expected zero\n", ret
);
2858 todo_wine
ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2860 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2861 win_width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
2862 win_height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
2864 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
[0]);
2865 index
= cfi
[0].nFont
;
2866 orig_font
= GetConsoleFontSize(std_output
, index
);
2868 memset(cfi
, 0, memsize
);
2869 ret
= pGetConsoleFontInfo(std_output
, FALSE
, num_fonts
, cfi
);
2870 todo_wine
ok(ret
, "got %d, expected non-zero\n", ret
);
2872 todo_wine
ok(cfi
[index
].dwFontSize
.X
== win_width
, "got %d, expected %d\n",
2873 cfi
[index
].dwFontSize
.X
, win_width
);
2874 todo_wine
ok(cfi
[index
].dwFontSize
.Y
== win_height
, "got %d, expected %d\n",
2875 cfi
[index
].dwFontSize
.Y
, win_height
);
2877 for (i
= 0; i
< num_fonts
; i
++)
2879 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %d, expected %d\n", cfi
[i
].nFont
, i
);
2880 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
2881 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* win_width
;
2882 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* win_height
;
2883 todo_wine
ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
2884 todo_wine
ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
2887 SetLastError(0xdeadbeef);
2888 ret
= pGetConsoleFontInfo(NULL
, TRUE
, 0, cfi
);
2889 ok(!ret
, "got %d, expected zero\n", ret
);
2890 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2892 SetLastError(0xdeadbeef);
2893 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, 0, cfi
);
2894 ok(!ret
, "got %d, expected zero\n", ret
);
2895 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2897 SetLastError(0xdeadbeef);
2898 ret
= pGetConsoleFontInfo(std_output
, TRUE
, 0, cfi
);
2899 ok(!ret
, "got %d, expected zero\n", ret
);
2900 todo_wine
ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2902 memset(cfi
, 0, memsize
);
2903 ret
= pGetConsoleFontInfo(std_output
, TRUE
, num_fonts
, cfi
);
2904 todo_wine
ok(ret
, "got %d, expected non-zero\n", ret
);
2906 todo_wine
ok(cfi
[index
].dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
, "got %d, expected %d\n",
2907 cfi
[index
].dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
2908 todo_wine
ok(cfi
[index
].dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
, "got %d, expected %d\n",
2909 cfi
[index
].dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
2911 for (i
= 0; i
< num_fonts
; i
++)
2913 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %d, expected %d\n", cfi
[i
].nFont
, i
);
2914 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
2915 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* csbi
.dwMaximumWindowSize
.X
;
2916 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* csbi
.dwMaximumWindowSize
.Y
;
2917 todo_wine
ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
2918 todo_wine
ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
2921 HeapFree(GetProcessHeap(), 0, cfi
);
2922 SetConsoleScreenBufferSize(std_output
, orig_sb_size
);
2925 static void test_SetConsoleFont(HANDLE std_output
)
2928 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
2930 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2933 hmod
= GetModuleHandleA("kernel32.dll");
2934 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
2935 if (!pSetConsoleFont
)
2937 win_skip("SetConsoleFont is not available\n");
2941 SetLastError(0xdeadbeef);
2942 ret
= pSetConsoleFont(NULL
, 0);
2943 ok(!ret
, "got %d, expected zero\n", ret
);
2944 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2946 SetLastError(0xdeadbeef);
2947 ret
= pSetConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), 0);
2948 ok(!ret
, "got %d, expected zero\n", ret
);
2949 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2951 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2952 if (!pGetNumberOfConsoleFonts
)
2954 win_skip("GetNumberOfConsoleFonts is not available\n");
2958 num_fonts
= pGetNumberOfConsoleFonts();
2960 SetLastError(0xdeadbeef);
2961 ret
= pSetConsoleFont(std_output
, num_fonts
);
2962 ok(!ret
, "got %d, expected zero\n", ret
);
2963 todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2966 static void test_GetConsoleScreenBufferInfoEx(HANDLE std_output
)
2969 BOOL (WINAPI
*pGetConsoleScreenBufferInfoEx
)(HANDLE
, CONSOLE_SCREEN_BUFFER_INFOEX
*);
2970 CONSOLE_SCREEN_BUFFER_INFOEX csbix
;
2972 HANDLE std_input
= GetStdHandle(STD_INPUT_HANDLE
);
2974 hmod
= GetModuleHandleA("kernel32.dll");
2975 pGetConsoleScreenBufferInfoEx
= (void *)GetProcAddress(hmod
, "GetConsoleScreenBufferInfoEx");
2976 if (!pGetConsoleScreenBufferInfoEx
)
2978 win_skip("GetConsoleScreenBufferInfoEx is not available\n");
2982 SetLastError(0xdeadbeef);
2983 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
2984 ok(!ret
, "got %d, expected zero\n", ret
);
2985 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2987 SetLastError(0xdeadbeef);
2988 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
2989 ok(!ret
, "got %d, expected zero\n", ret
);
2990 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2992 SetLastError(0xdeadbeef);
2993 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
2994 ok(!ret
, "got %d, expected zero\n", ret
);
2995 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2997 csbix
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
2999 SetLastError(0xdeadbeef);
3000 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
3001 ok(!ret
, "got %d, expected zero\n", ret
);
3002 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
3004 SetLastError(0xdeadbeef);
3005 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
3006 ok(!ret
, "got %d, expected zero\n", ret
);
3007 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
3009 SetLastError(0xdeadbeef);
3010 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
3011 ok(ret
, "got %d, expected non-zero\n", ret
);
3012 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
3017 static const char font_name
[] = "Lucida Console";
3018 HANDLE hConIn
, hConOut
;
3020 CONSOLE_SCREEN_BUFFER_INFO sbi
;
3023 char old_font
[LF_FACESIZE
];
3024 BOOL
delete = FALSE
;
3027 init_function_pointers();
3029 /* be sure we have a clean console (and that's our own)
3030 * FIXME: this will make the test fail (currently) if we don't run
3032 * Another solution would be to rerun the test under wineconsole with
3033 * the curses backend
3036 /* ReadConsoleOutputW doesn't retrieve characters from the output buffer
3037 * correctly for characters that don't have a glyph in the console font. So,
3038 * we first set the console font to Lucida Console (which has a wider
3039 * selection of glyphs available than the default raster fonts). We want
3040 * to be able to restore the original font afterwards, so don't change
3041 * if we can't read the original font.
3043 err
= RegOpenKeyExA(HKEY_CURRENT_USER
, "Console", 0,
3044 KEY_QUERY_VALUE
| KEY_SET_VALUE
, &console_key
);
3045 if (err
== ERROR_SUCCESS
)
3047 size
= sizeof(old_font
);
3048 err
= RegQueryValueExA(console_key
, "FaceName", NULL
, NULL
,
3049 (LPBYTE
) old_font
, &size
);
3050 if (err
== ERROR_SUCCESS
|| err
== ERROR_FILE_NOT_FOUND
)
3052 delete = (err
== ERROR_FILE_NOT_FOUND
);
3053 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
3054 (const BYTE
*) font_name
, sizeof(font_name
));
3055 if (err
!= ERROR_SUCCESS
)
3056 trace("Unable to change default console font, error %d\n", err
);
3060 trace("Unable to query default console font, error %d\n", err
);
3061 RegCloseKey(console_key
);
3067 trace("Unable to open HKCU\\Console, error %d\n", err
);
3071 /* Now detach and open a fresh console to play with */
3073 ok(AllocConsole(), "Couldn't alloc console\n");
3075 /* Restore default console font if needed */
3076 if (console_key
!= NULL
)
3079 err
= RegDeleteValueA(console_key
, "FaceName");
3081 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
3082 (const BYTE
*) old_font
, strlen(old_font
) + 1);
3083 ok(err
== ERROR_SUCCESS
, "Unable to restore default console font, error %d\n", err
);
3085 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3086 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3088 /* now verify everything's ok */
3089 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
3090 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
3092 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
3093 ok(ret
, "Getting sb info\n");
3096 /* Reduce the size of the buffer to the visible area plus 3 lines to speed
3099 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
);
3100 sbi
.dwSize
.Y
= size
= (sbi
.srWindow
.Bottom
+ 1) + 3;
3101 ret
= SetConsoleScreenBufferSize(hConOut
, sbi
.dwSize
);
3102 ok(ret
, "Setting sb info\n");
3103 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
3104 ok(ret
, "Getting sb info\n");
3105 ok(sbi
.dwSize
.Y
== size
, "Unexpected buffer size: %d instead of %d\n", sbi
.dwSize
.Y
, size
);
3109 /* Non interactive tests */
3110 testCursor(hConOut
, sbi
.dwSize
);
3111 /* test parameters (FIXME: test functionality) */
3112 testCursorInfo(hConOut
);
3113 /* will test wrapped (on/off) & processed (on/off) strings output */
3114 testWrite(hConOut
, sbi
.dwSize
);
3115 /* will test line scrolling at the bottom of the screen */
3116 /* testBottomScroll(); */
3117 /* will test all the scrolling operations */
3118 testScroll(hConOut
, sbi
.dwSize
);
3119 /* will test sb creation / modification / codepage handling */
3120 testScreenBuffer(hConOut
);
3121 /* Test waiting for a console handle */
3122 testWaitForConsoleInput(hConIn
);
3124 /* clear duplicated console font table */
3125 CloseHandle(hConIn
);
3126 CloseHandle(hConOut
);
3128 ok(AllocConsole(), "Couldn't alloc console\n");
3129 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3130 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3131 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
3132 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
3135 /* still to be done: access rights & access on objects */
3137 if (!pGetConsoleInputExeNameA
|| !pSetConsoleInputExeNameA
)
3138 win_skip("GetConsoleInputExeNameA and/or SetConsoleInputExeNameA is not available\n");
3140 test_GetSetConsoleInputExeName();
3142 test_GetConsoleProcessList();
3143 test_OpenConsoleW();
3146 test_VerifyConsoleIoHandle(hConOut
);
3147 test_GetSetStdHandle();
3148 test_GetNumberOfConsoleInputEvents(hConIn
);
3149 test_WriteConsoleInputA(hConIn
);
3150 test_WriteConsoleInputW(hConIn
);
3151 test_WriteConsoleOutputCharacterA(hConOut
);
3152 test_WriteConsoleOutputCharacterW(hConOut
);
3153 test_WriteConsoleOutputAttribute(hConOut
);
3154 test_FillConsoleOutputCharacterA(hConOut
);
3155 test_FillConsoleOutputCharacterW(hConOut
);
3156 test_FillConsoleOutputAttribute(hConOut
);
3157 test_ReadConsoleOutputCharacterA(hConOut
);
3158 test_ReadConsoleOutputCharacterW(hConOut
);
3159 test_ReadConsoleOutputAttribute(hConOut
);
3160 test_GetCurrentConsoleFont(hConOut
);
3161 test_GetConsoleFontSize(hConOut
);
3162 test_GetLargestConsoleWindowSize(hConOut
);
3163 test_GetConsoleFontInfo(hConOut
);
3164 test_SetConsoleFont(hConOut
);
3165 test_GetConsoleScreenBufferInfoEx(hConOut
);