2 * Unit tests for console API
4 * Copyright (c) 2003,2004 Eric Pouech
5 * Copyright (c) 2007 Kirill K. Smirnov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/test.h"
26 static BOOL (WINAPI
*pGetConsoleInputExeNameA
)(DWORD
, LPSTR
);
27 static DWORD (WINAPI
*pGetConsoleProcessList
)(LPDWORD
, DWORD
);
28 static HANDLE (WINAPI
*pOpenConsoleW
)(LPCWSTR
,DWORD
,BOOL
,DWORD
);
29 static BOOL (WINAPI
*pSetConsoleInputExeNameA
)(LPCSTR
);
30 static BOOL (WINAPI
*pVerifyConsoleIoHandle
)(HANDLE handle
);
32 /* DEFAULT_ATTRIB is used for all initial filling of the console.
33 * all modifications are made with TEST_ATTRIB so that we could check
34 * what has to be modified or not
36 #define TEST_ATTRIB (BACKGROUND_BLUE | FOREGROUND_GREEN)
37 #define DEFAULT_ATTRIB (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED)
38 /* when filling the screen with non-blank chars, this macro defines
39 * what character should be at position 'c'
41 #define CONTENT(c) ('A' + (((c).Y * 17 + (c).X) % 23))
43 #define okCURSOR(hCon, c) do { \
44 CONSOLE_SCREEN_BUFFER_INFO __sbi; \
45 BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
46 __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
47 ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
48 (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
51 #define okCHAR(hCon, c, ch, attr) do { \
52 char __ch; WORD __attr; DWORD __len; BOOL expect; \
53 expect = ReadConsoleOutputCharacterA((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \
54 ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x\n", (c).X, (c).Y, (ch), (ch), __ch, __ch); \
55 expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \
56 ok(expect, "At (%d,%d): expecting attr %04x got %04x\n", (c).X, (c).Y, (attr), __attr); \
59 static void init_function_pointers(void)
63 #define KERNEL32_GET_PROC(func) \
64 p##func = (void *)GetProcAddress(hKernel32, #func); \
65 if(!p##func) trace("GetProcAddress(hKernel32, '%s') failed\n", #func);
67 hKernel32
= GetModuleHandleA("kernel32.dll");
68 KERNEL32_GET_PROC(GetConsoleInputExeNameA
);
69 KERNEL32_GET_PROC(GetConsoleProcessList
);
70 KERNEL32_GET_PROC(OpenConsoleW
);
71 KERNEL32_GET_PROC(SetConsoleInputExeNameA
);
72 KERNEL32_GET_PROC(VerifyConsoleIoHandle
);
74 #undef KERNEL32_GET_PROC
77 /* FIXME: this could be optimized on a speed point of view */
78 static void resetContent(HANDLE hCon
, COORD sbSize
, BOOL content
)
81 WORD attr
= DEFAULT_ATTRIB
;
85 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
87 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
89 ch
= (content
) ? CONTENT(c
) : ' ';
90 WriteConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
91 WriteConsoleOutputCharacterA(hCon
, &ch
, 1, c
, &len
);
96 static void testCursor(HANDLE hCon
, COORD sbSize
)
101 ok(SetConsoleCursorPosition(0, c
) == 0, "No handle\n");
102 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
103 ERROR_INVALID_HANDLE
, GetLastError());
106 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
111 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in lower-right\n");
116 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
117 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
118 ERROR_INVALID_PARAMETER
, GetLastError());
122 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
123 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
124 ERROR_INVALID_PARAMETER
, GetLastError());
128 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
129 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
130 ERROR_INVALID_PARAMETER
, GetLastError());
134 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
135 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %u\n",
136 ERROR_INVALID_PARAMETER
, GetLastError());
139 static void testCursorInfo(HANDLE hCon
)
142 CONSOLE_CURSOR_INFO info
;
144 SetLastError(0xdeadbeef);
145 ret
= GetConsoleCursorInfo(NULL
, NULL
);
146 ok(!ret
, "Expected failure\n");
147 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
148 ERROR_INVALID_HANDLE
, GetLastError());
150 SetLastError(0xdeadbeef);
152 ret
= GetConsoleCursorInfo(NULL
, &info
);
153 ok(!ret
, "Expected failure\n");
154 ok(info
.dwSize
== -1, "Expected no change for dwSize\n");
155 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %u\n",
156 ERROR_INVALID_HANDLE
, GetLastError());
158 /* Test the correct call first to distinguish between win9x and the rest */
159 SetLastError(0xdeadbeef);
160 ret
= GetConsoleCursorInfo(hCon
, &info
);
161 ok(ret
, "Expected success\n");
162 ok(info
.dwSize
== 25 ||
163 info
.dwSize
== 12 /* win9x */,
164 "Expected 12 or 25, got %d\n", info
.dwSize
);
165 ok(info
.bVisible
, "Expected the cursor to be visible\n");
166 ok(GetLastError() == 0xdeadbeef, "GetLastError: expecting %u got %u\n",
167 0xdeadbeef, GetLastError());
169 /* Don't test NULL CONSOLE_CURSOR_INFO, it crashes on win9x and win7 */
172 static void testEmptyWrite(HANDLE hCon
)
174 static const char emptybuf
[16];
179 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
182 ok(WriteConsoleA(hCon
, NULL
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
185 /* Passing a NULL lpBuffer with sufficiently large non-zero length succeeds
186 * on native Windows and result in memory-like contents being written to
187 * the console. Calling WriteConsoleW like this will crash on Wine. */
191 ok(!WriteConsoleA(hCon
, NULL
, 16, &len
, NULL
) && len
== -1, "WriteConsole\n");
194 /* Cursor advances for this call. */
196 ok(WriteConsoleA(hCon
, NULL
, 128, &len
, NULL
) != 0 && len
== 128, "WriteConsole\n");
200 ok(WriteConsoleA(hCon
, emptybuf
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
203 /* WriteConsole does not halt on a null terminator and is happy to write
204 * memory contents beyond the actual size of the buffer. */
206 ok(WriteConsoleA(hCon
, emptybuf
, 16, &len
, NULL
) != 0 && len
== 16, "WriteConsole\n");
211 static void testWriteSimple(HANDLE hCon
)
215 const char* mytest
= "abcdefg";
216 const int mylen
= strlen(mytest
);
218 /* single line write */
220 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
222 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
224 for (c
.X
= 0; c
.X
< mylen
; c
.X
++)
226 okCHAR(hCon
, c
, mytest
[c
.X
], TEST_ATTRIB
);
230 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
233 static void testWriteNotWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
237 const char* mytest
= "123";
238 const int mylen
= strlen(mytest
);
242 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
& ~(ENABLE_PROCESSED_OUTPUT
|ENABLE_WRAP_AT_EOL_OUTPUT
)),
243 "clearing wrap at EOL & processed output\n");
245 /* write line, wrapping disabled, buffer exceeds sb width */
246 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
247 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
249 ret
= WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
);
250 ok(ret
!= 0 && len
== mylen
, "Couldn't write, ret = %d, len = %d\n", ret
, len
);
252 for (p
= mylen
- 3; p
< mylen
; p
++)
254 c
.X
= sbSize
.X
- 3 + p
% 3;
255 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
259 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
261 p
= sbSize
.X
- 3 + mylen
% 3;
264 /* write line, wrapping disabled, strings end on end of line */
265 c
.X
= sbSize
.X
- mylen
; c
.Y
= 0;
266 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
268 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
271 static void testWriteNotWrappedProcessed(HANDLE hCon
, COORD sbSize
)
275 const char* mytest
= "abcd\nf\tg";
276 const int mylen
= strlen(mytest
);
277 const int mylen2
= strchr(mytest
, '\n') - mytest
;
281 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, (mode
| ENABLE_PROCESSED_OUTPUT
) & ~ENABLE_WRAP_AT_EOL_OUTPUT
),
282 "clearing wrap at EOL & setting processed output\n");
284 /* write line, wrapping disabled, buffer exceeds sb width */
285 c
.X
= sbSize
.X
- 5; c
.Y
= 0;
286 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-5\n");
288 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
290 for (c
.X
= sbSize
.X
- 5; c
.X
< sbSize
.X
- 1; c
.X
++)
292 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 5], TEST_ATTRIB
);
295 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
296 /* Win9x and WinMe change the attribs for '\n' up to 'f' */
297 if (attr
== TEST_ATTRIB
)
299 win_skip("Win9x/WinMe don't respect ~ENABLE_WRAP_AT_EOL_OUTPUT\n");
303 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
306 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
307 for (c
.X
= 1; c
.X
< 8; c
.X
++)
308 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
309 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
311 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
315 /* write line, wrapping disabled, strings end on end of line */
316 c
.X
= sbSize
.X
- 4; c
.Y
= 0;
317 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
319 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
321 for (c
.X
= sbSize
.X
- 4; c
.X
< sbSize
.X
; c
.X
++)
323 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 4], TEST_ATTRIB
);
326 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
327 for (c
.X
= 1; c
.X
< 8; c
.X
++)
328 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
329 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
331 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
335 /* write line, wrapping disabled, strings end after end of line */
336 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
337 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
339 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
341 for (p
= mylen2
- 3; p
< mylen2
; p
++)
343 c
.X
= sbSize
.X
- 3 + p
% 3;
344 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
347 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
348 for (c
.X
= 1; c
.X
< 8; c
.X
++)
349 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
350 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
352 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
357 static void testWriteWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
361 const char* mytest
= "abcd\nf\tg";
362 const int mylen
= strlen(mytest
);
365 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
,(mode
| ENABLE_WRAP_AT_EOL_OUTPUT
) & ~(ENABLE_PROCESSED_OUTPUT
)),
366 "setting wrap at EOL & clearing processed output\n");
368 /* write line, wrapping enabled, buffer doesn't exceed sb width */
369 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
370 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
372 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
374 for (p
= 0; p
< mylen
; p
++)
376 c
.X
= sbSize
.X
- 9 + p
;
377 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
379 c
.X
= sbSize
.X
- 9 + mylen
;
380 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
382 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
384 /* write line, wrapping enabled, buffer does exceed sb width */
385 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
386 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
390 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
393 static void testWriteWrappedProcessed(HANDLE hCon
, COORD sbSize
)
397 const char* mytest
= "abcd\nf\tg";
398 const int mylen
= strlen(mytest
);
402 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
| (ENABLE_WRAP_AT_EOL_OUTPUT
|ENABLE_PROCESSED_OUTPUT
)),
403 "setting wrap at EOL & processed output\n");
405 /* write line, wrapping enabled, buffer doesn't exceed sb width */
406 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
407 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
409 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
410 for (p
= 0; p
< 4; p
++)
412 c
.X
= sbSize
.X
- 9 + p
;
413 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
415 c
.X
= sbSize
.X
- 9 + p
;
416 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
417 if (attr
== TEST_ATTRIB
)
418 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
420 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
422 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
423 for (c
.X
= 1; c
.X
< 8; c
.X
++)
424 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
425 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
427 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
430 /* write line, wrapping enabled, buffer does exceed sb width */
431 c
.X
= sbSize
.X
- 3; c
.Y
= 2;
432 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
434 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
435 for (p
= 0; p
< 3; p
++)
437 c
.X
= sbSize
.X
- 3 + p
;
438 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
441 okCHAR(hCon
, c
, mytest
[3], TEST_ATTRIB
);
443 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
444 if (attr
== TEST_ATTRIB
)
445 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
447 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
450 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
451 for (c
.X
= 1; c
.X
< 8; c
.X
++)
452 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
453 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
455 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
459 static void testWrite(HANDLE hCon
, COORD sbSize
)
461 /* FIXME: should in fact ensure that the sb is at least 10 characters wide */
462 ok(SetConsoleTextAttribute(hCon
, TEST_ATTRIB
), "Setting default text color\n");
463 resetContent(hCon
, sbSize
, FALSE
);
464 testEmptyWrite(hCon
);
465 resetContent(hCon
, sbSize
, FALSE
);
466 testWriteSimple(hCon
);
467 resetContent(hCon
, sbSize
, FALSE
);
468 testWriteNotWrappedNotProcessed(hCon
, sbSize
);
469 resetContent(hCon
, sbSize
, FALSE
);
470 testWriteNotWrappedProcessed(hCon
, sbSize
);
471 resetContent(hCon
, sbSize
, FALSE
);
472 testWriteWrappedNotProcessed(hCon
, sbSize
);
473 resetContent(hCon
, sbSize
, FALSE
);
474 testWriteWrappedProcessed(hCon
, sbSize
);
477 static void testScroll(HANDLE hCon
, COORD sbSize
)
479 SMALL_RECT scroll
, clip
;
487 #define IN_SRECT(r,c) ((r).Left <= (c).X && (c).X <= (r).Right && (r).Top <= (c).Y && (c).Y <= (r).Bottom)
488 #define IN_SRECT2(r,d,c) ((d).X <= (c).X && (c).X <= (d).X + (r).Right - (r).Left && (d).Y <= (c).Y && (c).Y <= (d).Y + (r).Bottom - (r).Top)
490 /* no clipping, src & dst rect don't overlap */
491 resetContent(hCon
, sbSize
, TRUE
);
494 scroll
.Right
= W
- 1;
496 scroll
.Bottom
= H
- 1;
499 ci
.Char
.UnicodeChar
= '#';
500 ci
.Attributes
= TEST_ATTRIB
;
503 clip
.Right
= sbSize
.X
- 1;
505 clip
.Bottom
= sbSize
.Y
- 1;
507 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
509 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
511 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
513 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
517 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
519 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
520 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
521 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
525 /* no clipping, src & dst rect do overlap */
526 resetContent(hCon
, sbSize
, TRUE
);
529 scroll
.Right
= W
- 1;
531 scroll
.Bottom
= H
- 1;
534 ci
.Char
.UnicodeChar
= '#';
535 ci
.Attributes
= TEST_ATTRIB
;
538 clip
.Right
= sbSize
.X
- 1;
540 clip
.Bottom
= sbSize
.Y
- 1;
542 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
544 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
546 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
548 if (dst
.X
<= c
.X
&& c
.X
< dst
.X
+ W
&& dst
.Y
<= c
.Y
&& c
.Y
< dst
.Y
+ H
)
552 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
554 else if (c
.X
< W
&& c
.Y
< H
) okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
555 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
559 /* clipping, src & dst rect don't overlap */
560 resetContent(hCon
, sbSize
, TRUE
);
563 scroll
.Right
= W
- 1;
565 scroll
.Bottom
= H
- 1;
568 ci
.Char
.UnicodeChar
= '#';
569 ci
.Attributes
= TEST_ATTRIB
;
572 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
574 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
576 SetLastError(0xdeadbeef);
577 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
);
580 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
582 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
584 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
588 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
590 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
591 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
592 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
598 /* Win9x will fail, Only accept ERROR_NOT_ENOUGH_MEMORY */
599 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
,
600 "Expected ERROR_NOT_ENOUGH_MEMORY, got %u\n", GetLastError());
603 /* clipping, src & dst rect do overlap */
604 resetContent(hCon
, sbSize
, TRUE
);
607 scroll
.Right
= W
- 1;
609 scroll
.Bottom
= H
- 1;
612 ci
.Char
.UnicodeChar
= '#';
613 ci
.Attributes
= TEST_ATTRIB
;
616 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
618 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
620 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
), "Scrolling SB\n");
622 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
624 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
626 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
630 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
632 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
633 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
634 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
639 static int mch_count
;
640 /* we need the event as Wine console event generation isn't synchronous
641 * (ie GenerateConsoleCtrlEvent returns before all ctrl-handlers in all
642 * processes have been called).
644 static HANDLE mch_event
;
645 static BOOL WINAPI
mch(DWORD event
)
652 static void testCtrlHandler(void)
654 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
655 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
656 ok(SetConsoleCtrlHandler(mch
, TRUE
), "Couldn't set handler\n");
657 /* wine requires the event for the test, as we cannot ensure, so far, that
658 * events are processed synchronously in GenerateConsoleCtrlEvent()
660 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
662 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
663 /* FIXME: it isn't synchronous on wine but it can still happen before we test */
664 if (0) ok(mch_count
== 1, "Event isn't synchronous\n");
665 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_OBJECT_0
, "event sending didn't work\n");
666 CloseHandle(mch_event
);
668 /* Turning off ctrl-c handling doesn't work on win9x such way ... */
669 ok(SetConsoleCtrlHandler(NULL
, TRUE
), "Couldn't turn off ctrl-c handling\n");
670 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
672 if(!(GetVersion() & 0x80000000))
673 /* ... and next line leads to an unhandled exception on 9x. Avoid it on 9x. */
674 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
675 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_TIMEOUT
&& mch_count
== 0, "Event shouldn't have been sent\n");
676 CloseHandle(mch_event
);
677 ok(SetConsoleCtrlHandler(mch
, FALSE
), "Couldn't remove handler\n");
678 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
679 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %u\n", GetLastError());
683 * Test console screen buffer:
684 * 1) Try to set invalid handle.
685 * 2) Try to set non-console handles.
686 * 3) Use CONOUT$ file as active SB.
688 * 5) Test output codepage to show it is not a property of SB.
689 * 6) Test switching to old SB if we close all handles to current SB - works
690 * in Windows, TODO in wine.
692 * What is not tested but should be:
693 * 1) ScreenBufferInfo
695 static void testScreenBuffer(HANDLE hConOut
)
697 HANDLE hConOutRW
, hConOutRO
, hConOutWT
;
698 HANDLE hFileOutRW
, hFileOutRO
, hFileOutWT
;
700 char test_str1
[] = "Test for SB1";
701 char test_str2
[] = "Test for SB2";
702 char test_cp866
[] = {0xe2, 0xa5, 0xe1, 0xe2, 0};
703 char test_cp1251
[] = {0xf2, 0xe5, 0xf1, 0xf2, 0};
704 WCHAR test_unicode
[] = {0x0442, 0x0435, 0x0441, 0x0442, 0};
712 if (!IsValidCodePage(866))
714 skip("Codepage 866 not available\n");
718 /* In the beginning set output codepage to 866 */
719 oldcp
= GetConsoleOutputCP();
720 SetLastError(0xdeadbeef);
721 ret
= SetConsoleOutputCP(866);
722 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
724 win_skip("SetConsoleOutputCP is not implemented\n");
727 ok(ret
, "Cannot set output codepage to 866\n");
729 hConOutRW
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
730 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
731 CONSOLE_TEXTMODE_BUFFER
, NULL
);
732 ok(hConOutRW
!= INVALID_HANDLE_VALUE
,
733 "Cannot create a new screen buffer for ReadWrite\n");
734 hConOutRO
= CreateConsoleScreenBuffer(GENERIC_READ
,
735 FILE_SHARE_READ
, NULL
,
736 CONSOLE_TEXTMODE_BUFFER
, NULL
);
737 ok(hConOutRO
!= INVALID_HANDLE_VALUE
,
738 "Cannot create a new screen buffer for ReadOnly\n");
739 hConOutWT
= CreateConsoleScreenBuffer(GENERIC_WRITE
,
740 FILE_SHARE_WRITE
, NULL
,
741 CONSOLE_TEXTMODE_BUFFER
, NULL
);
742 ok(hConOutWT
!= INVALID_HANDLE_VALUE
,
743 "Cannot create a new screen buffer for WriteOnly\n");
745 hFileOutRW
= CreateFileA("NUL", GENERIC_READ
| GENERIC_WRITE
,
746 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
747 OPEN_EXISTING
, 0, NULL
);
748 ok(hFileOutRW
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadWrite\n");
749 hFileOutRO
= CreateFileA("NUL", GENERIC_READ
, FILE_SHARE_READ
,
750 NULL
, OPEN_EXISTING
, 0, NULL
);
751 ok(hFileOutRO
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadOnly\n");
752 hFileOutWT
= CreateFileA("NUL", GENERIC_WRITE
, FILE_SHARE_WRITE
,
753 NULL
, OPEN_EXISTING
, 0, NULL
);
754 ok(hFileOutWT
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for WriteOnly\n");
756 /* Trying to set invalid handle */
758 ok(!SetConsoleActiveScreenBuffer(INVALID_HANDLE_VALUE
),
759 "Shouldn't succeed\n");
760 ok(GetLastError() == ERROR_INVALID_HANDLE
,
761 "GetLastError: expecting %u got %u\n",
762 ERROR_INVALID_HANDLE
, GetLastError());
764 /* Trying to set non-console handles */
766 ok(!SetConsoleActiveScreenBuffer(hFileOutRW
), "Shouldn't succeed\n");
767 ok(GetLastError() == ERROR_INVALID_HANDLE
,
768 "GetLastError: expecting %u got %u\n",
769 ERROR_INVALID_HANDLE
, GetLastError());
772 ok(!SetConsoleActiveScreenBuffer(hFileOutRO
), "Shouldn't succeed\n");
773 ok(GetLastError() == ERROR_INVALID_HANDLE
,
774 "GetLastError: expecting %u got %u\n",
775 ERROR_INVALID_HANDLE
, GetLastError());
778 ok(!SetConsoleActiveScreenBuffer(hFileOutWT
), "Shouldn't succeed\n");
779 ok(GetLastError() == ERROR_INVALID_HANDLE
,
780 "GetLastError: expecting %u got %u\n",
781 ERROR_INVALID_HANDLE
, GetLastError());
783 /* trying to write non-console handle */
784 SetLastError(0xdeadbeef);
785 ret
= WriteConsoleA(hFileOutRW
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
786 error
= GetLastError();
787 ok(!ret
, "Shouldn't succeed\n");
788 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
789 "GetLastError: got %u\n", error
);
791 SetLastError(0xdeadbeef);
792 ret
= WriteConsoleA(hFileOutRO
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
793 error
= GetLastError();
794 ok(!ret
, "Shouldn't succeed\n");
795 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
796 "GetLastError: got %u\n", error
);
798 SetLastError(0xdeadbeef);
799 ret
= WriteConsoleA(hFileOutWT
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
800 error
= GetLastError();
801 ok(!ret
, "Shouldn't succeed\n");
802 todo_wine
ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
803 "GetLastError: got %u\n", error
);
805 CloseHandle(hFileOutRW
);
806 CloseHandle(hFileOutRO
);
807 CloseHandle(hFileOutWT
);
809 /* Trying to set SB handles with various access modes */
811 ok(!SetConsoleActiveScreenBuffer(hConOutRO
), "Shouldn't succeed\n");
812 ok(GetLastError() == ERROR_INVALID_HANDLE
,
813 "GetLastError: expecting %u got %u\n",
814 ERROR_INVALID_HANDLE
, GetLastError());
816 ok(SetConsoleActiveScreenBuffer(hConOutWT
), "Couldn't set new WriteOnly SB\n");
818 ok(SetConsoleActiveScreenBuffer(hConOutRW
), "Couldn't set new ReadWrite SB\n");
820 CloseHandle(hConOutWT
);
821 CloseHandle(hConOutRO
);
823 /* Now we have two ReadWrite SB, active must be hConOutRW */
824 /* Open current SB via CONOUT$ */
825 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
826 NULL
, OPEN_EXISTING
, 0, 0);
827 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
832 SetConsoleCursorPosition(hConOut
, c
);
834 SetConsoleCursorPosition(hConOutRW
, c
);
835 okCURSOR(hConOutNew
, c
);
837 okCURSOR(hConOut
, c
);
842 /* Write using hConOutNew... */
843 SetConsoleCursorPosition(hConOutNew
, c
);
844 ret
= WriteConsoleA(hConOutNew
, test_str2
, lstrlenA(test_str2
), &len
, NULL
);
845 ok (ret
&& len
== lstrlenA(test_str2
), "WriteConsoleA failed\n");
846 /* ... and read it back via hConOutRW */
847 ret
= ReadConsoleOutputCharacterA(hConOutRW
, str_buf
, lstrlenA(test_str2
), c
, &len
);
848 ok(ret
&& len
== lstrlenA(test_str2
), "ReadConsoleOutputCharacterA failed\n");
849 str_buf
[lstrlenA(test_str2
)] = 0;
850 ok(!lstrcmpA(str_buf
, test_str2
), "got '%s' expected '%s'\n", str_buf
, test_str2
);
853 /* Now test output codepage handling. Current is 866 as we set earlier. */
854 SetConsoleCursorPosition(hConOutRW
, c
);
855 ret
= WriteConsoleA(hConOutRW
, test_cp866
, lstrlenA(test_cp866
), &len
, NULL
);
856 ok(ret
&& len
== lstrlenA(test_cp866
), "WriteConsoleA failed\n");
857 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp866
), c
, &len
);
858 ok(ret
&& len
== lstrlenA(test_cp866
), "ReadConsoleOutputCharacterW failed\n");
859 str_wbuf
[lstrlenA(test_cp866
)] = 0;
860 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
863 * cp866 is OK, let's switch to cp1251.
864 * We expect that this codepage will be used in every SB - active and not.
866 ok(SetConsoleOutputCP(1251), "Cannot set output cp to 1251\n");
867 SetConsoleCursorPosition(hConOutRW
, c
);
868 ret
= WriteConsoleA(hConOutRW
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
869 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
870 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
871 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
872 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
873 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
875 /* Check what has happened to hConOut. */
876 SetConsoleCursorPosition(hConOut
, c
);
877 ret
= WriteConsoleA(hConOut
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
878 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
879 ret
= ReadConsoleOutputCharacterW(hConOut
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
880 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
881 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
882 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
884 /* Close all handles of current console SB */
885 CloseHandle(hConOutNew
);
886 CloseHandle(hConOutRW
);
888 /* Now active SB should be hConOut */
889 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
890 NULL
, OPEN_EXISTING
, 0, 0);
891 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
893 /* Write using hConOutNew... */
894 SetConsoleCursorPosition(hConOutNew
, c
);
895 ret
= WriteConsoleA(hConOutNew
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
896 ok (ret
&& len
== lstrlenA(test_str1
), "WriteConsoleA failed\n");
897 /* ... and read it back via hConOut */
898 ret
= ReadConsoleOutputCharacterA(hConOut
, str_buf
, lstrlenA(test_str1
), c
, &len
);
899 ok(ret
&& len
== lstrlenA(test_str1
), "ReadConsoleOutputCharacterA failed\n");
900 str_buf
[lstrlenA(test_str1
)] = 0;
901 todo_wine
ok(!lstrcmpA(str_buf
, test_str1
), "got '%s' expected '%s'\n", str_buf
, test_str1
);
902 CloseHandle(hConOutNew
);
904 /* This is not really needed under Windows */
905 SetConsoleActiveScreenBuffer(hConOut
);
907 /* restore codepage */
908 SetConsoleOutputCP(oldcp
);
911 static void CALLBACK
signaled_function(void *p
, BOOLEAN timeout
)
915 ok(!timeout
, "wait shouldn't have timed out\n");
918 static void testWaitForConsoleInput(HANDLE input_handle
)
921 HANDLE complete_event
;
923 DWORD events_written
;
927 complete_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
929 /* Test success case */
930 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
931 ok(ret
== TRUE
, "Expected RegisterWaitForSingleObject to return TRUE, got %d\n", ret
);
932 /* give worker thread a chance to start up */
934 record
.EventType
= KEY_EVENT
;
935 record
.Event
.KeyEvent
.bKeyDown
= 1;
936 record
.Event
.KeyEvent
.wRepeatCount
= 1;
937 record
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
938 record
.Event
.KeyEvent
.wVirtualScanCode
= VK_RETURN
;
939 record
.Event
.KeyEvent
.uChar
.UnicodeChar
= '\r';
940 record
.Event
.KeyEvent
.dwControlKeyState
= 0;
941 ret
= WriteConsoleInputW(input_handle
, &record
, 1, &events_written
);
942 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
943 wait_ret
= WaitForSingleObject(complete_event
, INFINITE
);
944 ok(wait_ret
== WAIT_OBJECT_0
, "Expected the handle to be signaled\n");
945 ret
= UnregisterWait(wait_handle
);
946 /* If the callback is still running, this fails with ERROR_IO_PENDING, but
947 that's ok and expected. */
948 ok(ret
!= 0 || GetLastError() == ERROR_IO_PENDING
,
949 "UnregisterWait failed with error %d\n", GetLastError());
951 /* Test timeout case */
952 FlushConsoleInputBuffer(input_handle
);
953 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
954 wait_ret
= WaitForSingleObject(complete_event
, 100);
955 ok(wait_ret
== WAIT_TIMEOUT
, "Expected the wait to time out\n");
956 ret
= UnregisterWait(wait_handle
);
957 ok(ret
, "UnregisterWait failed with error %d\n", GetLastError());
960 CloseHandle(complete_event
);
963 static void test_GetSetConsoleInputExeName(void)
967 char buffer
[MAX_PATH
], module
[MAX_PATH
], *p
;
968 static char input_exe
[MAX_PATH
] = "winetest.exe";
970 SetLastError(0xdeadbeef);
971 ret
= pGetConsoleInputExeNameA(0, NULL
);
972 error
= GetLastError();
973 ok(ret
, "GetConsoleInputExeNameA failed\n");
974 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
976 SetLastError(0xdeadbeef);
977 ret
= pGetConsoleInputExeNameA(0, buffer
);
978 error
= GetLastError();
979 ok(ret
, "GetConsoleInputExeNameA failed\n");
980 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %u expected ERROR_BUFFER_OVERFLOW\n", error
);
982 GetModuleFileNameA(GetModuleHandleA(NULL
), module
, sizeof(module
));
983 p
= strrchr(module
, '\\') + 1;
985 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
986 ok(ret
, "GetConsoleInputExeNameA failed\n");
987 todo_wine
ok(!lstrcmpA(buffer
, p
), "got %s expected %s\n", buffer
, p
);
989 SetLastError(0xdeadbeef);
990 ret
= pSetConsoleInputExeNameA(NULL
);
991 error
= GetLastError();
992 ok(!ret
, "SetConsoleInputExeNameA failed\n");
993 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
995 SetLastError(0xdeadbeef);
996 ret
= pSetConsoleInputExeNameA("");
997 error
= GetLastError();
998 ok(!ret
, "SetConsoleInputExeNameA failed\n");
999 ok(error
== ERROR_INVALID_PARAMETER
, "got %u expected ERROR_INVALID_PARAMETER\n", error
);
1001 ret
= pSetConsoleInputExeNameA(input_exe
);
1002 ok(ret
, "SetConsoleInputExeNameA failed\n");
1004 ret
= pGetConsoleInputExeNameA(sizeof(buffer
)/sizeof(buffer
[0]), buffer
);
1005 ok(ret
, "GetConsoleInputExeNameA failed\n");
1006 ok(!lstrcmpA(buffer
, input_exe
), "got %s expected %s\n", buffer
, input_exe
);
1009 static void test_GetConsoleProcessList(void)
1011 DWORD ret
, *list
= NULL
;
1013 if (!pGetConsoleProcessList
)
1015 win_skip("GetConsoleProcessList is not available\n");
1019 SetLastError(0xdeadbeef);
1020 ret
= pGetConsoleProcessList(NULL
, 0);
1021 ok(ret
== 0, "Expected failure\n");
1022 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1023 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1026 SetLastError(0xdeadbeef);
1027 ret
= pGetConsoleProcessList(NULL
, 1);
1028 ok(ret
== 0, "Expected failure\n");
1029 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1030 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1033 /* We should only have 1 process but only for these specific unit tests as
1034 * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS) would
1035 * give us two processes for example.
1037 list
= HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD
));
1039 SetLastError(0xdeadbeef);
1040 ret
= pGetConsoleProcessList(list
, 0);
1041 ok(ret
== 0, "Expected failure\n");
1042 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1043 "Expected ERROR_INVALID_PARAMETER, got %d\n",
1046 SetLastError(0xdeadbeef);
1047 ret
= pGetConsoleProcessList(list
, 1);
1049 ok(ret
== 1, "Expected 1, got %d\n", ret
);
1051 HeapFree(GetProcessHeap(), 0, list
);
1053 list
= HeapAlloc(GetProcessHeap(), 0, ret
* sizeof(DWORD
));
1055 SetLastError(0xdeadbeef);
1056 ret
= pGetConsoleProcessList(list
, ret
);
1058 ok(ret
== 1, "Expected 1, got %d\n", ret
);
1062 DWORD pid
= GetCurrentProcessId();
1063 ok(list
[0] == pid
, "Expected %d, got %d\n", pid
, list
[0]);
1066 HeapFree(GetProcessHeap(), 0, list
);
1069 static void test_OpenCON(void)
1071 static const WCHAR conW
[] = {'C','O','N',0};
1072 static const DWORD accesses
[] = {CREATE_NEW
, CREATE_ALWAYS
, OPEN_EXISTING
,
1073 OPEN_ALWAYS
, TRUNCATE_EXISTING
};
1077 for (i
= 0; i
< sizeof(accesses
) / sizeof(accesses
[0]); i
++)
1079 h
= CreateFileW(conW
, GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1080 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win8 */),
1081 "Expected to open the CON device on write (%x)\n", accesses
[i
]);
1084 h
= CreateFileW(conW
, GENERIC_READ
, 0, NULL
, accesses
[i
], 0, NULL
);
1085 /* Windows versions differ here:
1086 * MSDN states in CreateFile that TRUNCATE_EXISTING requires GENERIC_WRITE
1087 * NT, XP, Vista comply, but Win7 doesn't and allows opening CON with TRUNCATE_EXISTING
1088 * So don't test when disposition is TRUNCATE_EXISTING
1090 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win7+ */),
1091 "Expected to open the CON device on read (%x)\n", accesses
[i
]);
1093 h
= CreateFileW(conW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1094 ok(h
== INVALID_HANDLE_VALUE
, "Expected not to open the CON device on read-write (%x)\n", accesses
[i
]);
1095 ok(GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1096 "Unexpected error %x\n", GetLastError());
1100 static void test_OpenConsoleW(void)
1102 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1103 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1104 static const WCHAR emptyW
[] = {0};
1105 static const WCHAR invalidW
[] = {'I','N','V','A','L','I','D',0};
1115 } invalid_table
[] = {
1116 {NULL
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1117 {NULL
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1118 {NULL
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1119 {NULL
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1120 {NULL
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1121 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1122 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1123 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1124 {emptyW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1125 {emptyW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1126 {emptyW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1127 {emptyW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1128 {emptyW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1129 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1130 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1131 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1132 {invalidW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1133 {invalidW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1134 {invalidW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1135 {invalidW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1136 {invalidW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1137 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1138 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1139 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1140 {coninW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1141 {coninW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1142 {coninW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1143 {conoutW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1144 {conoutW
, 0xceadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1145 {conoutW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1154 {coninW
, 0, FALSE
, 0 },
1155 {coninW
, 0, TRUE
, 0 },
1156 {coninW
, GENERIC_EXECUTE
, TRUE
, 0 },
1157 {coninW
, GENERIC_ALL
, TRUE
, 0 },
1158 {coninW
, 0, FALSE
, OPEN_ALWAYS
},
1159 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1160 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
},
1161 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1162 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1163 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1164 {conoutW
, 0, FALSE
, 0 },
1165 {conoutW
, 0, FALSE
, OPEN_ALWAYS
},
1166 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1167 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, },
1168 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1169 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1170 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1178 win_skip("OpenConsoleW is not available\n");
1182 for (index
= 0; index
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); index
++)
1184 SetLastError(0xdeadbeef);
1185 ret
= pOpenConsoleW(invalid_table
[index
].name
, invalid_table
[index
].access
,
1186 invalid_table
[index
].inherit
, invalid_table
[index
].creation
);
1187 gle
= GetLastError();
1188 ok(ret
== INVALID_HANDLE_VALUE
,
1189 "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
1191 ok(gle
== invalid_table
[index
].gle
|| (gle
!= 0 && gle
== invalid_table
[index
].gle2
),
1192 "Expected GetLastError() to return %u/%u for index %d, got %u\n",
1193 invalid_table
[index
].gle
, invalid_table
[index
].gle2
, index
, gle
);
1196 for (index
= 0; index
< sizeof(valid_table
)/sizeof(valid_table
[0]); index
++)
1198 ret
= pOpenConsoleW(valid_table
[index
].name
, valid_table
[index
].access
,
1199 valid_table
[index
].inherit
, valid_table
[index
].creation
);
1201 ok(ret
!= INVALID_HANDLE_VALUE
|| broken(ret
== INVALID_HANDLE_VALUE
/* until Win7 */),
1202 "Expected OpenConsoleW to succeed for index %d, got %p\n", index
, ret
);
1203 if (ret
!= INVALID_HANDLE_VALUE
)
1207 ret
= pOpenConsoleW(coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1208 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1209 if (ret
!= INVALID_HANDLE_VALUE
)
1212 ret
= pOpenConsoleW(conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1213 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1214 if (ret
!= INVALID_HANDLE_VALUE
)
1218 static void test_CreateFileW(void)
1220 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1221 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1232 {coninW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1233 {coninW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1234 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1235 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1236 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1237 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1238 {conoutW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1239 {conoutW
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1240 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1241 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1242 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1243 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1244 /* TRUNCATE_EXISTING is forbidden starting with Windows 8 */
1249 SECURITY_ATTRIBUTES sa
;
1251 for (index
= 0; index
< sizeof(cf_table
)/sizeof(cf_table
[0]); index
++)
1253 SetLastError(0xdeadbeef);
1255 sa
.nLength
= sizeof(sa
);
1256 sa
.lpSecurityDescriptor
= NULL
;
1257 sa
.bInheritHandle
= cf_table
[index
].inherit
;
1259 ret
= CreateFileW(cf_table
[index
].name
, cf_table
[index
].access
,
1260 FILE_SHARE_READ
|FILE_SHARE_WRITE
, &sa
,
1261 cf_table
[index
].creation
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1262 if (ret
== INVALID_HANDLE_VALUE
)
1264 ok(cf_table
[index
].gle
,
1265 "Expected CreateFileW not to return INVALID_HANDLE_VALUE for index %d\n", index
);
1266 ok(GetLastError() == cf_table
[index
].gle
,
1267 "Expected GetLastError() to return %u for index %d, got %u\n",
1268 cf_table
[index
].gle
, index
, GetLastError());
1272 ok(!cf_table
[index
].gle
|| broken(cf_table
[index
].is_broken
) /* Win7 */,
1273 "Expected CreateFileW to succeed for index %d\n", index
);
1279 static void test_VerifyConsoleIoHandle( HANDLE handle
)
1284 if (!pVerifyConsoleIoHandle
)
1286 win_skip("VerifyConsoleIoHandle is not available\n");
1290 /* invalid handle */
1291 SetLastError(0xdeadbeef);
1292 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee0);
1293 error
= GetLastError();
1294 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1295 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1297 /* invalid handle + 1 */
1298 SetLastError(0xdeadbeef);
1299 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee1);
1300 error
= GetLastError();
1301 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1302 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1304 /* invalid handle + 2 */
1305 SetLastError(0xdeadbeef);
1306 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee2);
1307 error
= GetLastError();
1308 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1309 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1311 /* invalid handle + 3 */
1312 SetLastError(0xdeadbeef);
1313 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee3);
1314 error
= GetLastError();
1315 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1316 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1319 SetLastError(0xdeadbeef);
1320 ret
= pVerifyConsoleIoHandle(handle
);
1321 error
= GetLastError();
1323 broken(!ret
), /* Windows 8 and 10 */
1324 "expected VerifyConsoleIoHandle to succeed\n");
1325 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1328 static void test_GetSetStdHandle(void)
1334 /* get invalid std handle */
1335 SetLastError(0xdeadbeef);
1336 handle
= GetStdHandle(42);
1337 error
= GetLastError();
1338 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1339 "wrong GetLastError() %d\n", error
);
1340 ok(handle
== INVALID_HANDLE_VALUE
, "expected INVALID_HANDLE_VALUE\n");
1343 SetLastError(0xdeadbeef);
1344 handle
= GetStdHandle(STD_INPUT_HANDLE
);
1345 error
= GetLastError();
1346 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1348 /* set invalid std handle */
1349 SetLastError(0xdeadbeef);
1350 ret
= SetStdHandle(42, handle
);
1351 error
= GetLastError();
1352 ok(!ret
, "expected SetStdHandle to fail\n");
1353 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1354 "wrong GetLastError() %d\n", error
);
1356 /* set valid (restore old value) */
1357 SetLastError(0xdeadbeef);
1358 ret
= SetStdHandle(STD_INPUT_HANDLE
, handle
);
1359 error
= GetLastError();
1360 ok(ret
, "expected SetStdHandle to succeed\n");
1361 ok(error
== 0xdeadbeef, "wrong GetLastError() %d\n", error
);
1364 static void test_GetNumberOfConsoleInputEvents(HANDLE input_handle
)
1377 {NULL
, NULL
, ERROR_INVALID_HANDLE
},
1378 {NULL
, &count
, ERROR_INVALID_HANDLE
},
1379 {INVALID_HANDLE_VALUE
, NULL
, ERROR_INVALID_HANDLE
},
1380 {INVALID_HANDLE_VALUE
, &count
, ERROR_INVALID_HANDLE
},
1383 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1385 SetLastError(0xdeadbeef);
1386 if (invalid_table
[i
].nrofevents
) count
= 0xdeadbeef;
1387 ret
= GetNumberOfConsoleInputEvents(invalid_table
[i
].handle
,
1388 invalid_table
[i
].nrofevents
);
1389 ok(!ret
, "[%d] Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", i
, ret
);
1390 if (invalid_table
[i
].nrofevents
)
1392 ok(count
== 0xdeadbeef,
1393 "[%d] Expected output count to be unmodified, got %u\n", i
, count
);
1395 ok(GetLastError() == invalid_table
[i
].last_error
,
1396 "[%d] Expected last error to be %u, got %u\n",
1397 i
, invalid_table
[i
].last_error
, GetLastError());
1400 /* Test crashes on Windows 7. */
1403 SetLastError(0xdeadbeef);
1404 ret
= GetNumberOfConsoleInputEvents(input_handle
, NULL
);
1405 ok(!ret
, "Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", ret
);
1406 ok(GetLastError() == ERROR_INVALID_ACCESS
,
1407 "Expected last error to be ERROR_INVALID_ACCESS, got %u\n",
1412 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1413 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1414 ok(count
!= 0xdeadbeef, "Expected output count to initialized\n");
1417 static void test_WriteConsoleInputA(HANDLE input_handle
)
1420 INPUT_RECORD event_list
[5];
1421 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1422 KEY_EVENT_RECORD key_event
;
1423 DWORD count
, console_mode
, gle
;
1430 const INPUT_RECORD
*buffer
;
1437 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1438 {NULL
, NULL
, 0, &count
,ERROR_INVALID_HANDLE
},
1439 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1440 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1441 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1442 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1443 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1444 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1445 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1446 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1447 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1448 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1449 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1450 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1451 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1452 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1453 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1454 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1455 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1456 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1457 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1460 /* Suppress external sources of input events for the duration of the test. */
1461 ret
= GetConsoleMode(input_handle
, &console_mode
);
1462 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1465 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1469 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1470 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1473 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1477 /* Discard any events queued before the tests. */
1478 ret
= FlushConsoleInputBuffer(input_handle
);
1479 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1481 event
.EventType
= MOUSE_EVENT
;
1482 event
.Event
.MouseEvent
= mouse_event
;
1484 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1486 if (invalid_table
[i
].win_crash
)
1489 SetLastError(0xdeadbeef);
1490 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1491 ret
= WriteConsoleInputA(invalid_table
[i
].handle
,
1492 invalid_table
[i
].buffer
,
1493 invalid_table
[i
].count
,
1494 invalid_table
[i
].written
);
1495 ok(!ret
, "[%d] Expected WriteConsoleInputA to return FALSE, got %d\n", i
, ret
);
1496 gle
= GetLastError();
1497 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1498 "[%d] Expected last error to be %u or %u, got %u\n",
1499 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1503 ret
= WriteConsoleInputA(input_handle
, NULL
, 0, &count
);
1504 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1505 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1508 ret
= WriteConsoleInputA(input_handle
, &event
, 0, &count
);
1509 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1510 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1513 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1514 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1515 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1517 ret
= FlushConsoleInputBuffer(input_handle
);
1518 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1520 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1521 event
.EventType
= MOUSE_EVENT
;
1522 event
.Event
.MouseEvent
= mouse_event
;
1524 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1525 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1526 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1528 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1529 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1530 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1532 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1533 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1534 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1536 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1537 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1539 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1541 ret
= FlushConsoleInputBuffer(input_handle
);
1542 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1544 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1546 event_list
[i
].EventType
= MOUSE_EVENT
;
1547 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1550 /* Writing consecutive chunks of mouse events appears to work. */
1551 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1552 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1553 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1554 "Expected count to be event list length, got %u\n", count
);
1556 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1557 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1558 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1559 "Expected count to be event list length, got %u\n", count
);
1561 ret
= WriteConsoleInputA(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1562 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1563 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1564 "Expected count to be event list length, got %u\n", count
);
1566 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1567 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1568 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1569 "Expected count to be twice event list length, got %u\n", count
);
1571 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1572 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1573 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1574 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1576 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1577 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1579 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1580 "Expected count to be twice event list length, got %u\n", count
);
1582 ret
= FlushConsoleInputBuffer(input_handle
);
1583 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1585 key_event
.bKeyDown
= FALSE
;
1586 key_event
.wRepeatCount
= 0;
1587 key_event
.wVirtualKeyCode
= VK_SPACE
;
1588 key_event
.wVirtualScanCode
= VK_SPACE
;
1589 key_event
.uChar
.AsciiChar
= ' ';
1590 key_event
.dwControlKeyState
= 0;
1592 event
.EventType
= KEY_EVENT
;
1593 event
.Event
.KeyEvent
= key_event
;
1595 /* Key events don't exhibit the same behavior as mouse events. */
1596 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1597 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1598 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1600 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1601 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1602 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1604 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1605 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1606 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1608 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1609 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1610 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1612 ret
= FlushConsoleInputBuffer(input_handle
);
1613 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1615 /* Try interleaving mouse and key events. */
1616 event
.EventType
= MOUSE_EVENT
;
1617 event
.Event
.MouseEvent
= mouse_event
;
1619 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1620 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1621 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1623 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1624 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1625 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1627 event
.EventType
= KEY_EVENT
;
1628 event
.Event
.KeyEvent
= key_event
;
1630 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1631 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1632 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1634 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1635 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1636 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1638 event
.EventType
= MOUSE_EVENT
;
1639 event
.Event
.MouseEvent
= mouse_event
;
1641 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1642 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1643 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1645 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1646 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1647 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1649 /* Restore the old console mode. */
1650 ret
= SetConsoleMode(input_handle
, console_mode
);
1651 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1654 static void test_WriteConsoleInputW(HANDLE input_handle
)
1657 INPUT_RECORD event_list
[5];
1658 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1659 KEY_EVENT_RECORD key_event
;
1660 DWORD count
, console_mode
, gle
;
1667 const INPUT_RECORD
*buffer
;
1674 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1675 {NULL
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1676 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1677 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1678 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1679 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1680 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1681 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1682 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1683 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1684 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1685 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1686 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1687 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1688 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1689 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1690 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1691 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1692 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1693 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1694 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1697 /* Suppress external sources of input events for the duration of the test. */
1698 ret
= GetConsoleMode(input_handle
, &console_mode
);
1699 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1702 skip("GetConsoleMode failed with last error %u\n", GetLastError());
1706 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1707 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1710 skip("SetConsoleMode failed with last error %u\n", GetLastError());
1714 /* Discard any events queued before the tests. */
1715 ret
= FlushConsoleInputBuffer(input_handle
);
1716 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1718 event
.EventType
= MOUSE_EVENT
;
1719 event
.Event
.MouseEvent
= mouse_event
;
1721 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1723 if (invalid_table
[i
].win_crash
)
1726 SetLastError(0xdeadbeef);
1727 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1728 ret
= WriteConsoleInputW(invalid_table
[i
].handle
,
1729 invalid_table
[i
].buffer
,
1730 invalid_table
[i
].count
,
1731 invalid_table
[i
].written
);
1732 ok(!ret
, "[%d] Expected WriteConsoleInputW to return FALSE, got %d\n", i
, ret
);
1733 gle
= GetLastError();
1734 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1735 "[%d] Expected last error to be %u or %u, got %u\n",
1736 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1740 ret
= WriteConsoleInputW(input_handle
, NULL
, 0, &count
);
1741 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1742 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1745 ret
= WriteConsoleInputW(input_handle
, &event
, 0, &count
);
1746 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1747 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1750 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1751 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1752 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1754 ret
= FlushConsoleInputBuffer(input_handle
);
1755 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1757 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1758 event
.EventType
= MOUSE_EVENT
;
1759 event
.Event
.MouseEvent
= mouse_event
;
1761 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1762 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1763 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1765 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1766 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1767 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1769 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1770 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1771 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1773 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1774 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1776 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1778 ret
= FlushConsoleInputBuffer(input_handle
);
1779 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1781 for (i
= 0; i
< sizeof(event_list
)/sizeof(event_list
[0]); i
++)
1783 event_list
[i
].EventType
= MOUSE_EVENT
;
1784 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1787 /* Writing consecutive chunks of mouse events appears to work. */
1788 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1789 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1790 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1791 "Expected count to be event list length, got %u\n", count
);
1793 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1794 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1795 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1796 "Expected count to be event list length, got %u\n", count
);
1798 ret
= WriteConsoleInputW(input_handle
, event_list
, sizeof(event_list
)/sizeof(event_list
[0]), &count
);
1799 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1800 ok(count
== sizeof(event_list
)/sizeof(event_list
[0]),
1801 "Expected count to be event list length, got %u\n", count
);
1803 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1804 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1805 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1806 "Expected count to be twice event list length, got %u\n", count
);
1808 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1809 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1810 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1811 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1813 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1814 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1816 ok(count
== 2*sizeof(event_list
)/sizeof(event_list
[0]),
1817 "Expected count to be twice event list length, got %u\n", count
);
1819 ret
= FlushConsoleInputBuffer(input_handle
);
1820 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1822 key_event
.bKeyDown
= FALSE
;
1823 key_event
.wRepeatCount
= 0;
1824 key_event
.wVirtualKeyCode
= VK_SPACE
;
1825 key_event
.wVirtualScanCode
= VK_SPACE
;
1826 key_event
.uChar
.UnicodeChar
= ' ';
1827 key_event
.dwControlKeyState
= 0;
1829 event
.EventType
= KEY_EVENT
;
1830 event
.Event
.KeyEvent
= key_event
;
1832 /* Key events don't exhibit the same behavior as mouse events. */
1833 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1834 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1835 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1837 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1838 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1839 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1841 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1842 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1843 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1845 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1846 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1847 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1849 ret
= FlushConsoleInputBuffer(input_handle
);
1850 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1852 /* Try interleaving mouse and key events. */
1853 event
.EventType
= MOUSE_EVENT
;
1854 event
.Event
.MouseEvent
= mouse_event
;
1856 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1857 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1858 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1860 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1861 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1862 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1864 event
.EventType
= KEY_EVENT
;
1865 event
.Event
.KeyEvent
= key_event
;
1867 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1868 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1869 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1871 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1872 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1873 ok(count
== 2, "Expected count to be 2, got %u\n", count
);
1875 event
.EventType
= MOUSE_EVENT
;
1876 event
.Event
.MouseEvent
= mouse_event
;
1878 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
1879 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1880 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1882 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1883 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1884 ok(count
== 3, "Expected count to be 3, got %u\n", count
);
1886 /* Restore the old console mode. */
1887 ret
= SetConsoleMode(input_handle
, console_mode
);
1888 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1891 static void test_WriteConsoleOutputCharacterA(HANDLE output_handle
)
1893 static const char output
[] = {'a', 0};
1895 COORD origin
= {0, 0};
1902 HANDLE hConsoleOutput
;
1906 LPDWORD lpNumCharsWritten
;
1907 DWORD expected_count
;
1912 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1913 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1914 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1915 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1916 {NULL
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1917 {NULL
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1918 {NULL
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1919 {NULL
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1920 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1921 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1922 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1923 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1924 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1925 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1926 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1927 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1928 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1929 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1930 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1931 {output_handle
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1932 {output_handle
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1935 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
1937 if (invalid_table
[i
].win7_crash
)
1940 SetLastError(0xdeadbeef);
1941 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
1942 ret
= WriteConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
1943 invalid_table
[i
].str
,
1944 invalid_table
[i
].length
,
1945 invalid_table
[i
].coord
,
1946 invalid_table
[i
].lpNumCharsWritten
);
1947 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
1948 if (invalid_table
[i
].lpNumCharsWritten
)
1950 ok(count
== invalid_table
[i
].expected_count
,
1951 "[%d] Expected count to be %u, got %u\n",
1952 i
, invalid_table
[i
].expected_count
, count
);
1954 ok(GetLastError() == invalid_table
[i
].last_error
,
1955 "[%d] Expected last error to be %u, got %u\n",
1956 i
, invalid_table
[i
].last_error
, GetLastError());
1960 ret
= WriteConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
1961 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1962 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1965 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 0, origin
, &count
);
1966 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1967 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
1970 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 1, origin
, &count
);
1971 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
1972 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
1975 static void test_WriteConsoleOutputCharacterW(HANDLE output_handle
)
1977 static const WCHAR outputW
[] = {'a',0};
1979 COORD origin
= {0, 0};
1986 HANDLE hConsoleOutput
;
1990 LPDWORD lpNumCharsWritten
;
1991 DWORD expected_count
;
1996 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1997 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
1998 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
1999 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2000 {NULL
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2001 {NULL
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2002 {NULL
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2003 {NULL
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2004 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2005 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2006 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2007 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2008 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2009 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2010 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2011 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2012 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2013 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2014 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2015 {output_handle
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2016 {output_handle
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2019 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2021 if (invalid_table
[i
].win7_crash
)
2024 SetLastError(0xdeadbeef);
2025 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2026 ret
= WriteConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2027 invalid_table
[i
].str
,
2028 invalid_table
[i
].length
,
2029 invalid_table
[i
].coord
,
2030 invalid_table
[i
].lpNumCharsWritten
);
2031 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2032 if (invalid_table
[i
].lpNumCharsWritten
)
2034 ok(count
== invalid_table
[i
].expected_count
,
2035 "[%d] Expected count to be %u, got %u\n",
2036 i
, invalid_table
[i
].expected_count
, count
);
2038 ok(GetLastError() == invalid_table
[i
].last_error
,
2039 "[%d] Expected last error to be %u, got %u\n",
2040 i
, invalid_table
[i
].last_error
, GetLastError());
2044 ret
= WriteConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2045 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2046 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2049 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 0, origin
, &count
);
2050 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2051 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2054 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 1, origin
, &count
);
2055 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2056 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2059 static void test_WriteConsoleOutputAttribute(HANDLE output_handle
)
2061 WORD attr
= FOREGROUND_BLUE
;
2062 COORD origin
= {0, 0};
2069 HANDLE hConsoleOutput
;
2073 LPDWORD lpNumAttrsWritten
;
2074 DWORD expected_count
;
2079 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2080 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2081 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2082 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2083 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2084 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2085 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2086 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2087 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2088 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2089 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2090 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2091 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2092 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2093 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2094 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2095 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2096 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2097 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2098 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2099 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2102 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2104 if (invalid_table
[i
].win7_crash
)
2107 SetLastError(0xdeadbeef);
2108 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2109 ret
= WriteConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2110 invalid_table
[i
].attr
,
2111 invalid_table
[i
].length
,
2112 invalid_table
[i
].coord
,
2113 invalid_table
[i
].lpNumAttrsWritten
);
2114 ok(!ret
, "[%d] Expected WriteConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2115 if (invalid_table
[i
].lpNumAttrsWritten
)
2117 ok(count
== invalid_table
[i
].expected_count
,
2118 "[%d] Expected count to be %u, got %u\n",
2119 i
, invalid_table
[i
].expected_count
, count
);
2121 ok(GetLastError() == invalid_table
[i
].last_error
,
2122 "[%d] Expected last error to be %u, got %u\n",
2123 i
, invalid_table
[i
].last_error
, GetLastError());
2127 ret
= WriteConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2128 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2129 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2132 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2133 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2134 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2137 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2138 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2139 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2142 static void test_FillConsoleOutputCharacterA(HANDLE output_handle
)
2144 COORD origin
= {0, 0};
2151 HANDLE hConsoleOutput
;
2155 LPDWORD lpNumCharsWritten
;
2160 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2161 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2162 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2163 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2164 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2165 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2166 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2167 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2168 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2169 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2172 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2174 if (invalid_table
[i
].win7_crash
)
2177 SetLastError(0xdeadbeef);
2178 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2179 ret
= FillConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2180 invalid_table
[i
].ch
,
2181 invalid_table
[i
].length
,
2182 invalid_table
[i
].coord
,
2183 invalid_table
[i
].lpNumCharsWritten
);
2184 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2185 ok(GetLastError() == invalid_table
[i
].last_error
,
2186 "[%d] Expected last error to be %u, got %u\n",
2187 i
, invalid_table
[i
].last_error
, GetLastError());
2191 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 0, origin
, &count
);
2192 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2193 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2196 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 1, origin
, &count
);
2197 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2198 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2201 static void test_FillConsoleOutputCharacterW(HANDLE output_handle
)
2203 COORD origin
= {0, 0};
2210 HANDLE hConsoleOutput
;
2214 LPDWORD lpNumCharsWritten
;
2219 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2220 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2221 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2222 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2223 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2224 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2225 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2226 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2227 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2228 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2231 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2233 if (invalid_table
[i
].win7_crash
)
2236 SetLastError(0xdeadbeef);
2237 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2238 ret
= FillConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2239 invalid_table
[i
].ch
,
2240 invalid_table
[i
].length
,
2241 invalid_table
[i
].coord
,
2242 invalid_table
[i
].lpNumCharsWritten
);
2243 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2244 ok(GetLastError() == invalid_table
[i
].last_error
,
2245 "[%d] Expected last error to be %u, got %u\n",
2246 i
, invalid_table
[i
].last_error
, GetLastError());
2250 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 0, origin
, &count
);
2251 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2252 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2255 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 1, origin
, &count
);
2256 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2257 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2260 static void test_FillConsoleOutputAttribute(HANDLE output_handle
)
2262 COORD origin
= {0, 0};
2269 HANDLE hConsoleOutput
;
2273 LPDWORD lpNumAttrsWritten
;
2278 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2279 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2280 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2281 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2282 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2283 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2284 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2285 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2286 {output_handle
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2287 {output_handle
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2290 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2292 if (invalid_table
[i
].win7_crash
)
2295 SetLastError(0xdeadbeef);
2296 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2297 ret
= FillConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2298 invalid_table
[i
].attr
,
2299 invalid_table
[i
].length
,
2300 invalid_table
[i
].coord
,
2301 invalid_table
[i
].lpNumAttrsWritten
);
2302 ok(!ret
, "[%d] Expected FillConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2303 ok(GetLastError() == invalid_table
[i
].last_error
,
2304 "[%d] Expected last error to be %u, got %u\n",
2305 i
, invalid_table
[i
].last_error
, GetLastError());
2309 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 0, origin
, &count
);
2310 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2311 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2314 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 1, origin
, &count
);
2315 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2316 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2319 ret
= FillConsoleOutputAttribute(output_handle
, ~0, 1, origin
, &count
);
2320 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2321 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2324 static void test_ReadConsoleOutputCharacterA(HANDLE output_handle
)
2327 COORD origin
= {0, 0};
2334 HANDLE hConsoleOutput
;
2339 DWORD expected_count
;
2344 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2345 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2346 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2347 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2348 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2349 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2350 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2351 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2352 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2353 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2354 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2355 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2356 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2357 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2358 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2359 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2360 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2361 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2362 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2363 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2364 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2365 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2368 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2370 if (invalid_table
[i
].win7_crash
)
2373 SetLastError(0xdeadbeef);
2374 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2375 ret
= ReadConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2376 invalid_table
[i
].lpstr
,
2377 invalid_table
[i
].length
,
2378 invalid_table
[i
].coord
,
2379 invalid_table
[i
].read_count
);
2380 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2381 if (invalid_table
[i
].read_count
)
2383 ok(count
== invalid_table
[i
].expected_count
,
2384 "[%d] Expected count to be %u, got %u\n",
2385 i
, invalid_table
[i
].expected_count
, count
);
2387 ok(GetLastError() == invalid_table
[i
].last_error
,
2388 "[%d] Expected last error to be %u, got %u\n",
2389 i
, invalid_table
[i
].last_error
, GetLastError());
2393 ret
= ReadConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
2394 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2395 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2398 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 0, origin
, &count
);
2399 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2400 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2403 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 1, origin
, &count
);
2404 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2405 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2408 static void test_ReadConsoleOutputCharacterW(HANDLE output_handle
)
2411 COORD origin
= {0, 0};
2418 HANDLE hConsoleOutput
;
2423 DWORD expected_count
;
2428 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2429 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2430 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2431 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2432 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2433 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2434 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2435 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2436 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2437 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2438 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2439 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2440 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2441 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2442 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2443 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2444 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2445 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2446 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2447 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2448 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2449 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2452 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2454 if (invalid_table
[i
].win7_crash
)
2457 SetLastError(0xdeadbeef);
2458 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2459 ret
= ReadConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2460 invalid_table
[i
].buffer
,
2461 invalid_table
[i
].length
,
2462 invalid_table
[i
].coord
,
2463 invalid_table
[i
].read_count
);
2464 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2465 if (invalid_table
[i
].read_count
)
2467 ok(count
== invalid_table
[i
].expected_count
,
2468 "[%d] Expected count to be %u, got %u\n",
2469 i
, invalid_table
[i
].expected_count
, count
);
2471 ok(GetLastError() == invalid_table
[i
].last_error
,
2472 "[%d] Expected last error to be %u, got %u\n",
2473 i
, invalid_table
[i
].last_error
, GetLastError());
2477 ret
= ReadConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2478 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2479 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2482 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 0, origin
, &count
);
2483 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2484 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2487 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 1, origin
, &count
);
2488 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2489 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2492 static void test_ReadConsoleOutputAttribute(HANDLE output_handle
)
2495 COORD origin
= {0, 0};
2502 HANDLE hConsoleOutput
;
2507 DWORD expected_count
;
2512 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2513 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2514 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2515 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2516 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2517 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2518 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2519 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2520 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2521 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2522 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2523 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2524 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2525 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2526 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2527 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2528 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2529 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2530 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2531 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2532 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2535 for (i
= 0; i
< sizeof(invalid_table
)/sizeof(invalid_table
[0]); i
++)
2537 if (invalid_table
[i
].win7_crash
)
2540 SetLastError(0xdeadbeef);
2541 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2542 ret
= ReadConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2543 invalid_table
[i
].lpAttribute
,
2544 invalid_table
[i
].length
,
2545 invalid_table
[i
].coord
,
2546 invalid_table
[i
].read_count
);
2547 ok(!ret
, "[%d] Expected ReadConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2548 if (invalid_table
[i
].read_count
)
2550 ok(count
== invalid_table
[i
].expected_count
,
2551 "[%d] Expected count to be %u, got %u\n",
2552 i
, invalid_table
[i
].expected_count
, count
);
2554 ok(GetLastError() == invalid_table
[i
].last_error
,
2555 "[%d] Expected last error to be %u, got %u\n",
2556 i
, invalid_table
[i
].last_error
, GetLastError());
2560 ret
= ReadConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2561 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2562 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2565 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2566 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2567 ok(count
== 0, "Expected count to be 0, got %u\n", count
);
2570 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2571 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2572 ok(count
== 1, "Expected count to be 1, got %u\n", count
);
2575 static void test_ReadConsole(void)
2581 std_input
= GetStdHandle(STD_INPUT_HANDLE
);
2583 SetLastError(0xdeadbeef);
2584 ret
= GetFileSize(std_input
, NULL
);
2585 ok(ret
== INVALID_FILE_SIZE
, "expected INVALID_FILE_SIZE, got %#x\n", ret
);
2586 ok(GetLastError() == ERROR_INVALID_HANDLE
||
2587 GetLastError() == ERROR_INVALID_FUNCTION
, /* Win 8, 10 */
2588 "expected ERROR_INVALID_HANDLE, got %d\n", GetLastError());
2591 SetLastError(0xdeadbeef);
2592 ret
= ReadFile(std_input
, buf
, -128, &bytes
, NULL
);
2593 ok(!ret
, "expected 0, got %u\n", ret
);
2594 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2595 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2596 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2597 ok(!bytes
, "expected 0, got %u\n", bytes
);
2600 SetLastError(0xdeadbeef);
2601 ret
= ReadConsoleA(std_input
, buf
, -128, &bytes
, NULL
);
2602 ok(!ret
, "expected 0, got %u\n", ret
);
2603 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2604 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2605 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2606 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2609 SetLastError(0xdeadbeef);
2610 ret
= ReadConsoleW(std_input
, buf
, -128, &bytes
, NULL
);
2611 ok(!ret
, "expected 0, got %u\n", ret
);
2612 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
2613 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
2614 "expected ERROR_NOT_ENOUGH_MEMORY, got %d\n", GetLastError());
2615 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#x\n", bytes
);
2618 static void test_GetCurrentConsoleFont(HANDLE std_output
)
2621 CONSOLE_FONT_INFO cfi
;
2622 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2623 short int width
, height
;
2626 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2627 SetLastError(0xdeadbeef);
2628 ret
= GetCurrentConsoleFont(NULL
, FALSE
, &cfi
);
2629 ok(!ret
, "got %d, expected 0\n", ret
);
2630 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2631 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2632 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2634 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2635 SetLastError(0xdeadbeef);
2636 ret
= GetCurrentConsoleFont(NULL
, TRUE
, &cfi
);
2637 ok(!ret
, "got %d, expected 0\n", ret
);
2638 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2639 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2640 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2642 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2643 SetLastError(0xdeadbeef);
2644 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, &cfi
);
2645 ok(!ret
, "got %d, expected 0\n", ret
);
2646 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2647 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2648 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2650 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2651 SetLastError(0xdeadbeef);
2652 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, &cfi
);
2653 ok(!ret
, "got %d, expected 0\n", ret
);
2654 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2655 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
2656 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
2658 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2659 SetLastError(0xdeadbeef);
2660 ret
= GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2661 ok(ret
, "got %d, expected non-zero\n", ret
);
2662 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2663 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2664 width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
2665 height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
2666 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2667 ok(cfi
.dwFontSize
.X
== width
|| cfi
.dwFontSize
.X
== c
.X
/* Vista and higher */,
2668 "got %d, expected %d\n", cfi
.dwFontSize
.X
, width
);
2669 ok(cfi
.dwFontSize
.Y
== height
|| cfi
.dwFontSize
.Y
== c
.Y
/* Vista and higher */,
2670 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, height
);
2672 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
2673 SetLastError(0xdeadbeef);
2674 ret
= GetCurrentConsoleFont(std_output
, TRUE
, &cfi
);
2675 ok(ret
, "got %d, expected non-zero\n", ret
);
2676 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2677 ok(cfi
.dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
,
2678 "got %d, expected %d\n", cfi
.dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
2679 ok(cfi
.dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
,
2680 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
2683 static void test_GetConsoleFontSize(HANDLE std_output
)
2687 CONSOLE_FONT_INFO cfi
;
2689 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2690 LONG font_width
, font_height
;
2692 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2694 memset(&c
, 10, sizeof(COORD
));
2695 SetLastError(0xdeadbeef);
2696 c
= GetConsoleFontSize(NULL
, index
);
2697 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2698 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2699 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2701 memset(&c
, 10, sizeof(COORD
));
2702 SetLastError(0xdeadbeef);
2703 c
= GetConsoleFontSize(GetStdHandle(STD_INPUT_HANDLE
), index
);
2704 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2705 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2706 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2708 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2709 memset(&c
, 10, sizeof(COORD
));
2710 SetLastError(0xdeadbeef);
2711 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2712 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2713 GetClientRect(GetConsoleWindow(), &r
);
2714 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2715 font_width
= (r
.right
- r
.left
+ 1) / csbi
.srWindow
.Right
;
2716 font_height
= (r
.bottom
- r
.top
+ 1) / csbi
.srWindow
.Bottom
;
2717 ok(c
.X
== font_width
, "got %d, expected %d\n", c
.X
, font_width
);
2718 ok(c
.Y
== font_height
, "got %d, expected %d\n", c
.Y
, font_height
);
2720 hmod
= GetModuleHandleA("kernel32.dll");
2721 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2722 if (!pGetNumberOfConsoleFonts
)
2724 win_skip("GetNumberOfConsoleFonts is not available\n");
2727 index
= pGetNumberOfConsoleFonts();
2729 memset(&c
, 10, sizeof(COORD
));
2730 SetLastError(0xdeadbeef);
2731 c
= GetConsoleFontSize(std_output
, index
);
2732 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2733 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2734 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2737 static void test_GetLargestConsoleWindowSize(HANDLE std_output
)
2741 LONG workarea_w
, workarea_h
, maxcon_w
, maxcon_h
;
2742 CONSOLE_SCREEN_BUFFER_INFO sbi
;
2743 CONSOLE_FONT_INFO cfi
;
2747 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2748 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
2750 memset(&c
, 10, sizeof(COORD
));
2751 SetLastError(0xdeadbeef);
2752 c
= GetLargestConsoleWindowSize(NULL
);
2753 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2754 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2755 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2757 memset(&c
, 10, sizeof(COORD
));
2758 SetLastError(0xdeadbeef);
2759 c
= GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE
));
2760 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2761 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
2762 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
2764 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &r
, 0);
2765 workarea_w
= r
.right
- r
.left
;
2766 workarea_h
= r
.bottom
- r
.top
- GetSystemMetrics(SM_CYCAPTION
);
2768 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2769 index
= cfi
.nFont
; /* save current font index */
2771 hmod
= GetModuleHandleA("kernel32.dll");
2772 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2773 if (!pGetNumberOfConsoleFonts
)
2775 win_skip("GetNumberOfConsoleFonts is not available\n");
2778 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
2779 if (!pSetConsoleFont
)
2781 win_skip("SetConsoleFont is not available\n");
2785 for (i
= 0; i
< pGetNumberOfConsoleFonts(); i
++)
2787 pSetConsoleFont(std_output
, i
);
2788 memset(&c
, 10, sizeof(COORD
));
2789 SetLastError(0xdeadbeef);
2790 c
= GetLargestConsoleWindowSize(std_output
);
2791 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2792 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
2793 font
= GetConsoleFontSize(std_output
, cfi
.nFont
);
2794 maxcon_w
= workarea_w
/ font
.X
;
2795 maxcon_h
= workarea_h
/ font
.Y
;
2796 ok(c
.X
== maxcon_w
|| c
.X
== maxcon_w
- 1 /* Win10 */, "got %d, expected %d\n", c
.X
, maxcon_w
);
2797 ok(c
.Y
== maxcon_h
|| c
.Y
== maxcon_h
- 1 /* Win10 */, "got %d, expected %d\n", c
.Y
, maxcon_h
);
2799 ret
= GetConsoleScreenBufferInfo(std_output
, &sbi
);
2800 ok(ret
, "GetConsoleScreenBufferInfo failed %u\n", GetLastError());
2801 ok(sbi
.dwMaximumWindowSize
.X
== min(c
.X
, sbi
.dwSize
.X
), "got %d, expected %d\n",
2802 sbi
.dwMaximumWindowSize
.X
, min(c
.X
, sbi
.dwSize
.X
));
2803 ok(sbi
.dwMaximumWindowSize
.Y
== min(c
.Y
, sbi
.dwSize
.Y
), "got %d, expected %d\n",
2804 sbi
.dwMaximumWindowSize
.Y
, min(c
.Y
, sbi
.dwSize
.Y
));
2806 pSetConsoleFont(std_output
, index
); /* restore original font size */
2809 static void test_GetConsoleFontInfo(HANDLE std_output
)
2812 BOOL (WINAPI
*pGetConsoleFontInfo
)(HANDLE
, BOOL
, DWORD
, CONSOLE_FONT_INFO
*);
2813 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2814 DWORD num_fonts
, index
, i
;
2815 int memsize
, win_width
, win_height
, tmp_w
, tmp_h
;
2816 CONSOLE_FONT_INFO
*cfi
;
2818 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2819 COORD orig_sb_size
, tmp_sb_size
, orig_font
, tmp_font
;
2821 hmod
= GetModuleHandleA("kernel32.dll");
2822 pGetConsoleFontInfo
= (void *)GetProcAddress(hmod
, "GetConsoleFontInfo");
2823 if (!pGetConsoleFontInfo
)
2825 win_skip("GetConsoleFontInfo is not available\n");
2829 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2830 if (!pGetNumberOfConsoleFonts
)
2832 win_skip("GetNumberOfConsoleFonts is not available\n");
2836 num_fonts
= pGetNumberOfConsoleFonts();
2837 memsize
= num_fonts
* sizeof(CONSOLE_FONT_INFO
);
2838 cfi
= HeapAlloc(GetProcessHeap(), 0, memsize
);
2839 memset(cfi
, 0, memsize
);
2841 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2842 orig_sb_size
= csbi
.dwSize
;
2843 tmp_sb_size
.X
= csbi
.dwSize
.X
+ 3;
2844 tmp_sb_size
.Y
= csbi
.dwSize
.Y
+ 5;
2845 SetConsoleScreenBufferSize(std_output
, tmp_sb_size
);
2847 SetLastError(0xdeadbeef);
2848 ret
= pGetConsoleFontInfo(NULL
, FALSE
, 0, cfi
);
2849 ok(!ret
, "got %d, expected zero\n", ret
);
2850 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2852 SetLastError(0xdeadbeef);
2853 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, 0, cfi
);
2854 ok(!ret
, "got %d, expected zero\n", ret
);
2855 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2857 SetLastError(0xdeadbeef);
2858 ret
= pGetConsoleFontInfo(std_output
, FALSE
, 0, cfi
);
2859 ok(!ret
, "got %d, expected zero\n", ret
);
2860 todo_wine
ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2862 GetConsoleScreenBufferInfo(std_output
, &csbi
);
2863 win_width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
2864 win_height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
2866 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
[0]);
2867 index
= cfi
[0].nFont
;
2868 orig_font
= GetConsoleFontSize(std_output
, index
);
2870 memset(cfi
, 0, memsize
);
2871 ret
= pGetConsoleFontInfo(std_output
, FALSE
, num_fonts
, cfi
);
2872 todo_wine
ok(ret
, "got %d, expected non-zero\n", ret
);
2874 todo_wine
ok(cfi
[index
].dwFontSize
.X
== win_width
, "got %d, expected %d\n",
2875 cfi
[index
].dwFontSize
.X
, win_width
);
2876 todo_wine
ok(cfi
[index
].dwFontSize
.Y
== win_height
, "got %d, expected %d\n",
2877 cfi
[index
].dwFontSize
.Y
, win_height
);
2879 for (i
= 0; i
< num_fonts
; i
++)
2881 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %d, expected %d\n", cfi
[i
].nFont
, i
);
2882 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
2883 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* win_width
;
2884 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* win_height
;
2885 todo_wine
ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
2886 todo_wine
ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
2889 SetLastError(0xdeadbeef);
2890 ret
= pGetConsoleFontInfo(NULL
, TRUE
, 0, cfi
);
2891 ok(!ret
, "got %d, expected zero\n", ret
);
2892 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2894 SetLastError(0xdeadbeef);
2895 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, 0, cfi
);
2896 ok(!ret
, "got %d, expected zero\n", ret
);
2897 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2899 SetLastError(0xdeadbeef);
2900 ret
= pGetConsoleFontInfo(std_output
, TRUE
, 0, cfi
);
2901 ok(!ret
, "got %d, expected zero\n", ret
);
2902 todo_wine
ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
2904 memset(cfi
, 0, memsize
);
2905 ret
= pGetConsoleFontInfo(std_output
, TRUE
, num_fonts
, cfi
);
2906 todo_wine
ok(ret
, "got %d, expected non-zero\n", ret
);
2908 todo_wine
ok(cfi
[index
].dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
, "got %d, expected %d\n",
2909 cfi
[index
].dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
2910 todo_wine
ok(cfi
[index
].dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
, "got %d, expected %d\n",
2911 cfi
[index
].dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
2913 for (i
= 0; i
< num_fonts
; i
++)
2915 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %d, expected %d\n", cfi
[i
].nFont
, i
);
2916 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
2917 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* csbi
.dwMaximumWindowSize
.X
;
2918 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* csbi
.dwMaximumWindowSize
.Y
;
2919 todo_wine
ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
2920 todo_wine
ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
2923 HeapFree(GetProcessHeap(), 0, cfi
);
2924 SetConsoleScreenBufferSize(std_output
, orig_sb_size
);
2927 static void test_SetConsoleFont(HANDLE std_output
)
2930 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
2932 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
2935 hmod
= GetModuleHandleA("kernel32.dll");
2936 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
2937 if (!pSetConsoleFont
)
2939 win_skip("SetConsoleFont is not available\n");
2943 SetLastError(0xdeadbeef);
2944 ret
= pSetConsoleFont(NULL
, 0);
2945 ok(!ret
, "got %d, expected zero\n", ret
);
2946 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2948 SetLastError(0xdeadbeef);
2949 ret
= pSetConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), 0);
2950 ok(!ret
, "got %d, expected zero\n", ret
);
2951 todo_wine
ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
2953 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
2954 if (!pGetNumberOfConsoleFonts
)
2956 win_skip("GetNumberOfConsoleFonts is not available\n");
2960 num_fonts
= pGetNumberOfConsoleFonts();
2962 SetLastError(0xdeadbeef);
2963 ret
= pSetConsoleFont(std_output
, num_fonts
);
2964 ok(!ret
, "got %d, expected zero\n", ret
);
2965 todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2968 static void test_GetConsoleScreenBufferInfoEx(HANDLE std_output
)
2971 BOOL (WINAPI
*pGetConsoleScreenBufferInfoEx
)(HANDLE
, CONSOLE_SCREEN_BUFFER_INFOEX
*);
2972 CONSOLE_SCREEN_BUFFER_INFOEX csbix
;
2974 HANDLE std_input
= GetStdHandle(STD_INPUT_HANDLE
);
2976 hmod
= GetModuleHandleA("kernel32.dll");
2977 pGetConsoleScreenBufferInfoEx
= (void *)GetProcAddress(hmod
, "GetConsoleScreenBufferInfoEx");
2978 if (!pGetConsoleScreenBufferInfoEx
)
2980 win_skip("GetConsoleScreenBufferInfoEx is not available\n");
2984 SetLastError(0xdeadbeef);
2985 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
2986 ok(!ret
, "got %d, expected zero\n", ret
);
2987 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2989 SetLastError(0xdeadbeef);
2990 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
2991 ok(!ret
, "got %d, expected zero\n", ret
);
2992 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2994 SetLastError(0xdeadbeef);
2995 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
2996 ok(!ret
, "got %d, expected zero\n", ret
);
2997 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %u, expected 87\n", GetLastError());
2999 csbix
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
3001 SetLastError(0xdeadbeef);
3002 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
3003 ok(!ret
, "got %d, expected zero\n", ret
);
3004 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
3006 SetLastError(0xdeadbeef);
3007 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
3008 ok(!ret
, "got %d, expected zero\n", ret
);
3009 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %u, expected 6\n", GetLastError());
3011 SetLastError(0xdeadbeef);
3012 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
3013 ok(ret
, "got %d, expected non-zero\n", ret
);
3014 ok(GetLastError() == 0xdeadbeef, "got %u, expected 0xdeadbeef\n", GetLastError());
3019 static const char font_name
[] = "Lucida Console";
3020 HANDLE hConIn
, hConOut
;
3022 CONSOLE_SCREEN_BUFFER_INFO sbi
;
3025 char old_font
[LF_FACESIZE
];
3026 BOOL
delete = FALSE
;
3029 init_function_pointers();
3031 /* be sure we have a clean console (and that's our own)
3032 * FIXME: this will make the test fail (currently) if we don't run
3034 * Another solution would be to rerun the test under wineconsole with
3035 * the curses backend
3038 /* ReadConsoleOutputW doesn't retrieve characters from the output buffer
3039 * correctly for characters that don't have a glyph in the console font. So,
3040 * we first set the console font to Lucida Console (which has a wider
3041 * selection of glyphs available than the default raster fonts). We want
3042 * to be able to restore the original font afterwards, so don't change
3043 * if we can't read the original font.
3045 err
= RegOpenKeyExA(HKEY_CURRENT_USER
, "Console", 0,
3046 KEY_QUERY_VALUE
| KEY_SET_VALUE
, &console_key
);
3047 if (err
== ERROR_SUCCESS
)
3049 size
= sizeof(old_font
);
3050 err
= RegQueryValueExA(console_key
, "FaceName", NULL
, NULL
,
3051 (LPBYTE
) old_font
, &size
);
3052 if (err
== ERROR_SUCCESS
|| err
== ERROR_FILE_NOT_FOUND
)
3054 delete = (err
== ERROR_FILE_NOT_FOUND
);
3055 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
3056 (const BYTE
*) font_name
, sizeof(font_name
));
3057 if (err
!= ERROR_SUCCESS
)
3058 trace("Unable to change default console font, error %d\n", err
);
3062 trace("Unable to query default console font, error %d\n", err
);
3063 RegCloseKey(console_key
);
3069 trace("Unable to open HKCU\\Console, error %d\n", err
);
3073 /* Now detach and open a fresh console to play with */
3075 ok(AllocConsole(), "Couldn't alloc console\n");
3077 /* Restore default console font if needed */
3078 if (console_key
!= NULL
)
3081 err
= RegDeleteValueA(console_key
, "FaceName");
3083 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
3084 (const BYTE
*) old_font
, strlen(old_font
) + 1);
3085 ok(err
== ERROR_SUCCESS
, "Unable to restore default console font, error %d\n", err
);
3087 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3088 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3090 /* now verify everything's ok */
3091 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
3092 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
3094 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
3095 ok(ret
, "Getting sb info\n");
3098 /* Reduce the size of the buffer to the visible area plus 3 lines to speed
3101 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
);
3102 sbi
.dwSize
.Y
= size
= (sbi
.srWindow
.Bottom
+ 1) + 3;
3103 ret
= SetConsoleScreenBufferSize(hConOut
, sbi
.dwSize
);
3104 ok(ret
, "Setting sb info\n");
3105 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
3106 ok(ret
, "Getting sb info\n");
3107 ok(sbi
.dwSize
.Y
== size
, "Unexpected buffer size: %d instead of %d\n", sbi
.dwSize
.Y
, size
);
3111 /* Non interactive tests */
3112 testCursor(hConOut
, sbi
.dwSize
);
3113 /* test parameters (FIXME: test functionality) */
3114 testCursorInfo(hConOut
);
3115 /* will test wrapped (on/off) & processed (on/off) strings output */
3116 testWrite(hConOut
, sbi
.dwSize
);
3117 /* will test line scrolling at the bottom of the screen */
3118 /* testBottomScroll(); */
3119 /* will test all the scrolling operations */
3120 testScroll(hConOut
, sbi
.dwSize
);
3121 /* will test sb creation / modification / codepage handling */
3122 testScreenBuffer(hConOut
);
3123 /* Test waiting for a console handle */
3124 testWaitForConsoleInput(hConIn
);
3126 /* clear duplicated console font table */
3127 CloseHandle(hConIn
);
3128 CloseHandle(hConOut
);
3130 ok(AllocConsole(), "Couldn't alloc console\n");
3131 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3132 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3133 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
3134 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
3137 /* still to be done: access rights & access on objects */
3139 if (!pGetConsoleInputExeNameA
|| !pSetConsoleInputExeNameA
)
3140 win_skip("GetConsoleInputExeNameA and/or SetConsoleInputExeNameA is not available\n");
3142 test_GetSetConsoleInputExeName();
3144 test_GetConsoleProcessList();
3145 test_OpenConsoleW();
3148 test_VerifyConsoleIoHandle(hConOut
);
3149 test_GetSetStdHandle();
3150 test_GetNumberOfConsoleInputEvents(hConIn
);
3151 test_WriteConsoleInputA(hConIn
);
3152 test_WriteConsoleInputW(hConIn
);
3153 test_WriteConsoleOutputCharacterA(hConOut
);
3154 test_WriteConsoleOutputCharacterW(hConOut
);
3155 test_WriteConsoleOutputAttribute(hConOut
);
3156 test_FillConsoleOutputCharacterA(hConOut
);
3157 test_FillConsoleOutputCharacterW(hConOut
);
3158 test_FillConsoleOutputAttribute(hConOut
);
3159 test_ReadConsoleOutputCharacterA(hConOut
);
3160 test_ReadConsoleOutputCharacterW(hConOut
);
3161 test_ReadConsoleOutputAttribute(hConOut
);
3162 test_GetCurrentConsoleFont(hConOut
);
3163 test_GetConsoleFontSize(hConOut
);
3164 test_GetLargestConsoleWindowSize(hConOut
);
3165 test_GetConsoleFontInfo(hConOut
);
3166 test_SetConsoleFont(hConOut
);
3167 test_GetConsoleScreenBufferInfoEx(hConOut
);