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
23 #define WIN32_NO_STATUS
29 #include "wine/test.h"
31 static void (WINAPI
*pClosePseudoConsole
)(HPCON
);
32 static HRESULT (WINAPI
*pCreatePseudoConsole
)(COORD
,HANDLE
,HANDLE
,DWORD
,HPCON
*);
33 static BOOL (WINAPI
*pGetConsoleInputExeNameA
)(DWORD
, LPSTR
);
34 static DWORD (WINAPI
*pGetConsoleProcessList
)(LPDWORD
, DWORD
);
35 static HANDLE (WINAPI
*pOpenConsoleW
)(LPCWSTR
,DWORD
,BOOL
,DWORD
);
36 static BOOL (WINAPI
*pSetConsoleInputExeNameA
)(LPCSTR
);
37 static BOOL (WINAPI
*pVerifyConsoleIoHandle
)(HANDLE handle
);
41 /* DEFAULT_ATTRIB is used for all initial filling of the console.
42 * all modifications are made with TEST_ATTRIB so that we could check
43 * what has to be modified or not
45 #define TEST_ATTRIB (BACKGROUND_BLUE | FOREGROUND_GREEN)
46 #define DEFAULT_ATTRIB (FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED)
47 /* when filling the screen with non-blank chars, this macro defines
48 * what character should be at position 'c'
50 #define CONTENT(c) ('A' + (((c).Y * 17 + (c).X) % 23))
52 #define okCURSOR(hCon, c) do { \
53 CONSOLE_SCREEN_BUFFER_INFO __sbi; \
54 BOOL expect = GetConsoleScreenBufferInfo((hCon), &__sbi) && \
55 __sbi.dwCursorPosition.X == (c).X && __sbi.dwCursorPosition.Y == (c).Y; \
56 ok(expect, "Expected cursor at (%d,%d), got (%d,%d)\n", \
57 (c).X, (c).Y, __sbi.dwCursorPosition.X, __sbi.dwCursorPosition.Y); \
60 #define okCHAR(hCon, c, ch, attr) do { \
61 char __ch; WORD __attr; DWORD __len; BOOL expect; \
62 expect = ReadConsoleOutputCharacterA((hCon), &__ch, 1, (c), &__len) == 1 && __len == 1 && __ch == (ch); \
63 ok(expect, "At (%d,%d): expecting char '%c'/%02x got '%c'/%02x\n", (c).X, (c).Y, (ch), (ch), __ch, __ch); \
64 expect = ReadConsoleOutputAttribute((hCon), &__attr, 1, (c), &__len) == 1 && __len == 1 && __attr == (attr); \
65 ok(expect, "At (%d,%d): expecting attr %04x got %04x\n", (c).X, (c).Y, (attr), __attr); \
68 static void init_function_pointers(void)
72 #define KERNEL32_GET_PROC(func) \
73 p##func = (void *)GetProcAddress(hKernel32, #func); \
74 if(!p##func) trace("GetProcAddress(hKernel32, '%s') failed\n", #func);
76 hKernel32
= GetModuleHandleA("kernel32.dll");
77 KERNEL32_GET_PROC(ClosePseudoConsole
);
78 KERNEL32_GET_PROC(CreatePseudoConsole
);
79 KERNEL32_GET_PROC(GetConsoleInputExeNameA
);
80 KERNEL32_GET_PROC(GetConsoleProcessList
);
81 KERNEL32_GET_PROC(OpenConsoleW
);
82 KERNEL32_GET_PROC(SetConsoleInputExeNameA
);
83 KERNEL32_GET_PROC(VerifyConsoleIoHandle
);
85 #undef KERNEL32_GET_PROC
88 static HANDLE
create_unbound_handle(BOOL output
, BOOL test_status
)
90 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
96 attr
.ObjectName
= &name
;
97 attr
.Attributes
= OBJ_INHERIT
;
98 RtlInitUnicodeString( &name
, output
? L
"\\Device\\ConDrv\\Output" : L
"\\Device\\ConDrv\\Input" );
99 status
= NtCreateFile( &handle
, FILE_READ_DATA
| FILE_WRITE_DATA
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
|
100 FILE_WRITE_ATTRIBUTES
, &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
,
101 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_CREATE
,
102 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
103 if (test_status
) ok(!status
, "NtCreateFile failed: %#lx\n", status
);
104 return status
? NULL
: handle
;
107 /* FIXME: this could be optimized on a speed point of view */
108 static void resetContent(HANDLE hCon
, COORD sbSize
, BOOL content
)
111 WORD attr
= DEFAULT_ATTRIB
;
115 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
117 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
119 ch
= (content
) ? CONTENT(c
) : ' ';
120 WriteConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
121 WriteConsoleOutputCharacterA(hCon
, &ch
, 1, c
, &len
);
126 /* dummy console ctrl handler to test reset of ctrl handler's list */
127 static BOOL WINAPI
mydummych(DWORD event
)
132 static void testCursor(HANDLE hCon
, COORD sbSize
)
137 ok(SetConsoleCursorPosition(0, c
) == 0, "No handle\n");
138 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %lu\n",
139 ERROR_INVALID_HANDLE
, GetLastError());
142 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
147 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in lower-right\n");
152 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
153 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %lu\n",
154 ERROR_INVALID_PARAMETER
, GetLastError());
158 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
159 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %lu\n",
160 ERROR_INVALID_PARAMETER
, GetLastError());
164 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
165 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %lu\n",
166 ERROR_INVALID_PARAMETER
, GetLastError());
170 ok(SetConsoleCursorPosition(hCon
, c
) == 0, "Cursor is outside\n");
171 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "GetLastError: expecting %u got %lu\n",
172 ERROR_INVALID_PARAMETER
, GetLastError());
175 static void testCursorInfo(HANDLE hCon
)
178 CONSOLE_CURSOR_INFO info
;
181 SetLastError(0xdeadbeef);
182 ret
= GetConsoleCursorInfo(NULL
, NULL
);
183 ok(!ret
, "Expected failure\n");
184 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %lu\n",
185 ERROR_INVALID_HANDLE
, GetLastError());
187 SetLastError(0xdeadbeef);
189 ret
= GetConsoleCursorInfo(NULL
, &info
);
190 ok(!ret
, "Expected failure\n");
191 ok(info
.dwSize
== -1, "Expected no change for dwSize\n");
192 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: expecting %u got %lu\n",
193 ERROR_INVALID_HANDLE
, GetLastError());
195 /* Test the correct call first to distinguish between win9x and the rest */
196 SetLastError(0xdeadbeef);
197 ret
= GetConsoleCursorInfo(hCon
, &info
);
198 ok(ret
, "Expected success\n");
199 ok(info
.dwSize
== 25 ||
200 info
.dwSize
== 12 /* win9x */,
201 "Expected 12 or 25, got %ld\n", info
.dwSize
);
202 ok(info
.bVisible
, "Expected the cursor to be visible\n");
203 ok(GetLastError() == 0xdeadbeef, "GetLastError: expecting %u got %lu\n",
204 0xdeadbeef, GetLastError());
206 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
208 ret
= GetConsoleCursorInfo(pipe1
, &info
);
209 ok(!ret
, "Expected failure\n");
210 ok(info
.dwSize
== -1, "Expected no change for dwSize\n");
211 ok(GetLastError() == ERROR_INVALID_HANDLE
, "GetLastError: %lu\n", GetLastError());
215 /* Don't test NULL CONSOLE_CURSOR_INFO, it crashes on win9x and win7 */
218 static void testEmptyWrite(HANDLE hCon
)
220 static const char emptybuf
[16];
225 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left\n");
228 ok(WriteConsoleA(hCon
, NULL
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
231 /* Passing a NULL lpBuffer with sufficiently large non-zero length succeeds
232 * on native Windows and result in memory-like contents being written to
233 * the console. Calling WriteConsoleW like this will crash on Wine. */
237 ok(!WriteConsoleA(hCon
, NULL
, 16, &len
, NULL
) && len
== -1, "WriteConsole\n");
240 /* Cursor advances for this call. */
242 ok(WriteConsoleA(hCon
, NULL
, 128, &len
, NULL
) != 0 && len
== 128, "WriteConsole\n");
246 ok(WriteConsoleA(hCon
, emptybuf
, 0, &len
, NULL
) != 0 && len
== 0, "WriteConsole\n");
249 /* WriteConsole does not halt on a null terminator and is happy to write
250 * memory contents beyond the actual size of the buffer. */
252 ok(WriteConsoleA(hCon
, emptybuf
, 16, &len
, NULL
) != 0 && len
== 16, "WriteConsole\n");
257 static void simple_write_console(HANDLE console
, const char *text
)
263 /* single line write */
265 ok(SetConsoleCursorPosition(console
, c
) != 0, "Cursor in upper-left\n");
267 ret
= WriteConsoleA(console
, text
, strlen(text
), &len
, NULL
);
268 ok(ret
, "WriteConsoleA failed: %lu\n", GetLastError());
269 ok(len
== strlen(text
), "unexpected len %lu\n", len
);
272 static void testWriteSimple(HANDLE hCon
)
274 const char* mytest
= "abcdefg";
275 int mylen
= strlen(mytest
);
280 simple_write_console(hCon
, mytest
);
282 for (c
.X
= 0; c
.X
< mylen
; c
.X
++)
284 okCHAR(hCon
, c
, mytest
[c
.X
], TEST_ATTRIB
);
288 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
290 ret
= WriteFile(hCon
, mytest
, mylen
, &len
, NULL
);
291 ok(ret
, "WriteFile failed: %lu\n", GetLastError());
292 ok(len
== mylen
, "unexpected len = %lu\n", len
);
294 for (c
.X
= 0; c
.X
< 2 * mylen
; c
.X
++)
296 okCHAR(hCon
, c
, mytest
[c
.X
% mylen
], TEST_ATTRIB
);
300 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
303 static void testWriteNotWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
307 const char* mytest
= "123";
308 const int mylen
= strlen(mytest
);
313 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
& ~(ENABLE_PROCESSED_OUTPUT
|ENABLE_WRAP_AT_EOL_OUTPUT
)),
314 "clearing wrap at EOL & processed output\n");
316 /* write line, wrapping disabled, buffer exceeds sb width */
317 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
318 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
320 ret
= WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
);
321 ok(ret
!= 0 && len
== mylen
, "Couldn't write, ret = %d, len = %ld\n", ret
, len
);
323 for (p
= mylen
- 3; p
< mylen
; p
++)
325 c
.X
= sbSize
.X
- 3 + p
% 3;
326 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
330 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
332 p
= sbSize
.X
- 3 + mylen
% 3;
335 /* write line, wrapping disabled, strings end on end of line */
336 c
.X
= sbSize
.X
- mylen
; c
.Y
= 0;
337 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
339 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
341 /* test how control chars are handled. */
343 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
344 for (p
= 0; p
< 32; p
++) ctrl_buf
[p
] = (char)p
;
345 ok(WriteConsoleA(hCon
, ctrl_buf
, 32, &len
, NULL
) != 0 && len
== 32, "WriteConsole\n");
346 for (p
= 0; p
< 32; p
++)
349 okCHAR(hCon
, c
, (char)p
, TEST_ATTRIB
);
353 static void testWriteNotWrappedProcessed(HANDLE hCon
, COORD sbSize
)
357 const char* mytest
= "abcd\nf\tg";
358 const int mylen
= strlen(mytest
);
359 const int mylen2
= strchr(mytest
, '\n') - mytest
;
363 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, (mode
| ENABLE_PROCESSED_OUTPUT
) &
364 ~(ENABLE_WRAP_AT_EOL_OUTPUT
| ENABLE_VIRTUAL_TERMINAL_PROCESSING
)),
365 "clearing wrap at EOL & setting processed output\n");
367 /* write line, wrapping disabled, buffer exceeds sb width */
368 c
.X
= sbSize
.X
- 5; c
.Y
= 0;
369 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-5\n");
371 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
373 for (c
.X
= sbSize
.X
- 5; c
.X
< sbSize
.X
- 1; c
.X
++)
375 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 5], TEST_ATTRIB
);
378 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
379 /* Win9x and WinMe change the attribs for '\n' up to 'f' */
380 if (attr
== TEST_ATTRIB
)
382 win_skip("Win9x/WinMe don't respect ~ENABLE_WRAP_AT_EOL_OUTPUT\n");
386 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
389 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
390 for (c
.X
= 1; c
.X
< 8; c
.X
++)
391 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
392 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
394 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
398 /* write line, wrapping disabled, strings end on end of line */
399 c
.X
= sbSize
.X
- 4; c
.Y
= 0;
400 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
402 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
404 for (c
.X
= sbSize
.X
- 4; c
.X
< sbSize
.X
; c
.X
++)
406 okCHAR(hCon
, c
, mytest
[c
.X
- sbSize
.X
+ 4], TEST_ATTRIB
);
409 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
410 for (c
.X
= 1; c
.X
< 8; c
.X
++)
411 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
412 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
414 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
418 /* write line, wrapping disabled, strings end after end of line */
419 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
420 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-4\n");
422 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
424 for (p
= mylen2
- 3; p
< mylen2
; p
++)
426 c
.X
= sbSize
.X
- 3 + p
% 3;
427 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
430 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
431 for (c
.X
= 1; c
.X
< 8; c
.X
++)
432 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
433 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
435 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
440 static void testWriteWrappedNotProcessed(HANDLE hCon
, COORD sbSize
)
444 const char* mytest
= "abcd\nf\tg";
445 const int mylen
= strlen(mytest
);
448 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
,(mode
| ENABLE_WRAP_AT_EOL_OUTPUT
) & ~(ENABLE_PROCESSED_OUTPUT
)),
449 "setting wrap at EOL & clearing processed output\n");
451 /* write line, wrapping enabled, buffer doesn't exceed sb width */
452 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
453 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
455 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
457 for (p
= 0; p
< mylen
; p
++)
459 c
.X
= sbSize
.X
- 9 + p
;
460 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
462 c
.X
= sbSize
.X
- 9 + mylen
;
463 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
465 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
467 /* write line, wrapping enabled, buffer does exceed sb width */
468 c
.X
= sbSize
.X
- 3; c
.Y
= 0;
469 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
473 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
476 static void testWriteWrappedProcessed(HANDLE hCon
, COORD sbSize
)
480 const char* mytest
= "abcd\nf\tg";
481 const int mylen
= strlen(mytest
);
485 ok(GetConsoleMode(hCon
, &mode
) && SetConsoleMode(hCon
, mode
| (ENABLE_WRAP_AT_EOL_OUTPUT
|ENABLE_PROCESSED_OUTPUT
)),
486 "setting wrap at EOL & processed output\n");
488 /* write line, wrapping enabled, buffer doesn't exceed sb width */
489 c
.X
= sbSize
.X
- 9; c
.Y
= 0;
490 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-9\n");
492 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
493 for (p
= 0; p
< 4; p
++)
495 c
.X
= sbSize
.X
- 9 + p
;
496 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
498 c
.X
= sbSize
.X
- 9 + p
;
499 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
500 if (attr
== TEST_ATTRIB
)
501 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
503 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
505 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
506 for (c
.X
= 1; c
.X
< 8; c
.X
++)
507 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
508 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
510 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
513 /* write line, wrapping enabled, buffer does exceed sb width */
514 c
.X
= sbSize
.X
- 3; c
.Y
= 2;
515 ok(SetConsoleCursorPosition(hCon
, c
) != 0, "Cursor in upper-left-3\n");
517 ok(WriteConsoleA(hCon
, mytest
, mylen
, &len
, NULL
) != 0 && len
== mylen
, "WriteConsole\n");
518 for (p
= 0; p
< 3; p
++)
520 c
.X
= sbSize
.X
- 3 + p
;
521 okCHAR(hCon
, c
, mytest
[p
], TEST_ATTRIB
);
524 okCHAR(hCon
, c
, mytest
[3], TEST_ATTRIB
);
526 ReadConsoleOutputAttribute(hCon
, &attr
, 1, c
, &len
);
527 if (attr
== TEST_ATTRIB
)
528 win_skip("Win9x/WinMe changes attribs for '\\n' up to 'f'\n");
530 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
533 okCHAR(hCon
, c
, mytest
[5], TEST_ATTRIB
);
534 for (c
.X
= 1; c
.X
< 8; c
.X
++)
535 okCHAR(hCon
, c
, ' ', TEST_ATTRIB
);
536 okCHAR(hCon
, c
, mytest
[7], TEST_ATTRIB
);
538 okCHAR(hCon
, c
, ' ', DEFAULT_ATTRIB
);
542 static void testWrite(HANDLE hCon
, COORD sbSize
)
544 /* FIXME: should in fact ensure that the sb is at least 10 characters wide */
545 ok(SetConsoleTextAttribute(hCon
, TEST_ATTRIB
), "Setting default text color\n");
546 resetContent(hCon
, sbSize
, FALSE
);
547 testEmptyWrite(hCon
);
548 resetContent(hCon
, sbSize
, FALSE
);
549 testWriteSimple(hCon
);
550 resetContent(hCon
, sbSize
, FALSE
);
551 testWriteNotWrappedNotProcessed(hCon
, sbSize
);
552 resetContent(hCon
, sbSize
, FALSE
);
553 testWriteNotWrappedProcessed(hCon
, sbSize
);
554 resetContent(hCon
, sbSize
, FALSE
);
555 testWriteWrappedNotProcessed(hCon
, sbSize
);
556 resetContent(hCon
, sbSize
, FALSE
);
557 testWriteWrappedProcessed(hCon
, sbSize
);
560 static void testScroll(HANDLE hCon
, COORD sbSize
)
562 SMALL_RECT scroll
, clip
;
570 #define IN_SRECT(r,c) ((r).Left <= (c).X && (c).X <= (r).Right && (r).Top <= (c).Y && (c).Y <= (r).Bottom)
571 #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)
573 /* no clipping, src & dst rect don't overlap */
574 resetContent(hCon
, sbSize
, TRUE
);
577 scroll
.Right
= W
- 1;
579 scroll
.Bottom
= H
- 1;
582 ci
.Char
.UnicodeChar
= '#';
583 ci
.Attributes
= TEST_ATTRIB
;
586 clip
.Right
= sbSize
.X
- 1;
588 clip
.Bottom
= sbSize
.Y
- 1;
590 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
592 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
594 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
596 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
600 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
602 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
603 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
604 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
608 /* no clipping, src & dst rect do overlap */
609 resetContent(hCon
, sbSize
, TRUE
);
612 scroll
.Right
= W
- 1;
614 scroll
.Bottom
= H
- 1;
617 ci
.Char
.UnicodeChar
= '#';
618 ci
.Attributes
= TEST_ATTRIB
;
621 clip
.Right
= sbSize
.X
- 1;
623 clip
.Bottom
= sbSize
.Y
- 1;
625 ok(ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
), "Scrolling SB\n");
627 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
629 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
631 if (dst
.X
<= c
.X
&& c
.X
< dst
.X
+ W
&& dst
.Y
<= c
.Y
&& c
.Y
< dst
.Y
+ H
)
635 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
637 else if (c
.X
< W
&& c
.Y
< H
) okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
638 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
642 /* clipping, src & dst rect don't overlap */
643 resetContent(hCon
, sbSize
, TRUE
);
646 scroll
.Right
= W
- 1;
648 scroll
.Bottom
= H
- 1;
651 ci
.Char
.UnicodeChar
= '#';
652 ci
.Attributes
= TEST_ATTRIB
;
655 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
657 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
659 SetLastError(0xdeadbeef);
660 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
);
663 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
665 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
667 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
671 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
673 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
674 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
675 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
681 /* Win9x will fail, Only accept ERROR_NOT_ENOUGH_MEMORY */
682 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
,
683 "Expected ERROR_NOT_ENOUGH_MEMORY, got %lu\n", GetLastError());
686 /* no clipping, src & dst rect do overlap */
688 scroll
.Right
= W
- 1;
690 scroll
.Bottom
= H
- 1;
693 ci
.Char
.UnicodeChar
= '#';
694 ci
.Attributes
= TEST_ATTRIB
;
696 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, NULL
, dst
, &ci
);
697 ok(ret
, "ScrollConsoleScreenBufferA failed: %lu\n", GetLastError());
698 /* no win10 1909 error here, only check the result of the clipped case */
700 /* clipping, src & dst rect do overlap */
701 resetContent(hCon
, sbSize
, TRUE
);
704 scroll
.Right
= W
- 1;
706 scroll
.Bottom
= H
- 1;
709 ci
.Char
.UnicodeChar
= '#';
710 ci
.Attributes
= TEST_ATTRIB
;
713 clip
.Right
= min(W
+ W
/ 2, sbSize
.X
- 1);
715 clip
.Bottom
= min(H
+ H
/ 2, sbSize
.Y
- 1);
717 /* Windows 10 1909 fails if the destination is not in the clip rect
718 * but the result is still ok!
720 SetLastError(0xdeadbeef);
721 ret
= ScrollConsoleScreenBufferA(hCon
, &scroll
, &clip
, dst
, &ci
);
722 ok((ret
&& GetLastError() == 0xdeadbeef) ||
723 broken(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
),
724 "ScrollConsoleScreenBufferA failed: %lu\n", GetLastError());
726 for (c
.Y
= 0; c
.Y
< sbSize
.Y
; c
.Y
++)
728 for (c
.X
= 0; c
.X
< sbSize
.X
; c
.X
++)
730 if (IN_SRECT2(scroll
, dst
, c
) && IN_SRECT(clip
, c
))
734 okCHAR(hCon
, c
, CONTENT(tc
), DEFAULT_ATTRIB
);
736 else if (IN_SRECT(scroll
, c
) && IN_SRECT(clip
, c
))
737 okCHAR(hCon
, c
, '#', TEST_ATTRIB
);
738 else okCHAR(hCon
, c
, CONTENT(c
), DEFAULT_ATTRIB
);
743 static int mch_count
;
744 /* we need the event as Wine console event generation isn't synchronous
745 * (ie GenerateConsoleCtrlEvent returns before all ctrl-handlers in all
746 * processes have been called).
748 static HANDLE mch_event
;
749 static BOOL WINAPI
mch(DWORD event
)
756 static void testCtrlHandler(void)
758 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
759 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %lu\n", GetLastError());
760 ok(SetConsoleCtrlHandler(mch
, TRUE
), "Couldn't set handler\n");
761 /* wine requires the event for the test, as we cannot ensure, so far, that
762 * events are processed synchronously in GenerateConsoleCtrlEvent()
764 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
766 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
767 /* FIXME: it isn't synchronous on wine but it can still happen before we test */
768 if (0) ok(mch_count
== 1, "Event isn't synchronous\n");
769 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_OBJECT_0
, "event sending didn't work\n");
770 CloseHandle(mch_event
);
772 /* Turning off ctrl-c handling doesn't work on win9x such way ... */
773 ok(SetConsoleCtrlHandler(NULL
, TRUE
), "Couldn't turn off ctrl-c handling\n");
774 mch_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
776 if(!(GetVersion() & 0x80000000))
777 /* ... and next line leads to an unhandled exception on 9x. Avoid it on 9x. */
778 ok(GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0), "Couldn't send ctrl-c event\n");
779 ok(WaitForSingleObject(mch_event
, 3000) == WAIT_TIMEOUT
&& mch_count
== 0, "Event shouldn't have been sent\n");
780 CloseHandle(mch_event
);
781 ok(SetConsoleCtrlHandler(mch
, FALSE
), "Couldn't remove handler\n");
782 ok(!SetConsoleCtrlHandler(mch
, FALSE
), "Shouldn't succeed\n");
783 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Bad error %lu\n", GetLastError());
787 * Test console screen buffer:
788 * 1) Try to set invalid handle.
789 * 2) Try to set non-console handles.
790 * 3) Use CONOUT$ file as active SB.
792 * 5) Test output codepage to show it is not a property of SB.
793 * 6) Test switching to old SB if we close all handles to current SB - works
794 * in Windows, TODO in wine.
796 * What is not tested but should be:
797 * 1) ScreenBufferInfo
799 static void testScreenBuffer(HANDLE hConOut
)
801 HANDLE hConOutRW
, hConOutRO
, hConOutWT
;
802 HANDLE hFileOutRW
, hFileOutRO
, hFileOutWT
;
804 char test_str1
[] = "Test for SB1";
805 char test_str2
[] = "Test for SB2";
806 char test_cp866
[] = {0xe2, 0xa5, 0xe1, 0xe2, 0};
807 char test_cp1251
[] = {0xf2, 0xe5, 0xf1, 0xf2, 0};
808 WCHAR test_unicode
[] = {0x0442, 0x0435, 0x0441, 0x0442, 0};
816 if (!IsValidCodePage(866))
818 skip("Codepage 866 not available\n");
822 /* In the beginning set output codepage to 866 */
823 oldcp
= GetConsoleOutputCP();
824 SetLastError(0xdeadbeef);
825 ret
= SetConsoleOutputCP(866);
826 if (!ret
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED
)
828 win_skip("SetConsoleOutputCP is not implemented\n");
831 ok(ret
, "Cannot set output codepage to 866\n");
833 hConOutRW
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
834 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
835 CONSOLE_TEXTMODE_BUFFER
, NULL
);
836 ok(hConOutRW
!= INVALID_HANDLE_VALUE
,
837 "Cannot create a new screen buffer for ReadWrite\n");
838 hConOutRO
= CreateConsoleScreenBuffer(GENERIC_READ
,
839 FILE_SHARE_READ
, NULL
,
840 CONSOLE_TEXTMODE_BUFFER
, NULL
);
841 ok(hConOutRO
!= INVALID_HANDLE_VALUE
,
842 "Cannot create a new screen buffer for ReadOnly\n");
843 hConOutWT
= CreateConsoleScreenBuffer(GENERIC_WRITE
,
844 FILE_SHARE_WRITE
, NULL
,
845 CONSOLE_TEXTMODE_BUFFER
, NULL
);
846 ok(hConOutWT
!= INVALID_HANDLE_VALUE
,
847 "Cannot create a new screen buffer for WriteOnly\n");
849 hFileOutRW
= CreateFileA("NUL", GENERIC_READ
| GENERIC_WRITE
,
850 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
851 OPEN_EXISTING
, 0, NULL
);
852 ok(hFileOutRW
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadWrite\n");
853 hFileOutRO
= CreateFileA("NUL", GENERIC_READ
, FILE_SHARE_READ
,
854 NULL
, OPEN_EXISTING
, 0, NULL
);
855 ok(hFileOutRO
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for ReadOnly\n");
856 hFileOutWT
= CreateFileA("NUL", GENERIC_WRITE
, FILE_SHARE_WRITE
,
857 NULL
, OPEN_EXISTING
, 0, NULL
);
858 ok(hFileOutWT
!= INVALID_HANDLE_VALUE
, "Cannot open NUL for WriteOnly\n");
860 /* Trying to set invalid handle */
862 ok(!SetConsoleActiveScreenBuffer(INVALID_HANDLE_VALUE
),
863 "Shouldn't succeed\n");
864 ok(GetLastError() == ERROR_INVALID_HANDLE
,
865 "GetLastError: expecting %u got %lu\n",
866 ERROR_INVALID_HANDLE
, GetLastError());
868 /* Trying to set non-console handles */
870 ok(!SetConsoleActiveScreenBuffer(hFileOutRW
), "Shouldn't succeed\n");
871 ok(GetLastError() == ERROR_INVALID_HANDLE
,
872 "GetLastError: expecting %u got %lu\n",
873 ERROR_INVALID_HANDLE
, GetLastError());
876 ok(!SetConsoleActiveScreenBuffer(hFileOutRO
), "Shouldn't succeed\n");
877 ok(GetLastError() == ERROR_INVALID_HANDLE
,
878 "GetLastError: expecting %u got %lu\n",
879 ERROR_INVALID_HANDLE
, GetLastError());
882 ok(!SetConsoleActiveScreenBuffer(hFileOutWT
), "Shouldn't succeed\n");
883 ok(GetLastError() == ERROR_INVALID_HANDLE
,
884 "GetLastError: expecting %u got %lu\n",
885 ERROR_INVALID_HANDLE
, GetLastError());
887 /* trying to write non-console handle */
888 SetLastError(0xdeadbeef);
889 ret
= WriteConsoleA(hFileOutRW
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
890 error
= GetLastError();
891 ok(!ret
, "Shouldn't succeed\n");
892 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
893 "GetLastError: got %lu\n", error
);
895 SetLastError(0xdeadbeef);
896 ret
= WriteConsoleA(hFileOutRO
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
897 error
= GetLastError();
898 ok(!ret
, "Shouldn't succeed\n");
899 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
900 "GetLastError: got %lu\n", error
);
902 SetLastError(0xdeadbeef);
903 ret
= WriteConsoleA(hFileOutWT
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
904 error
= GetLastError();
905 ok(!ret
, "Shouldn't succeed\n");
906 ok(error
== ERROR_INVALID_HANDLE
|| error
== ERROR_INVALID_FUNCTION
,
907 "GetLastError: got %lu\n", error
);
909 CloseHandle(hFileOutRW
);
910 CloseHandle(hFileOutRO
);
911 CloseHandle(hFileOutWT
);
913 /* Trying to set SB handles with various access modes */
915 ok(!SetConsoleActiveScreenBuffer(hConOutRO
), "Shouldn't succeed\n");
916 ok(GetLastError() == ERROR_INVALID_HANDLE
|| broken(GetLastError() == ERROR_ACCESS_DENIED
) /* win10 1809 */,
917 "unexpected last error %lu\n", GetLastError());
919 ok(SetConsoleActiveScreenBuffer(hConOutWT
), "Couldn't set new WriteOnly SB\n");
921 ok(SetConsoleActiveScreenBuffer(hConOutRW
), "Couldn't set new ReadWrite SB\n");
923 CloseHandle(hConOutWT
);
924 CloseHandle(hConOutRO
);
926 /* Now we have two ReadWrite SB, active must be hConOutRW */
927 /* Open current SB via CONOUT$ */
928 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
929 NULL
, OPEN_EXISTING
, 0, 0);
930 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
935 SetConsoleCursorPosition(hConOut
, c
);
937 SetConsoleCursorPosition(hConOutRW
, c
);
938 okCURSOR(hConOutNew
, c
);
940 okCURSOR(hConOut
, c
);
945 /* Write using hConOutNew... */
946 SetConsoleCursorPosition(hConOutNew
, c
);
947 ret
= WriteConsoleA(hConOutNew
, test_str2
, lstrlenA(test_str2
), &len
, NULL
);
948 ok (ret
&& len
== lstrlenA(test_str2
), "WriteConsoleA failed\n");
949 /* ... and read it back via hConOutRW */
950 ret
= ReadConsoleOutputCharacterA(hConOutRW
, str_buf
, lstrlenA(test_str2
), c
, &len
);
951 ok(ret
&& len
== lstrlenA(test_str2
), "ReadConsoleOutputCharacterA failed\n");
952 str_buf
[lstrlenA(test_str2
)] = 0;
953 ok(!lstrcmpA(str_buf
, test_str2
), "got '%s' expected '%s'\n", str_buf
, test_str2
);
956 /* Now test output codepage handling. Current is 866 as we set earlier. */
957 SetConsoleCursorPosition(hConOutRW
, c
);
958 ret
= WriteConsoleA(hConOutRW
, test_cp866
, lstrlenA(test_cp866
), &len
, NULL
);
959 ok(ret
&& len
== lstrlenA(test_cp866
), "WriteConsoleA failed\n");
960 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenW(test_unicode
), c
, &len
);
961 /* Work around some broken results under Windows with some locale (ja, cn, ko...)
962 * Looks like a real bug in Win10 (at least).
964 if (ret
&& broken(len
== lstrlenW(test_unicode
) / sizeof(WCHAR
)))
965 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenW(test_unicode
) * sizeof(WCHAR
), c
, &len
);
966 ok(ret
, "ReadConsoleOutputCharacterW failed\n");
967 ok(len
== lstrlenW(test_unicode
), "unexpected len %lu %u\n", len
, lstrlenW(test_unicode
));
968 ok(!memcmp(str_wbuf
, test_unicode
, lstrlenW(test_unicode
) * sizeof(WCHAR
)),
969 "string does not match the pattern\n");
972 * cp866 is OK, let's switch to cp1251.
973 * We expect that this codepage will be used in every SB - active and not.
975 ok(SetConsoleOutputCP(1251), "Cannot set output cp to 1251\n");
976 SetConsoleCursorPosition(hConOutRW
, c
);
977 ret
= WriteConsoleA(hConOutRW
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
978 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
979 ret
= ReadConsoleOutputCharacterW(hConOutRW
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
980 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
981 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
982 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
984 /* Check what has happened to hConOut. */
985 SetConsoleCursorPosition(hConOut
, c
);
986 ret
= WriteConsoleA(hConOut
, test_cp1251
, lstrlenA(test_cp1251
), &len
, NULL
);
987 ok(ret
&& len
== lstrlenA(test_cp1251
), "WriteConsoleA failed\n");
988 ret
= ReadConsoleOutputCharacterW(hConOut
, str_wbuf
, lstrlenA(test_cp1251
), c
, &len
);
989 ok(ret
&& len
== lstrlenA(test_cp1251
), "ReadConsoleOutputCharacterW failed\n");
990 str_wbuf
[lstrlenA(test_cp1251
)] = 0;
991 ok(!lstrcmpW(str_wbuf
, test_unicode
), "string does not match the pattern\n");
993 /* Close all handles of current console SB */
994 CloseHandle(hConOutNew
);
995 CloseHandle(hConOutRW
);
997 /* Now active SB should be hConOut */
998 hConOutNew
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0,
999 NULL
, OPEN_EXISTING
, 0, 0);
1000 ok(hConOutNew
!= INVALID_HANDLE_VALUE
, "CONOUT$ is not opened\n");
1002 /* Write using hConOutNew... */
1003 SetConsoleCursorPosition(hConOutNew
, c
);
1004 ret
= WriteConsoleA(hConOutNew
, test_str1
, lstrlenA(test_str1
), &len
, NULL
);
1005 ok (ret
&& len
== lstrlenA(test_str1
), "WriteConsoleA failed\n");
1006 /* ... and read it back via hConOut */
1007 ret
= ReadConsoleOutputCharacterA(hConOut
, str_buf
, lstrlenA(test_str1
), c
, &len
);
1008 ok(ret
&& len
== lstrlenA(test_str1
), "ReadConsoleOutputCharacterA failed\n");
1009 str_buf
[lstrlenA(test_str1
)] = 0;
1010 todo_wine
ok(!lstrcmpA(str_buf
, test_str1
), "got '%s' expected '%s'\n", str_buf
, test_str1
);
1011 CloseHandle(hConOutNew
);
1013 /* This is not really needed under Windows */
1014 SetConsoleActiveScreenBuffer(hConOut
);
1016 /* restore codepage */
1017 SetConsoleOutputCP(oldcp
);
1020 static void test_new_screen_buffer_properties(HANDLE hConOut
)
1024 CONSOLE_FONT_INFOEX cfi
, cfi2
;
1025 CONSOLE_SCREEN_BUFFER_INFO csbi
, csbi2
;
1027 /* Font information */
1028 cfi
.cbSize
= cfi2
.cbSize
= sizeof(CONSOLE_FONT_INFOEX
);
1030 ret
= GetCurrentConsoleFontEx(hConOut
, FALSE
, &cfi
);
1031 ok(ret
, "GetCurrentConsoleFontEx failed: error %lu\n", GetLastError());
1033 hConOut2
= CreateConsoleScreenBuffer(GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1034 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1035 ok(hConOut2
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: error %lu\n", GetLastError());
1037 ret
= GetCurrentConsoleFontEx(hConOut2
, FALSE
, &cfi2
);
1038 ok(ret
, "GetCurrentConsoleFontEx failed: error %lu\n", GetLastError());
1039 CloseHandle(hConOut2
);
1041 ok(cfi2
.nFont
== cfi
.nFont
, "Font index should match: "
1042 "got %lu, expected %lu\n", cfi2
.nFont
, cfi
.nFont
);
1043 ok(cfi2
.dwFontSize
.X
== cfi
.dwFontSize
.X
, "Font width should match: "
1044 "got %d, expected %d\n", cfi2
.dwFontSize
.X
, cfi
.dwFontSize
.X
);
1045 ok(cfi2
.dwFontSize
.Y
== cfi
.dwFontSize
.Y
, "Font height should match: "
1046 "got %d, expected %d\n", cfi2
.dwFontSize
.Y
, cfi
.dwFontSize
.Y
);
1047 ok(cfi2
.FontFamily
== cfi
.FontFamily
, "Font family should match: "
1048 "got %u, expected %u\n", cfi2
.FontFamily
, cfi
.FontFamily
);
1049 ok(cfi2
.FontWeight
== cfi
.FontWeight
, "Font weight should match: "
1050 "got %u, expected %u\n", cfi2
.FontWeight
, cfi
.FontWeight
);
1051 ok(!lstrcmpW(cfi2
.FaceName
, cfi
.FaceName
), "Font name should match: "
1052 "got %s, expected %s\n", wine_dbgstr_w(cfi2
.FaceName
), wine_dbgstr_w(cfi
.FaceName
));
1054 /* Display window size */
1055 ret
= GetConsoleScreenBufferInfo(hConOut
, &csbi
);
1056 ok(ret
, "GetConsoleScreenBufferInfo failed: error %lu\n", GetLastError());
1058 hConOut2
= CreateConsoleScreenBuffer(GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1059 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1060 ok(hConOut2
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: error %lu\n", GetLastError());
1062 ret
= GetConsoleScreenBufferInfo(hConOut2
, &csbi2
);
1063 ok(ret
, "GetConsoleScreenBufferInfo failed: error %lu\n", GetLastError());
1064 CloseHandle(hConOut2
);
1066 ok(csbi2
.srWindow
.Left
== csbi
.srWindow
.Left
, "Left coordinate should match\n");
1067 ok(csbi2
.srWindow
.Top
== csbi
.srWindow
.Top
, "Top coordinate should match\n");
1068 ok(csbi2
.srWindow
.Right
== csbi
.srWindow
.Right
, "Right coordinate should match\n");
1069 ok(csbi2
.srWindow
.Bottom
== csbi
.srWindow
.Bottom
, "Bottom coordinate should match\n");
1072 static void test_new_screen_buffer_color_attributes(HANDLE hConOut
)
1074 CONSOLE_SCREEN_BUFFER_INFOEX csbi
, csbi2
;
1077 WORD orig_attr
, orig_popup
, attr
;
1079 csbi
.cbSize
= csbi2
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
1081 ret
= GetConsoleScreenBufferInfoEx(hConOut
, &csbi
);
1082 ok(ret
, "GetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1083 orig_attr
= csbi
.wAttributes
;
1084 orig_popup
= csbi
.wPopupAttributes
;
1086 hConOut2
= CreateConsoleScreenBuffer(GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1087 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1088 ok(hConOut2
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: error %lu\n", GetLastError());
1090 ret
= GetConsoleScreenBufferInfoEx(hConOut2
, &csbi2
);
1091 ok(ret
, "GetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1092 CloseHandle(hConOut2
);
1094 ok(csbi2
.wAttributes
== orig_attr
, "Character Attributes should have been copied: "
1095 "got %#x, expected %#x\n", csbi2
.wAttributes
, orig_attr
);
1096 ok(csbi2
.wPopupAttributes
!= orig_popup
, "Popup Attributes should not match original value\n");
1097 ok(csbi2
.wPopupAttributes
== orig_attr
, "Popup Attributes should match Character Attributes\n");
1099 /* Test different Character Attributes */
1100 attr
= FOREGROUND_BLUE
|BACKGROUND_GREEN
;
1101 ret
= SetConsoleTextAttribute(hConOut
, attr
);
1102 ok(ret
, "SetConsoleTextAttribute failed: error %lu\n", GetLastError());
1104 hConOut2
= CreateConsoleScreenBuffer(GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1105 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1106 ok(hConOut2
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: error %lu\n", GetLastError());
1108 memset(&csbi2
, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
));
1109 csbi2
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
1111 ret
= GetConsoleScreenBufferInfoEx(hConOut2
, &csbi2
);
1112 ok(ret
, "GetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1113 CloseHandle(hConOut2
);
1115 ok(csbi2
.wAttributes
== attr
, "Character Attributes should have been copied: "
1116 "got %#x, expected %#x\n", csbi2
.wAttributes
, attr
);
1117 ok(csbi2
.wPopupAttributes
!= orig_popup
, "Popup Attributes should not match original value\n");
1118 ok(csbi2
.wPopupAttributes
== attr
, "Popup Attributes should match Character Attributes\n");
1120 ret
= SetConsoleTextAttribute(hConOut
, orig_attr
);
1121 ok(ret
, "SetConsoleTextAttribute failed: error %lu\n", GetLastError());
1123 /* Test inheritance of different Popup Attributes */
1124 csbi
.wPopupAttributes
= attr
;
1125 ret
= SetConsoleScreenBufferInfoEx(hConOut
, &csbi
);
1126 ok(ret
, "SetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1128 hConOut2
= CreateConsoleScreenBuffer(GENERIC_READ
|GENERIC_WRITE
, 0, NULL
,
1129 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1130 ok(hConOut2
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: error %lu\n", GetLastError());
1132 memset(&csbi2
, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
));
1133 csbi2
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
1135 ret
= GetConsoleScreenBufferInfoEx(hConOut2
, &csbi2
);
1136 ok(ret
, "GetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1137 CloseHandle(hConOut2
);
1139 ok(csbi2
.wAttributes
== orig_attr
, "Character Attributes should have been copied: "
1140 "got %#x, expected %#x\n", csbi2
.wAttributes
, orig_attr
);
1141 ok(csbi2
.wPopupAttributes
!= orig_popup
, "Popup Attributes should not match original value\n");
1142 ok(csbi2
.wPopupAttributes
== orig_attr
, "Popup Attributes should match Character Attributes\n");
1144 csbi
.wPopupAttributes
= orig_popup
;
1145 ret
= SetConsoleScreenBufferInfoEx(hConOut
, &csbi
);
1146 ok(ret
, "SetConsoleScreenBufferInfoEx failed: error %lu\n", GetLastError());
1149 static void CALLBACK
signaled_function(void *p
, BOOLEAN timeout
)
1153 ok(!timeout
, "wait shouldn't have timed out\n");
1156 static void testWaitForConsoleInput(HANDLE input_handle
)
1159 HANDLE complete_event
;
1160 INPUT_RECORD record
;
1161 DWORD events_written
;
1165 complete_event
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
1167 /* Test success case */
1168 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
1169 ok(ret
== TRUE
, "Expected RegisterWaitForSingleObject to return TRUE, got %d\n", ret
);
1170 /* give worker thread a chance to start up */
1172 record
.EventType
= KEY_EVENT
;
1173 record
.Event
.KeyEvent
.bKeyDown
= 1;
1174 record
.Event
.KeyEvent
.wRepeatCount
= 1;
1175 record
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
1176 record
.Event
.KeyEvent
.wVirtualScanCode
= VK_RETURN
;
1177 record
.Event
.KeyEvent
.uChar
.UnicodeChar
= '\r';
1178 record
.Event
.KeyEvent
.dwControlKeyState
= 0;
1179 ret
= WriteConsoleInputW(input_handle
, &record
, 1, &events_written
);
1180 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
1181 wait_ret
= WaitForSingleObject(complete_event
, INFINITE
);
1182 ok(wait_ret
== WAIT_OBJECT_0
, "Expected the handle to be signaled\n");
1183 ret
= UnregisterWait(wait_handle
);
1184 /* If the callback is still running, this fails with ERROR_IO_PENDING, but
1185 that's ok and expected. */
1186 ok(ret
!= 0 || GetLastError() == ERROR_IO_PENDING
,
1187 "UnregisterWait failed with error %ld\n", GetLastError());
1189 /* Test timeout case */
1190 FlushConsoleInputBuffer(input_handle
);
1191 ret
= RegisterWaitForSingleObject(&wait_handle
, input_handle
, signaled_function
, complete_event
, INFINITE
, WT_EXECUTEONLYONCE
);
1192 wait_ret
= WaitForSingleObject(complete_event
, 100);
1193 ok(wait_ret
== WAIT_TIMEOUT
, "Expected the wait to time out\n");
1194 ret
= UnregisterWait(wait_handle
);
1195 ok(ret
, "UnregisterWait failed with error %ld\n", GetLastError());
1198 CloseHandle(complete_event
);
1201 static void test_wait(HANDLE input
, HANDLE orig_output
)
1203 HANDLE output
, unbound_output
, unbound_input
;
1210 if (skip_nt
) return;
1212 memset(&ir
, 0, sizeof(ir
));
1213 ir
.EventType
= MOUSE_EVENT
;
1214 ir
.Event
.MouseEvent
.dwEventFlags
= MOUSE_MOVED
;
1217 output
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
1218 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
1219 CONSOLE_TEXTMODE_BUFFER
, NULL
);
1220 ok(output
!= INVALID_HANDLE_VALUE
, "CreateConsoleScreenBuffer failed: %lu\n", GetLastError());
1222 ret
= SetConsoleActiveScreenBuffer(output
);
1223 ok(ret
, "SetConsoleActiveScreenBuffer failed: %lu\n", GetLastError());
1224 FlushConsoleInputBuffer(input
);
1226 unbound_output
= create_unbound_handle(TRUE
, TRUE
);
1227 unbound_input
= create_unbound_handle(FALSE
, TRUE
);
1229 res
= WaitForSingleObject(input
, 0);
1230 ok(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", res
);
1231 res
= WaitForSingleObject(output
, 0);
1232 ok(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", res
);
1233 res
= WaitForSingleObject(orig_output
, 0);
1234 ok(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", res
);
1235 res
= WaitForSingleObject(unbound_output
, 0);
1236 ok(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", res
);
1237 res
= WaitForSingleObject(unbound_input
, 0);
1238 ok(res
== WAIT_TIMEOUT
, "WaitForSingleObject returned %lx\n", res
);
1239 status
= NtWaitForSingleObject(input
, FALSE
, &zero
);
1240 ok(status
== STATUS_TIMEOUT
|| broken(status
== STATUS_ACCESS_DENIED
/* win2k8 */),
1241 "NtWaitForSingleObject returned %lx\n", status
);
1242 status
= NtWaitForSingleObject(output
, FALSE
, &zero
);
1243 ok(status
== STATUS_TIMEOUT
|| broken(status
== STATUS_ACCESS_DENIED
/* win2k8 */),
1244 "NtWaitForSingleObject returned %lx\n", status
);
1246 ret
= WriteConsoleInputW(input
, &ir
, 1, &count
);
1247 ok(ret
, "WriteConsoleInputW failed: %lu\n", GetLastError());
1249 res
= WaitForSingleObject(input
, 0);
1250 ok(!res
, "WaitForSingleObject returned %lx\n", res
);
1251 res
= WaitForSingleObject(output
, 0);
1252 ok(!res
, "WaitForSingleObject returned %lx\n", res
);
1253 res
= WaitForSingleObject(orig_output
, 0);
1254 ok(!res
, "WaitForSingleObject returned %lx\n", res
);
1255 res
= WaitForSingleObject(unbound_output
, 0);
1256 ok(!res
, "WaitForSingleObject returned %lx\n", res
);
1257 res
= WaitForSingleObject(unbound_input
, 0);
1258 ok(!res
, "WaitForSingleObject returned %lx\n", res
);
1259 status
= NtWaitForSingleObject(input
, FALSE
, &zero
);
1260 ok(!status
|| broken(status
== STATUS_ACCESS_DENIED
/* win2k8 */),
1261 "NtWaitForSingleObject returned %lx\n", status
);
1262 status
= NtWaitForSingleObject(output
, FALSE
, &zero
);
1263 ok(!status
|| broken(status
== STATUS_ACCESS_DENIED
/* win2k8 */),
1264 "NtWaitForSingleObject returned %lx\n", status
);
1266 ret
= SetConsoleActiveScreenBuffer(orig_output
);
1267 ok(ret
, "SetConsoleActiveScreenBuffer failed: %lu\n", GetLastError());
1269 CloseHandle(unbound_input
);
1270 CloseHandle(unbound_output
);
1271 CloseHandle(output
);
1274 static void test_GetSetConsoleInputExeName(void)
1278 char buffer
[MAX_PATH
], module
[MAX_PATH
], *p
;
1279 static char input_exe
[MAX_PATH
] = "winetest.exe";
1281 SetLastError(0xdeadbeef);
1282 ret
= pGetConsoleInputExeNameA(0, NULL
);
1283 error
= GetLastError();
1284 ok(ret
, "GetConsoleInputExeNameA failed\n");
1285 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %lu expected ERROR_BUFFER_OVERFLOW\n", error
);
1287 SetLastError(0xdeadbeef);
1288 ret
= pGetConsoleInputExeNameA(0, buffer
);
1289 error
= GetLastError();
1290 ok(ret
, "GetConsoleInputExeNameA failed\n");
1291 ok(error
== ERROR_BUFFER_OVERFLOW
, "got %lu expected ERROR_BUFFER_OVERFLOW\n", error
);
1293 GetModuleFileNameA(GetModuleHandleA(NULL
), module
, sizeof(module
));
1294 p
= strrchr(module
, '\\') + 1;
1296 ret
= pGetConsoleInputExeNameA(ARRAY_SIZE(buffer
), buffer
);
1297 ok(ret
, "GetConsoleInputExeNameA failed\n");
1298 todo_wine
ok(!lstrcmpA(buffer
, p
), "got %s expected %s\n", buffer
, p
);
1300 SetLastError(0xdeadbeef);
1301 ret
= pSetConsoleInputExeNameA(NULL
);
1302 error
= GetLastError();
1303 ok(!ret
, "SetConsoleInputExeNameA failed\n");
1304 ok(error
== ERROR_INVALID_PARAMETER
, "got %lu expected ERROR_INVALID_PARAMETER\n", error
);
1306 SetLastError(0xdeadbeef);
1307 ret
= pSetConsoleInputExeNameA("");
1308 error
= GetLastError();
1309 ok(!ret
, "SetConsoleInputExeNameA failed\n");
1310 ok(error
== ERROR_INVALID_PARAMETER
, "got %lu expected ERROR_INVALID_PARAMETER\n", error
);
1312 ret
= pSetConsoleInputExeNameA(input_exe
);
1313 ok(ret
, "SetConsoleInputExeNameA failed\n");
1315 ret
= pGetConsoleInputExeNameA(ARRAY_SIZE(buffer
), buffer
);
1316 ok(ret
, "GetConsoleInputExeNameA failed\n");
1317 ok(!lstrcmpA(buffer
, input_exe
), "got %s expected %s\n", buffer
, input_exe
);
1320 static void test_GetConsoleProcessList(void)
1322 DWORD ret
, *list
= NULL
;
1324 if (!pGetConsoleProcessList
)
1326 win_skip("GetConsoleProcessList is not available\n");
1330 SetLastError(0xdeadbeef);
1331 ret
= pGetConsoleProcessList(NULL
, 0);
1332 ok(ret
== 0, "Expected failure\n");
1333 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1334 "Expected ERROR_INVALID_PARAMETER, got %ld\n",
1337 SetLastError(0xdeadbeef);
1338 ret
= pGetConsoleProcessList(NULL
, 1);
1339 ok(ret
== 0, "Expected failure\n");
1340 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1341 "Expected ERROR_INVALID_PARAMETER, got %ld\n",
1344 /* We should only have 1 process but only for these specific unit tests as
1345 * we created our own console. An AttachConsole(ATTACH_PARENT_PROCESS)
1346 * gives us two processes - see test_AttachConsole.
1348 list
= HeapAlloc(GetProcessHeap(), 0, sizeof(DWORD
));
1350 SetLastError(0xdeadbeef);
1351 ret
= pGetConsoleProcessList(list
, 0);
1352 ok(ret
== 0, "Expected failure\n");
1353 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
1354 "Expected ERROR_INVALID_PARAMETER, got %ld\n",
1357 SetLastError(0xdeadbeef);
1358 ret
= pGetConsoleProcessList(list
, 1);
1359 ok(ret
== 1, "Expected 1, got %ld\n", ret
);
1361 HeapFree(GetProcessHeap(), 0, list
);
1363 list
= HeapAlloc(GetProcessHeap(), 0, ret
* sizeof(DWORD
));
1365 SetLastError(0xdeadbeef);
1366 ret
= pGetConsoleProcessList(list
, ret
);
1367 ok(ret
== 1, "Expected 1, got %ld\n", ret
);
1371 DWORD pid
= GetCurrentProcessId();
1372 ok(list
[0] == pid
, "Expected %ld, got %ld\n", pid
, list
[0]);
1375 HeapFree(GetProcessHeap(), 0, list
);
1378 static void test_OpenCON(void)
1380 static const WCHAR conW
[] = {'C','O','N',0};
1381 static const DWORD accesses
[] = {CREATE_NEW
, CREATE_ALWAYS
, OPEN_EXISTING
,
1382 OPEN_ALWAYS
, TRUNCATE_EXISTING
};
1386 for (i
= 0; i
< ARRAY_SIZE(accesses
); i
++)
1388 h
= CreateFileW(conW
, GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1389 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win8 */),
1390 "Expected to open the CON device on write (%lx)\n", accesses
[i
]);
1393 h
= CreateFileW(conW
, GENERIC_READ
, 0, NULL
, accesses
[i
], 0, NULL
);
1394 /* Windows versions differ here:
1395 * MSDN states in CreateFile that TRUNCATE_EXISTING requires GENERIC_WRITE
1396 * NT, XP, Vista comply, but Win7 doesn't and allows opening CON with TRUNCATE_EXISTING
1397 * So don't test when disposition is TRUNCATE_EXISTING
1399 ok(h
!= INVALID_HANDLE_VALUE
|| broken(accesses
[i
] == TRUNCATE_EXISTING
/* Win7+ */),
1400 "Expected to open the CON device on read (%lx)\n", accesses
[i
]);
1402 h
= CreateFileW(conW
, GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, accesses
[i
], 0, NULL
);
1403 ok(h
== INVALID_HANDLE_VALUE
, "Expected not to open the CON device on read-write (%lx)\n", accesses
[i
]);
1404 ok(GetLastError() == ERROR_FILE_NOT_FOUND
|| GetLastError() == ERROR_INVALID_PARAMETER
,
1405 "Unexpected error %lx\n", GetLastError());
1409 static void test_OpenConsoleW(void)
1411 static const WCHAR coninW
[] = {'C','O','N','I','N','$',0};
1412 static const WCHAR conoutW
[] = {'C','O','N','O','U','T','$',0};
1413 static const WCHAR emptyW
[] = {0};
1414 static const WCHAR invalidW
[] = {'I','N','V','A','L','I','D',0};
1424 } invalid_table
[] = {
1425 {NULL
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1426 {NULL
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1427 {NULL
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1428 {NULL
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1429 {NULL
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1430 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1431 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1432 {NULL
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1433 {emptyW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1434 {emptyW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1435 {emptyW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1436 {emptyW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1437 {emptyW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1438 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1439 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1440 {emptyW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_PATH_NOT_FOUND
},
1441 {invalidW
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1442 {invalidW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1443 {invalidW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1444 {invalidW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1445 {invalidW
, 0, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1446 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1447 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1448 {invalidW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
, ERROR_INVALID_PARAMETER
, ERROR_FILE_NOT_FOUND
},
1449 {coninW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1450 {coninW
, 0xdeadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1451 {coninW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1452 {conoutW
, 0, FALSE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1453 {conoutW
, 0xceadbeef, FALSE
, 0, ERROR_INVALID_PARAMETER
, ERROR_ACCESS_DENIED
},
1454 {conoutW
, 0xdeadbeef, TRUE
, 0xdeadbeef, ERROR_INVALID_PARAMETER
, 0},
1463 {coninW
, 0, FALSE
, 0 },
1464 {coninW
, 0, TRUE
, 0 },
1465 {coninW
, GENERIC_EXECUTE
, TRUE
, 0 },
1466 {coninW
, GENERIC_ALL
, TRUE
, 0 },
1467 {coninW
, 0, FALSE
, OPEN_ALWAYS
},
1468 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1469 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
},
1470 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1471 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1472 {coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1473 {conoutW
, 0, FALSE
, 0 },
1474 {conoutW
, 0, FALSE
, OPEN_ALWAYS
},
1475 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0 },
1476 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, },
1477 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
},
1478 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
},
1479 {conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, TRUNCATE_EXISTING
},
1487 win_skip("OpenConsoleW is not available\n");
1491 for (index
= 0; index
< ARRAY_SIZE(invalid_table
); index
++)
1493 SetLastError(0xdeadbeef);
1494 ret
= pOpenConsoleW(invalid_table
[index
].name
, invalid_table
[index
].access
,
1495 invalid_table
[index
].inherit
, invalid_table
[index
].creation
);
1496 gle
= GetLastError();
1497 ok(ret
== INVALID_HANDLE_VALUE
,
1498 "Expected OpenConsoleW to return INVALID_HANDLE_VALUE for index %d, got %p\n",
1500 ok(gle
== invalid_table
[index
].gle
|| (gle
!= 0 && gle
== invalid_table
[index
].gle2
),
1501 "Expected GetLastError() to return %lu/%lu for index %d, got %lu\n",
1502 invalid_table
[index
].gle
, invalid_table
[index
].gle2
, index
, gle
);
1505 for (index
= 0; index
< ARRAY_SIZE(valid_table
); index
++)
1507 ret
= pOpenConsoleW(valid_table
[index
].name
, valid_table
[index
].access
,
1508 valid_table
[index
].inherit
, valid_table
[index
].creation
);
1510 ok(ret
!= INVALID_HANDLE_VALUE
|| broken(ret
== INVALID_HANDLE_VALUE
/* until Win7 */),
1511 "Expected OpenConsoleW to succeed for index %d, got %p\n", index
, ret
);
1512 if (ret
!= INVALID_HANDLE_VALUE
)
1516 ret
= pOpenConsoleW(coninW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1517 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1518 if (ret
!= INVALID_HANDLE_VALUE
)
1521 ret
= pOpenConsoleW(conoutW
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_EXISTING
);
1522 ok(ret
!= INVALID_HANDLE_VALUE
, "Expected OpenConsoleW to return a valid handle\n");
1523 if (ret
!= INVALID_HANDLE_VALUE
)
1527 static void test_CreateFileW(void)
1538 {TRUE
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1539 {TRUE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1540 {TRUE
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1541 {TRUE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1542 {TRUE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1543 {TRUE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1544 {FALSE
, 0, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1545 {FALSE
, 0, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1546 {FALSE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, 0, ERROR_INVALID_PARAMETER
, TRUE
},
1547 {FALSE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_NEW
, 0, FALSE
},
1548 {FALSE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, CREATE_ALWAYS
, 0, FALSE
},
1549 {FALSE
, GENERIC_READ
| GENERIC_WRITE
, FALSE
, OPEN_ALWAYS
, 0, FALSE
},
1550 /* TRUNCATE_EXISTING is forbidden starting with Windows 8 */
1553 static const UINT nt_disposition
[5] =
1555 FILE_CREATE
, /* CREATE_NEW */
1556 FILE_OVERWRITE_IF
, /* CREATE_ALWAYS */
1557 FILE_OPEN
, /* OPEN_EXISTING */
1558 FILE_OPEN_IF
, /* OPEN_ALWAYS */
1559 FILE_OVERWRITE
/* TRUNCATE_EXISTING */
1564 SECURITY_ATTRIBUTES sa
;
1565 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
1566 UNICODE_STRING string
;
1567 IO_STATUS_BLOCK iosb
;
1570 for (index
= 0; index
< ARRAY_SIZE(cf_table
); index
++)
1572 SetLastError(0xdeadbeef);
1574 sa
.nLength
= sizeof(sa
);
1575 sa
.lpSecurityDescriptor
= NULL
;
1576 sa
.bInheritHandle
= cf_table
[index
].inherit
;
1578 ret
= CreateFileW(cf_table
[index
].input
? L
"CONIN$" : L
"CONOUT$", cf_table
[index
].access
,
1579 FILE_SHARE_READ
|FILE_SHARE_WRITE
, &sa
,
1580 cf_table
[index
].creation
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1581 if (ret
== INVALID_HANDLE_VALUE
)
1583 ok(cf_table
[index
].gle
,
1584 "Expected CreateFileW not to return INVALID_HANDLE_VALUE for index %d\n", index
);
1585 ok(GetLastError() == cf_table
[index
].gle
,
1586 "Expected GetLastError() to return %lu for index %d, got %lu\n",
1587 cf_table
[index
].gle
, index
, GetLastError());
1591 ok(!cf_table
[index
].gle
|| broken(cf_table
[index
].is_broken
) /* Win7 */,
1592 "Expected CreateFileW to succeed for index %d\n", index
);
1596 if (skip_nt
) continue;
1598 SetLastError(0xdeadbeef);
1600 sa
.nLength
= sizeof(sa
);
1601 sa
.lpSecurityDescriptor
= NULL
;
1602 sa
.bInheritHandle
= cf_table
[index
].inherit
;
1604 ret
= CreateFileW(cf_table
[index
].input
? L
"\\??\\CONIN$" : L
"\\??\\CONOUT$", cf_table
[index
].access
,
1605 FILE_SHARE_READ
|FILE_SHARE_WRITE
, &sa
,
1606 cf_table
[index
].creation
, FILE_ATTRIBUTE_NORMAL
, NULL
);
1607 if (cf_table
[index
].gle
)
1608 ok(ret
== INVALID_HANDLE_VALUE
&& GetLastError() == cf_table
[index
].gle
,
1609 "CreateFileW to returned %p %lu for index %d\n", ret
, GetLastError(), index
);
1611 ok(ret
!= INVALID_HANDLE_VALUE
&& (!cf_table
[index
].gle
|| broken(cf_table
[index
].is_broken
) /* Win7 */),
1612 "CreateFileW to returned %p %lu for index %d\n", ret
, GetLastError(), index
);
1613 if (ret
!= INVALID_HANDLE_VALUE
) CloseHandle(ret
);
1615 if (cf_table
[index
].gle
) continue;
1617 RtlInitUnicodeString(&string
, cf_table
[index
].input
1618 ? L
"\\Device\\ConDrv\\CurrentIn" : L
"\\Device\\ConDrv\\CurrentOut");
1619 attr
.ObjectName
= &string
;
1620 status
= NtCreateFile(&ret
, cf_table
[index
].access
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
, &attr
, &iosb
, NULL
,
1621 FILE_ATTRIBUTE_NORMAL
, 0, nt_disposition
[cf_table
[index
].creation
- CREATE_NEW
],
1622 FILE_NON_DIRECTORY_FILE
, NULL
, 0);
1623 ok(!status
, "NtCreateFile failed %lx for %u\n", status
, index
);
1626 RtlInitUnicodeString(&string
, cf_table
[index
].input
? L
"\\??\\CONIN$" : L
"\\??\\CONOUT$");
1627 attr
.ObjectName
= &string
;
1628 status
= NtCreateFile(&ret
, cf_table
[index
].access
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
, &attr
, &iosb
, NULL
,
1629 FILE_ATTRIBUTE_NORMAL
, 0, nt_disposition
[cf_table
[index
].creation
- CREATE_NEW
],
1630 FILE_NON_DIRECTORY_FILE
, NULL
, 0);
1631 ok(!status
, "NtCreateFile failed %lx for %u\n", status
, index
);
1636 static void test_VerifyConsoleIoHandle( HANDLE handle
)
1641 if (!pVerifyConsoleIoHandle
)
1643 win_skip("VerifyConsoleIoHandle is not available\n");
1647 /* invalid handle */
1648 SetLastError(0xdeadbeef);
1649 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee0);
1650 error
= GetLastError();
1651 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1652 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1654 /* invalid handle + 1 */
1655 SetLastError(0xdeadbeef);
1656 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee1);
1657 error
= GetLastError();
1658 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1659 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1661 /* invalid handle + 2 */
1662 SetLastError(0xdeadbeef);
1663 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee2);
1664 error
= GetLastError();
1665 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1666 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1668 /* invalid handle + 3 */
1669 SetLastError(0xdeadbeef);
1670 ret
= pVerifyConsoleIoHandle((HANDLE
)0xdeadbee3);
1671 error
= GetLastError();
1672 ok(!ret
, "expected VerifyConsoleIoHandle to fail\n");
1673 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1676 SetLastError(0xdeadbeef);
1677 ret
= pVerifyConsoleIoHandle(handle
);
1678 error
= GetLastError();
1680 broken(!ret
), /* Windows 8 and 10 */
1681 "expected VerifyConsoleIoHandle to succeed\n");
1682 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1685 static void test_GetSetStdHandle(void)
1691 /* get invalid std handle */
1692 SetLastError(0xdeadbeef);
1693 handle
= GetStdHandle(42);
1694 error
= GetLastError();
1695 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1696 "wrong GetLastError() %ld\n", error
);
1697 ok(handle
== INVALID_HANDLE_VALUE
, "expected INVALID_HANDLE_VALUE\n");
1700 SetLastError(0xdeadbeef);
1701 handle
= GetStdHandle(STD_INPUT_HANDLE
);
1702 error
= GetLastError();
1703 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1705 /* set invalid std handle */
1706 SetLastError(0xdeadbeef);
1707 ret
= SetStdHandle(42, handle
);
1708 error
= GetLastError();
1709 ok(!ret
, "expected SetStdHandle to fail\n");
1710 ok(error
== ERROR_INVALID_HANDLE
|| broken(error
== ERROR_INVALID_FUNCTION
)/* Win9x */,
1711 "wrong GetLastError() %ld\n", error
);
1713 /* set valid (restore old value) */
1714 SetLastError(0xdeadbeef);
1715 ret
= SetStdHandle(STD_INPUT_HANDLE
, handle
);
1716 error
= GetLastError();
1717 ok(ret
, "expected SetStdHandle to succeed\n");
1718 ok(error
== 0xdeadbeef, "wrong GetLastError() %ld\n", error
);
1721 static void test_DuplicateConsoleHandle(void)
1723 HANDLE handle
, event
;
1726 if (skip_nt
) return;
1728 event
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
1730 /* duplicate an event handle with DuplicateConsoleHandle */
1731 handle
= DuplicateConsoleHandle(event
, 0, FALSE
, DUPLICATE_SAME_ACCESS
);
1732 ok(handle
!= NULL
, "DuplicateConsoleHandle failed: %lu\n", GetLastError());
1734 ret
= SetEvent(handle
);
1735 ok(ret
, "SetEvent failed: %lu\n", GetLastError());
1737 ret
= CloseConsoleHandle(handle
);
1738 ok(ret
, "CloseConsoleHandle failed: %lu\n", GetLastError());
1739 ret
= CloseConsoleHandle(event
);
1740 ok(ret
, "CloseConsoleHandle failed: %lu\n", GetLastError());
1742 handle
= DuplicateConsoleHandle((HANDLE
)0xdeadbeef, 0, FALSE
, DUPLICATE_SAME_ACCESS
);
1743 ok(handle
== INVALID_HANDLE_VALUE
, "DuplicateConsoleHandle failed: %lu\n", GetLastError());
1744 ok(GetLastError() == ERROR_INVALID_HANDLE
, "last error = %lu\n", GetLastError());
1747 static void test_GetNumberOfConsoleInputEvents(HANDLE input_handle
)
1760 {NULL
, NULL
, ERROR_INVALID_HANDLE
},
1761 {NULL
, &count
, ERROR_INVALID_HANDLE
},
1762 {INVALID_HANDLE_VALUE
, NULL
, ERROR_INVALID_HANDLE
},
1763 {INVALID_HANDLE_VALUE
, &count
, ERROR_INVALID_HANDLE
},
1766 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
1768 SetLastError(0xdeadbeef);
1769 if (invalid_table
[i
].nrofevents
) count
= 0xdeadbeef;
1770 ret
= GetNumberOfConsoleInputEvents(invalid_table
[i
].handle
,
1771 invalid_table
[i
].nrofevents
);
1772 ok(!ret
, "[%d] Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", i
, ret
);
1773 if (invalid_table
[i
].nrofevents
)
1775 ok(count
== 0xdeadbeef,
1776 "[%d] Expected output count to be unmodified, got %lu\n", i
, count
);
1778 ok(GetLastError() == invalid_table
[i
].last_error
,
1779 "[%d] Expected last error to be %lu, got %lu\n",
1780 i
, invalid_table
[i
].last_error
, GetLastError());
1783 /* Test crashes on Windows 7. */
1786 SetLastError(0xdeadbeef);
1787 ret
= GetNumberOfConsoleInputEvents(input_handle
, NULL
);
1788 ok(!ret
, "Expected GetNumberOfConsoleInputEvents to return FALSE, got %d\n", ret
);
1789 ok(GetLastError() == ERROR_INVALID_ACCESS
,
1790 "Expected last error to be ERROR_INVALID_ACCESS, got %lu\n",
1795 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1796 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1797 ok(count
!= 0xdeadbeef, "Expected output count to initialized\n");
1800 static void test_WriteConsoleInputA(HANDLE input_handle
)
1803 INPUT_RECORD event_list
[5];
1804 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
1805 KEY_EVENT_RECORD key_event
;
1806 DWORD count
, console_mode
, gle
;
1813 const INPUT_RECORD
*buffer
;
1820 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1821 {NULL
, NULL
, 0, &count
,ERROR_INVALID_HANDLE
},
1822 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1823 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1824 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1825 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1826 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1827 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1828 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1829 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
1830 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1831 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
1832 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1833 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
1834 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1835 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
1836 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1837 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1838 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
1839 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1840 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
1843 /* Suppress external sources of input events for the duration of the test. */
1844 ret
= GetConsoleMode(input_handle
, &console_mode
);
1845 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
1848 skip("GetConsoleMode failed with last error %lu\n", GetLastError());
1852 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
1853 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
1856 skip("SetConsoleMode failed with last error %lu\n", GetLastError());
1860 /* Discard any events queued before the tests. */
1861 ret
= FlushConsoleInputBuffer(input_handle
);
1862 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1864 event
.EventType
= MOUSE_EVENT
;
1865 event
.Event
.MouseEvent
= mouse_event
;
1867 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
1869 if (invalid_table
[i
].win_crash
)
1872 SetLastError(0xdeadbeef);
1873 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
1874 ret
= WriteConsoleInputA(invalid_table
[i
].handle
,
1875 invalid_table
[i
].buffer
,
1876 invalid_table
[i
].count
,
1877 invalid_table
[i
].written
);
1878 ok(!ret
, "[%d] Expected WriteConsoleInputA to return FALSE, got %d\n", i
, ret
);
1879 gle
= GetLastError();
1880 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
1881 "[%d] Expected last error to be %lu or %lu, got %lu\n",
1882 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
1886 ret
= WriteConsoleInputA(input_handle
, NULL
, 0, &count
);
1887 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1888 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
1891 ret
= WriteConsoleInputA(input_handle
, &event
, 0, &count
);
1892 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1893 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
1896 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1897 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1898 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1900 ret
= FlushConsoleInputBuffer(input_handle
);
1901 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1903 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
1904 event
.EventType
= MOUSE_EVENT
;
1905 event
.Event
.MouseEvent
= mouse_event
;
1907 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1908 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1909 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1911 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1912 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1913 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1915 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1916 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1917 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1919 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1920 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1922 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1924 ret
= FlushConsoleInputBuffer(input_handle
);
1925 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1927 for (i
= 0; i
< ARRAY_SIZE(event_list
); i
++)
1929 event_list
[i
].EventType
= MOUSE_EVENT
;
1930 event_list
[i
].Event
.MouseEvent
= mouse_event
;
1933 /* Writing consecutive chunks of mouse events appears to work. */
1934 ret
= WriteConsoleInputA(input_handle
, event_list
, ARRAY_SIZE(event_list
), &count
);
1935 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1936 ok(count
== ARRAY_SIZE(event_list
),
1937 "Expected count to be event list length, got %lu\n", count
);
1939 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1940 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1941 ok(count
== ARRAY_SIZE(event_list
),
1942 "Expected count to be event list length, got %lu\n", count
);
1944 ret
= WriteConsoleInputA(input_handle
, event_list
, ARRAY_SIZE(event_list
), &count
);
1945 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1946 ok(count
== ARRAY_SIZE(event_list
),
1947 "Expected count to be event list length, got %lu\n", count
);
1949 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1950 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1951 ok(count
== 2*ARRAY_SIZE(event_list
),
1952 "Expected count to be twice event list length, got %lu\n", count
);
1954 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
1955 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1956 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1957 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1959 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1960 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1962 ok(count
== 2*ARRAY_SIZE(event_list
),
1963 "Expected count to be twice event list length, got %lu\n", count
);
1965 ret
= FlushConsoleInputBuffer(input_handle
);
1966 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1968 key_event
.bKeyDown
= FALSE
;
1969 key_event
.wRepeatCount
= 0;
1970 key_event
.wVirtualKeyCode
= VK_SPACE
;
1971 key_event
.wVirtualScanCode
= VK_SPACE
;
1972 key_event
.uChar
.AsciiChar
= ' ';
1973 key_event
.dwControlKeyState
= 0;
1975 event
.EventType
= KEY_EVENT
;
1976 event
.Event
.KeyEvent
= key_event
;
1978 /* Key events don't exhibit the same behavior as mouse events. */
1979 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1980 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1981 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1983 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1984 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1985 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1987 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
1988 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
1989 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
1991 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
1992 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
1993 ok(count
== 2, "Expected count to be 2, got %lu\n", count
);
1995 ret
= FlushConsoleInputBuffer(input_handle
);
1996 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
1998 /* Try interleaving mouse and key events. */
1999 event
.EventType
= MOUSE_EVENT
;
2000 event
.Event
.MouseEvent
= mouse_event
;
2002 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
2003 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
2004 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2006 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2007 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2008 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2010 event
.EventType
= KEY_EVENT
;
2011 event
.Event
.KeyEvent
= key_event
;
2013 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
2014 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
2015 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2017 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2018 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2019 ok(count
== 2, "Expected count to be 2, got %lu\n", count
);
2021 event
.EventType
= MOUSE_EVENT
;
2022 event
.Event
.MouseEvent
= mouse_event
;
2024 ret
= WriteConsoleInputA(input_handle
, &event
, 1, &count
);
2025 ok(ret
== TRUE
, "Expected WriteConsoleInputA to return TRUE, got %d\n", ret
);
2026 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2028 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2029 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2030 ok(count
== 3, "Expected count to be 3, got %lu\n", count
);
2032 /* Restore the old console mode. */
2033 ret
= SetConsoleMode(input_handle
, console_mode
);
2034 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
2037 static void test_WriteConsoleInputW(HANDLE input_handle
)
2040 INPUT_RECORD event_list
[5];
2041 MOUSE_EVENT_RECORD mouse_event
= { {0, 0}, 0, 0, MOUSE_MOVED
};
2042 KEY_EVENT_RECORD key_event
;
2043 DWORD count
, console_mode
, gle
;
2050 const INPUT_RECORD
*buffer
;
2057 {NULL
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2058 {NULL
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
2059 {NULL
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2060 {NULL
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
2061 {NULL
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2062 {NULL
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
2063 {NULL
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2064 {NULL
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
2065 {INVALID_HANDLE_VALUE
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2066 {INVALID_HANDLE_VALUE
, NULL
, 0, &count
, ERROR_INVALID_HANDLE
},
2067 {INVALID_HANDLE_VALUE
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2068 {INVALID_HANDLE_VALUE
, NULL
, 1, &count
, ERROR_INVALID_HANDLE
, ERROR_INVALID_ACCESS
},
2069 {INVALID_HANDLE_VALUE
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2070 {INVALID_HANDLE_VALUE
, &event
, 0, &count
, ERROR_INVALID_HANDLE
},
2071 {INVALID_HANDLE_VALUE
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2072 {INVALID_HANDLE_VALUE
, &event
, 1, &count
, ERROR_INVALID_HANDLE
},
2073 {input_handle
, NULL
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2074 {input_handle
, NULL
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2075 {input_handle
, NULL
, 1, &count
, ERROR_NOACCESS
, ERROR_INVALID_ACCESS
},
2076 {input_handle
, &event
, 0, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2077 {input_handle
, &event
, 1, NULL
, ERROR_INVALID_ACCESS
, 0, 1},
2080 /* Suppress external sources of input events for the duration of the test. */
2081 ret
= GetConsoleMode(input_handle
, &console_mode
);
2082 ok(ret
== TRUE
, "Expected GetConsoleMode to return TRUE, got %d\n", ret
);
2085 skip("GetConsoleMode failed with last error %lu\n", GetLastError());
2089 ret
= SetConsoleMode(input_handle
, console_mode
& ~(ENABLE_MOUSE_INPUT
| ENABLE_WINDOW_INPUT
));
2090 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
2093 skip("SetConsoleMode failed with last error %lu\n", GetLastError());
2097 /* Discard any events queued before the tests. */
2098 ret
= FlushConsoleInputBuffer(input_handle
);
2099 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
2101 event
.EventType
= MOUSE_EVENT
;
2102 event
.Event
.MouseEvent
= mouse_event
;
2104 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2106 if (invalid_table
[i
].win_crash
)
2109 SetLastError(0xdeadbeef);
2110 if (invalid_table
[i
].written
) count
= 0xdeadbeef;
2111 ret
= WriteConsoleInputW(invalid_table
[i
].handle
,
2112 invalid_table
[i
].buffer
,
2113 invalid_table
[i
].count
,
2114 invalid_table
[i
].written
);
2115 ok(!ret
, "[%d] Expected WriteConsoleInputW to return FALSE, got %d\n", i
, ret
);
2116 gle
= GetLastError();
2117 ok(gle
== invalid_table
[i
].gle
|| (gle
!= 0 && gle
== invalid_table
[i
].gle2
),
2118 "[%d] Expected last error to be %lu or %lu, got %lu\n",
2119 i
, invalid_table
[i
].gle
, invalid_table
[i
].gle2
, gle
);
2123 ret
= WriteConsoleInputW(input_handle
, NULL
, 0, &count
);
2124 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2125 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2128 ret
= WriteConsoleInputW(input_handle
, &event
, 0, &count
);
2129 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2130 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2133 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2134 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2135 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2137 ret
= FlushConsoleInputBuffer(input_handle
);
2138 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
2140 /* Writing a single mouse event doesn't seem to affect the count if an adjacent mouse event is already queued. */
2141 event
.EventType
= MOUSE_EVENT
;
2142 event
.Event
.MouseEvent
= mouse_event
;
2144 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2145 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2146 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2148 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2149 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2150 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2152 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2153 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2154 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2156 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2157 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2159 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2161 ret
= FlushConsoleInputBuffer(input_handle
);
2162 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
2164 for (i
= 0; i
< ARRAY_SIZE(event_list
); i
++)
2166 event_list
[i
].EventType
= MOUSE_EVENT
;
2167 event_list
[i
].Event
.MouseEvent
= mouse_event
;
2170 /* Writing consecutive chunks of mouse events appears to work. */
2171 ret
= WriteConsoleInputW(input_handle
, event_list
, ARRAY_SIZE(event_list
), &count
);
2172 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2173 ok(count
== ARRAY_SIZE(event_list
),
2174 "Expected count to be event list length, got %lu\n", count
);
2176 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2177 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2178 ok(count
== ARRAY_SIZE(event_list
),
2179 "Expected count to be event list length, got %lu\n", count
);
2181 ret
= WriteConsoleInputW(input_handle
, event_list
, ARRAY_SIZE(event_list
), &count
);
2182 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2183 ok(count
== ARRAY_SIZE(event_list
),
2184 "Expected count to be event list length, got %lu\n", count
);
2186 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2187 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2188 ok(count
== 2*ARRAY_SIZE(event_list
),
2189 "Expected count to be twice event list length, got %lu\n", count
);
2191 /* Again, writing a single mouse event with adjacent mouse events queued doesn't appear to affect the count. */
2192 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2193 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2194 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2196 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2197 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2199 ok(count
== 2*ARRAY_SIZE(event_list
),
2200 "Expected count to be twice event list length, got %lu\n", count
);
2202 ret
= FlushConsoleInputBuffer(input_handle
);
2203 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
2205 key_event
.bKeyDown
= FALSE
;
2206 key_event
.wRepeatCount
= 0;
2207 key_event
.wVirtualKeyCode
= VK_SPACE
;
2208 key_event
.wVirtualScanCode
= VK_SPACE
;
2209 key_event
.uChar
.UnicodeChar
= ' ';
2210 key_event
.dwControlKeyState
= 0;
2212 event
.EventType
= KEY_EVENT
;
2213 event
.Event
.KeyEvent
= key_event
;
2215 /* Key events don't exhibit the same behavior as mouse events. */
2216 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2217 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2218 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2220 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2221 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2222 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2224 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2225 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2226 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2228 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2229 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2230 ok(count
== 2, "Expected count to be 2, got %lu\n", count
);
2232 ret
= FlushConsoleInputBuffer(input_handle
);
2233 ok(ret
== TRUE
, "Expected FlushConsoleInputBuffer to return TRUE, got %d\n", ret
);
2235 /* Try interleaving mouse and key events. */
2236 event
.EventType
= MOUSE_EVENT
;
2237 event
.Event
.MouseEvent
= mouse_event
;
2239 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2240 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2241 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2243 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2244 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2245 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2247 event
.EventType
= KEY_EVENT
;
2248 event
.Event
.KeyEvent
= key_event
;
2250 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2251 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2252 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2254 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2255 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2256 ok(count
== 2, "Expected count to be 2, got %lu\n", count
);
2258 event
.EventType
= MOUSE_EVENT
;
2259 event
.Event
.MouseEvent
= mouse_event
;
2261 ret
= WriteConsoleInputW(input_handle
, &event
, 1, &count
);
2262 ok(ret
== TRUE
, "Expected WriteConsoleInputW to return TRUE, got %d\n", ret
);
2263 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2265 ret
= GetNumberOfConsoleInputEvents(input_handle
, &count
);
2266 ok(ret
== TRUE
, "Expected GetNumberOfConsoleInputEvents to return TRUE, got %d\n", ret
);
2267 ok(count
== 3, "Expected count to be 3, got %lu\n", count
);
2269 /* Restore the old console mode. */
2270 ret
= SetConsoleMode(input_handle
, console_mode
);
2271 ok(ret
== TRUE
, "Expected SetConsoleMode to return TRUE, got %d\n", ret
);
2274 static void test_FlushConsoleInputBuffer(HANDLE input
, HANDLE output
)
2276 INPUT_RECORD record
;
2280 ret
= FlushConsoleInputBuffer(input
);
2281 ok(ret
, "FlushConsoleInputBuffer failed: %lu\n", GetLastError());
2283 ret
= GetNumberOfConsoleInputEvents(input
, &count
);
2284 ok(ret
, "GetNumberOfConsoleInputEvents failed: %lu\n", GetLastError());
2285 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2287 record
.EventType
= KEY_EVENT
;
2288 record
.Event
.KeyEvent
.bKeyDown
= 1;
2289 record
.Event
.KeyEvent
.wRepeatCount
= 1;
2290 record
.Event
.KeyEvent
.wVirtualKeyCode
= VK_RETURN
;
2291 record
.Event
.KeyEvent
.wVirtualScanCode
= VK_RETURN
;
2292 record
.Event
.KeyEvent
.uChar
.UnicodeChar
= '\r';
2293 record
.Event
.KeyEvent
.dwControlKeyState
= 0;
2294 ret
= WriteConsoleInputW(input
, &record
, 1, &count
);
2295 ok(ret
, "WriteConsoleInputW failed: %lu\n", GetLastError());
2297 ret
= GetNumberOfConsoleInputEvents(input
, &count
);
2298 ok(ret
, "GetNumberOfConsoleInputEvents failed: %lu\n", GetLastError());
2299 ok(count
== 1, "Expected count to be 0, got %lu\n", count
);
2301 ret
= FlushConsoleInputBuffer(input
);
2302 ok(ret
, "FlushConsoleInputBuffer failed: %lu\n", GetLastError());
2304 ret
= GetNumberOfConsoleInputEvents(input
, &count
);
2305 ok(ret
, "GetNumberOfConsoleInputEvents failed: %lu\n", GetLastError());
2306 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2308 ret
= WriteConsoleInputW(input
, &record
, 1, &count
);
2309 ok(ret
, "WriteConsoleInputW failed: %lu\n", GetLastError());
2311 ret
= GetNumberOfConsoleInputEvents(input
, &count
);
2312 ok(ret
, "GetNumberOfConsoleInputEvents failed: %lu\n", GetLastError());
2313 ok(count
== 1, "Expected count to be 0, got %lu\n", count
);
2315 ret
= FlushFileBuffers(input
);
2316 ok(ret
, "FlushFileBuffers failed: %lu\n", GetLastError());
2318 ret
= GetNumberOfConsoleInputEvents(input
, &count
);
2319 ok(ret
, "GetNumberOfConsoleInputEvents failed: %lu\n", GetLastError());
2320 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2322 ret
= FlushConsoleInputBuffer(output
);
2323 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "FlushConsoleInputBuffer returned: %x(%lu)\n",
2324 ret
, GetLastError());
2326 ret
= FlushFileBuffers(output
);
2327 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "FlushFileBuffers returned: %x(%lu)\n",
2328 ret
, GetLastError());
2331 static void test_WriteConsoleOutputCharacterA(HANDLE output_handle
)
2333 static const char output
[] = {'a', 0};
2335 COORD origin
= {0, 0};
2342 HANDLE hConsoleOutput
;
2346 LPDWORD lpNumCharsWritten
;
2347 DWORD expected_count
;
2352 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2353 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2354 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2355 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2356 {NULL
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2357 {NULL
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2358 {NULL
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2359 {NULL
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2360 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2361 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2362 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2363 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2364 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2365 {INVALID_HANDLE_VALUE
, output
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2366 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2367 {INVALID_HANDLE_VALUE
, output
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2368 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2369 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2370 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2371 {output_handle
, output
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2372 {output_handle
, output
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2375 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2377 if (invalid_table
[i
].win7_crash
)
2380 SetLastError(0xdeadbeef);
2381 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2382 ret
= WriteConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2383 invalid_table
[i
].str
,
2384 invalid_table
[i
].length
,
2385 invalid_table
[i
].coord
,
2386 invalid_table
[i
].lpNumCharsWritten
);
2387 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2388 ok(GetLastError() == invalid_table
[i
].last_error
,
2389 "[%d] Expected last error to be %lu, got %lu\n",
2390 i
, invalid_table
[i
].last_error
, GetLastError());
2394 ret
= WriteConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
2395 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2396 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2399 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 0, origin
, &count
);
2400 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2401 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2404 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 1, origin
, &count
);
2405 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2406 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2410 ret
= WriteConsoleOutputCharacterA(output_handle
, output
, 0, origin
, &count
);
2411 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2412 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2414 for (i
= 1; i
< 32; i
++)
2416 CONSOLE_SCREEN_BUFFER_INFO csbi
;
2420 ret
= WriteConsoleOutputCharacterA(output_handle
, &ch
, 1, c
, &count
);
2421 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2422 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2423 okCHAR(output_handle
, c
, (char)i
, 7);
2424 ret
= GetConsoleScreenBufferInfo(output_handle
, &csbi
);
2428 static void test_WriteConsoleOutputCharacterW(HANDLE output_handle
)
2430 static const WCHAR outputW
[] = {'a',0};
2432 COORD origin
= {0, 0};
2439 HANDLE hConsoleOutput
;
2443 LPDWORD lpNumCharsWritten
;
2444 DWORD expected_count
;
2449 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2450 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2451 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2452 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2453 {NULL
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2454 {NULL
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2455 {NULL
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2456 {NULL
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2457 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2458 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2459 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2460 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2461 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2462 {INVALID_HANDLE_VALUE
, outputW
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2463 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2464 {INVALID_HANDLE_VALUE
, outputW
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2465 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2466 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2467 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2468 {output_handle
, outputW
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2469 {output_handle
, outputW
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2472 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2474 if (invalid_table
[i
].win7_crash
)
2477 SetLastError(0xdeadbeef);
2478 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2479 ret
= WriteConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2480 invalid_table
[i
].str
,
2481 invalid_table
[i
].length
,
2482 invalid_table
[i
].coord
,
2483 invalid_table
[i
].lpNumCharsWritten
);
2484 ok(!ret
, "[%d] Expected WriteConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2485 ok(GetLastError() == invalid_table
[i
].last_error
,
2486 "[%d] Expected last error to be %lu, got %lu\n",
2487 i
, invalid_table
[i
].last_error
, GetLastError());
2491 ret
= WriteConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
2492 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2493 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2496 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 0, origin
, &count
);
2497 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2498 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2501 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 1, origin
, &count
);
2502 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2503 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2507 ret
= WriteConsoleOutputCharacterW(output_handle
, outputW
, 0, origin
, &count
);
2508 ok(ret
== TRUE
, "Expected WriteConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2509 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2513 static void test_WriteConsoleOutputAttribute(HANDLE output_handle
)
2515 WORD attr
= FOREGROUND_BLUE
;
2516 COORD origin
= {0, 0};
2523 HANDLE hConsoleOutput
;
2527 LPDWORD lpNumAttrsWritten
;
2528 DWORD expected_count
;
2533 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2534 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2535 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2536 {NULL
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2537 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2538 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2539 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2540 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2541 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2542 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2543 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2544 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2545 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2546 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2547 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2548 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2549 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2550 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2551 {output_handle
, NULL
, 1, {0, 0}, &count
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2552 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2553 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2556 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2558 if (invalid_table
[i
].win7_crash
)
2561 SetLastError(0xdeadbeef);
2562 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2563 ret
= WriteConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2564 invalid_table
[i
].attr
,
2565 invalid_table
[i
].length
,
2566 invalid_table
[i
].coord
,
2567 invalid_table
[i
].lpNumAttrsWritten
);
2568 ok(!ret
, "[%d] Expected WriteConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2569 ok(GetLastError() == invalid_table
[i
].last_error
,
2570 "[%d] Expected last error to be %lu, got %lu\n",
2571 i
, invalid_table
[i
].last_error
, GetLastError());
2575 ret
= WriteConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
2576 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2577 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2580 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2581 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2582 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2585 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
2586 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2587 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2591 ret
= WriteConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
2592 ok(ret
== TRUE
, "Expected WriteConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2593 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2596 static void set_region(SMALL_RECT
*region
, unsigned int left
, unsigned int top
, unsigned int right
, unsigned int bottom
)
2598 region
->Left
= left
;
2600 region
->Right
= right
;
2601 region
->Bottom
= bottom
;
2604 #define check_region(a,b,c,d,e) check_region_(__LINE__,a,b,c,d,e)
2605 static void check_region_(unsigned int line
, const SMALL_RECT
*region
, unsigned int left
, unsigned int top
, int right
, int bottom
)
2607 ok_(__FILE__
,line
)(region
->Left
== left
, "Left = %u, expected %u\n", region
->Left
, left
);
2608 ok_(__FILE__
,line
)(region
->Top
== top
, "Top = %u, expected %u\n", region
->Top
, top
);
2609 /* In multiple places returned region depends on Windows versions: some return right < left, others leave it untouched */
2611 ok_(__FILE__
,line
)(region
->Right
== right
, "Right = %u, expected %u\n", region
->Right
, right
);
2613 ok_(__FILE__
,line
)(region
->Right
== -right
|| region
->Right
== region
->Left
- 1,
2614 "Right = %u, expected %d\n", region
->Right
, right
);
2616 ok_(__FILE__
,line
)(region
->Bottom
== bottom
, "Bottom = %u, expected %u\n", region
->Bottom
, bottom
);
2617 else if (bottom
< 0)
2618 ok_(__FILE__
,line
)(region
->Bottom
== -bottom
|| region
->Bottom
== region
->Top
- 1,
2619 "Bottom = %u, expected %d\n", region
->Bottom
, bottom
);
2622 static void test_WriteConsoleOutput(HANDLE console
)
2624 CONSOLE_SCREEN_BUFFER_INFO info
;
2625 CHAR_INFO char_info_buf
[2048];
2631 for (i
= 0; i
< ARRAY_SIZE(char_info_buf
); i
++)
2633 char_info_buf
[i
].Char
.UnicodeChar
= '0' + i
% 10;
2634 char_info_buf
[i
].Attributes
= 0;
2637 ret
= GetConsoleScreenBufferInfo(console
, &info
);
2638 ok(ret
, "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
2644 set_region(®ion
, 10, 7, 15, 11);
2645 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2646 ok(ret
, "WriteConsoleOutputW failed: %lu\n", GetLastError());
2647 check_region(®ion
, 10, 7, 15, 11);
2653 set_region(®ion
, 200, 7, 15, 211);
2654 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2655 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2656 check_region(®ion
, 200, 7, 15, 211);
2662 set_region(®ion
, 200, 7, 211, 8);
2663 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2664 ok(ret
, "WriteConsoleOutputW failed: %lu\n", GetLastError());
2665 check_region(®ion
, 200, 7, 211, 8);
2671 set_region(®ion
, 10, 7, 9, 11);
2672 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2673 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2674 check_region(®ion
, 10, 7, 9, 11);
2680 set_region(®ion
, 10, 7, 11, 6);
2681 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2682 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2683 check_region(®ion
, 10, 7, 11, 6);
2689 set_region(®ion
, 10, 7, 15, 11);
2690 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2691 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2692 check_region(®ion
, 10, 7, 15, 11);
2698 set_region(®ion
, 10, 7, 15, 11);
2699 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2700 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2701 check_region(®ion
, 10, 7, 15, 11);
2707 set_region(®ion
, 10, 7, 15, 11);
2708 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2709 ok(ret
, "WriteConsoleOutputW failed: %lu\n", GetLastError());
2710 check_region(®ion
, 10, 7, 13, 11);
2716 set_region(®ion
, 10, 7, 15, 11);
2717 ret
= WriteConsoleOutputW((HANDLE
)0xdeadbeef, char_info_buf
, size
, coord
, ®ion
);
2718 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "WriteConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
2719 if (!skip_nt
) check_region(®ion
, 10, 7, 13, 11);
2725 set_region(®ion
, 10, 7, 15, 11);
2726 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2727 ok(ret
, "WriteConsoleOutputW failed: %lu\n", GetLastError());
2728 check_region(®ion
, 10, 7, 15, 10);
2734 set_region(®ion
, info
.dwSize
.X
- 2, 7, info
.dwSize
.X
+ 2, 7);
2735 ret
= WriteConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
2736 ok(ret
, "WriteConsoleOutputW failed: %lu\n", GetLastError());
2737 check_region(®ion
, info
.dwSize
.X
- 2, 7, info
.dwSize
.X
- 1, 7);
2740 static void test_FillConsoleOutputCharacterA(HANDLE output_handle
)
2742 COORD origin
= {0, 0};
2749 HANDLE hConsoleOutput
;
2753 LPDWORD lpNumCharsWritten
;
2758 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2759 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2760 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2761 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2762 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2763 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2764 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2765 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2766 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2767 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2770 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2772 if (invalid_table
[i
].win7_crash
)
2775 SetLastError(0xdeadbeef);
2776 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2777 ret
= FillConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2778 invalid_table
[i
].ch
,
2779 invalid_table
[i
].length
,
2780 invalid_table
[i
].coord
,
2781 invalid_table
[i
].lpNumCharsWritten
);
2782 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2783 ok(GetLastError() == invalid_table
[i
].last_error
,
2784 "[%d] Expected last error to be %lu, got %lu\n",
2785 i
, invalid_table
[i
].last_error
, GetLastError());
2789 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 0, origin
, &count
);
2790 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2791 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2794 ret
= FillConsoleOutputCharacterA(output_handle
, 'a', 1, origin
, &count
);
2795 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2796 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2799 static void test_FillConsoleOutputCharacterW(HANDLE output_handle
)
2801 COORD origin
= {0, 0};
2808 HANDLE hConsoleOutput
;
2812 LPDWORD lpNumCharsWritten
;
2817 {NULL
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2818 {NULL
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2819 {NULL
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2820 {NULL
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2821 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2822 {INVALID_HANDLE_VALUE
, 'a', 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2823 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2824 {INVALID_HANDLE_VALUE
, 'a', 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2825 {output_handle
, 'a', 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2826 {output_handle
, 'a', 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2829 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2831 if (invalid_table
[i
].win7_crash
)
2834 SetLastError(0xdeadbeef);
2835 if (invalid_table
[i
].lpNumCharsWritten
) count
= 0xdeadbeef;
2836 ret
= FillConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
2837 invalid_table
[i
].ch
,
2838 invalid_table
[i
].length
,
2839 invalid_table
[i
].coord
,
2840 invalid_table
[i
].lpNumCharsWritten
);
2841 ok(!ret
, "[%d] Expected FillConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
2842 ok(GetLastError() == invalid_table
[i
].last_error
,
2843 "[%d] Expected last error to be %lu, got %lu\n",
2844 i
, invalid_table
[i
].last_error
, GetLastError());
2848 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 0, origin
, &count
);
2849 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2850 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2853 ret
= FillConsoleOutputCharacterW(output_handle
, 'a', 1, origin
, &count
);
2854 ok(ret
== TRUE
, "Expected FillConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
2855 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2858 static void test_FillConsoleOutputAttribute(HANDLE output_handle
)
2860 COORD origin
= {0, 0};
2867 HANDLE hConsoleOutput
;
2871 LPDWORD lpNumAttrsWritten
;
2876 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2877 {NULL
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2878 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2879 {NULL
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2880 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2881 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 0, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2882 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2883 {INVALID_HANDLE_VALUE
, FOREGROUND_BLUE
, 1, {0, 0}, &count
, ERROR_INVALID_HANDLE
},
2884 {output_handle
, FOREGROUND_BLUE
, 0, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2885 {output_handle
, FOREGROUND_BLUE
, 1, {0, 0}, NULL
, ERROR_INVALID_ACCESS
, 1},
2888 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2890 if (invalid_table
[i
].win7_crash
)
2893 SetLastError(0xdeadbeef);
2894 if (invalid_table
[i
].lpNumAttrsWritten
) count
= 0xdeadbeef;
2895 ret
= FillConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
2896 invalid_table
[i
].attr
,
2897 invalid_table
[i
].length
,
2898 invalid_table
[i
].coord
,
2899 invalid_table
[i
].lpNumAttrsWritten
);
2900 ok(!ret
, "[%d] Expected FillConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
2901 ok(GetLastError() == invalid_table
[i
].last_error
,
2902 "[%d] Expected last error to be %lu, got %lu\n",
2903 i
, invalid_table
[i
].last_error
, GetLastError());
2907 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 0, origin
, &count
);
2908 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2909 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2912 ret
= FillConsoleOutputAttribute(output_handle
, FOREGROUND_BLUE
, 1, origin
, &count
);
2913 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2914 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2917 ret
= FillConsoleOutputAttribute(output_handle
, ~0, 1, origin
, &count
);
2918 ok(ret
== TRUE
, "Expected FillConsoleOutputAttribute to return TRUE, got %d\n", ret
);
2919 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
2922 static void test_ReadConsoleOutputCharacterA(HANDLE output_handle
)
2925 COORD origin
= {0, 0};
2932 HANDLE hConsoleOutput
;
2937 DWORD expected_count
;
2942 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2943 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2944 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2945 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2946 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2947 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2948 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2949 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2950 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2951 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2952 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2953 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
2954 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2955 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2956 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2957 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
2958 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2959 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2960 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
2961 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
2962 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2963 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
2966 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
2968 if (invalid_table
[i
].win7_crash
)
2971 SetLastError(0xdeadbeef);
2972 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
2973 ret
= ReadConsoleOutputCharacterA(invalid_table
[i
].hConsoleOutput
,
2974 invalid_table
[i
].lpstr
,
2975 invalid_table
[i
].length
,
2976 invalid_table
[i
].coord
,
2977 invalid_table
[i
].read_count
);
2978 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterA to return FALSE, got %d\n", i
, ret
);
2979 ok(GetLastError() == invalid_table
[i
].last_error
,
2980 "[%d] Expected last error to be %lu, got %lu\n",
2981 i
, invalid_table
[i
].last_error
, GetLastError());
2985 ret
= ReadConsoleOutputCharacterA(output_handle
, NULL
, 0, origin
, &count
);
2986 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2987 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2990 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 0, origin
, &count
);
2991 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2992 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
2995 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 1, origin
, &count
);
2996 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
2997 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
3001 ret
= ReadConsoleOutputCharacterA(output_handle
, &read
, 1, origin
, &count
);
3002 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterA to return TRUE, got %d\n", ret
);
3003 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3006 static void test_ReadConsoleOutputCharacterW(HANDLE output_handle
)
3009 COORD origin
= {0, 0};
3016 HANDLE hConsoleOutput
;
3021 DWORD expected_count
;
3026 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3027 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3028 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3029 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
3030 {NULL
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3031 {NULL
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3032 {NULL
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3033 {NULL
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3034 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3035 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3036 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3037 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
3038 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3039 {INVALID_HANDLE_VALUE
, &read
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3040 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3041 {INVALID_HANDLE_VALUE
, &read
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3042 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3043 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3044 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
3045 {output_handle
, NULL
, 10, {0, 0}, &count
, 10, ERROR_INVALID_ACCESS
, 1},
3046 {output_handle
, &read
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3047 {output_handle
, &read
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3050 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
3052 if (invalid_table
[i
].win7_crash
)
3055 SetLastError(0xdeadbeef);
3056 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
3057 ret
= ReadConsoleOutputCharacterW(invalid_table
[i
].hConsoleOutput
,
3058 invalid_table
[i
].buffer
,
3059 invalid_table
[i
].length
,
3060 invalid_table
[i
].coord
,
3061 invalid_table
[i
].read_count
);
3062 ok(!ret
, "[%d] Expected ReadConsoleOutputCharacterW to return FALSE, got %d\n", i
, ret
);
3063 ok(GetLastError() == invalid_table
[i
].last_error
,
3064 "[%d] Expected last error to be %lu, got %lu\n",
3065 i
, invalid_table
[i
].last_error
, GetLastError());
3069 ret
= ReadConsoleOutputCharacterW(output_handle
, NULL
, 0, origin
, &count
);
3070 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
3071 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3074 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 0, origin
, &count
);
3075 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
3076 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3079 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 1, origin
, &count
);
3080 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
3081 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
3085 ret
= ReadConsoleOutputCharacterW(output_handle
, &read
, 1, origin
, &count
);
3086 ok(ret
== TRUE
, "Expected ReadConsoleOutputCharacterW to return TRUE, got %d\n", ret
);
3087 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3090 static void test_ReadConsoleOutputAttribute(HANDLE output_handle
)
3093 COORD origin
= {0, 0};
3100 HANDLE hConsoleOutput
;
3105 DWORD expected_count
;
3110 {NULL
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3111 {NULL
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3112 {NULL
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3113 {NULL
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
3114 {NULL
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3115 {NULL
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3116 {NULL
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3117 {NULL
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3118 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3119 {INVALID_HANDLE_VALUE
, NULL
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3120 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3121 {INVALID_HANDLE_VALUE
, NULL
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
, 1},
3122 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3123 {INVALID_HANDLE_VALUE
, &attr
, 0, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3124 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3125 {INVALID_HANDLE_VALUE
, &attr
, 1, {0, 0}, &count
, 0, ERROR_INVALID_HANDLE
},
3126 {output_handle
, NULL
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3127 {output_handle
, NULL
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3128 {output_handle
, NULL
, 1, {0, 0}, &count
, 1, ERROR_INVALID_ACCESS
, 1},
3129 {output_handle
, &attr
, 0, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3130 {output_handle
, &attr
, 1, {0, 0}, NULL
, 0xdeadbeef, ERROR_INVALID_ACCESS
, 1},
3133 for (i
= 0; i
< ARRAY_SIZE(invalid_table
); i
++)
3135 if (invalid_table
[i
].win7_crash
)
3138 SetLastError(0xdeadbeef);
3139 if (invalid_table
[i
].read_count
) count
= 0xdeadbeef;
3140 ret
= ReadConsoleOutputAttribute(invalid_table
[i
].hConsoleOutput
,
3141 invalid_table
[i
].lpAttribute
,
3142 invalid_table
[i
].length
,
3143 invalid_table
[i
].coord
,
3144 invalid_table
[i
].read_count
);
3145 ok(!ret
, "[%d] Expected ReadConsoleOutputAttribute to return FALSE, got %d\n", i
, ret
);
3146 ok(GetLastError() == invalid_table
[i
].last_error
,
3147 "[%d] Expected last error to be %lu, got %lu\n",
3148 i
, invalid_table
[i
].last_error
, GetLastError());
3152 ret
= ReadConsoleOutputAttribute(output_handle
, NULL
, 0, origin
, &count
);
3153 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
3154 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3157 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 0, origin
, &count
);
3158 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
3159 ok(count
== 0, "Expected count to be 0, got %lu\n", count
);
3162 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
3163 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
3164 ok(count
== 1, "Expected count to be 1, got %lu\n", count
);
3168 ret
= ReadConsoleOutputAttribute(output_handle
, &attr
, 1, origin
, &count
);
3169 ok(ret
== TRUE
, "Expected ReadConsoleOutputAttribute to return TRUE, got %d\n", ret
);
3170 ok(count
== 0, "Expected count to be 1, got %lu\n", count
);
3173 static void test_ReadConsoleOutput(HANDLE console
)
3175 CONSOLE_SCREEN_BUFFER_INFO info
;
3176 CHAR_INFO char_info_buf
[2048];
3183 if (skip_nt
) return;
3185 ret
= GetConsoleScreenBufferInfo(console
, &info
);
3186 ok(ret
, "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
3192 set_region(®ion
, 10, 7, 15, 11);
3193 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3194 ok(ret
, "ReadConsoleOutputW failed: %lu\n", GetLastError());
3195 check_region(®ion
, 10, 7, 15, 11);
3201 set_region(®ion
, 200, 7, 15, 211);
3202 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3203 ok(!ret
, "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3204 check_region(®ion
, 200, 7, -15, 0);
3210 set_region(®ion
, 200, 7, 211, 8);
3211 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3212 ok((!ret
&& (GetLastError() == ERROR_INVALID_PARAMETER
|| GetLastError() == ERROR_INVALID_FUNCTION
)) || broken(ret
/* win8 */),
3213 "ReadConsoleOutputW returned: %x %lu\n", ret
, GetLastError());
3214 if (!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) check_region(®ion
, 200, 7, -211, -8);
3220 set_region(®ion
, 10, 7, 9, 11);
3221 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3222 ok((!ret
&& (GetLastError() == ERROR_INVALID_FUNCTION
|| GetLastError() == ERROR_NOT_ENOUGH_MEMORY
)) || broken(ret
/* win8 */),
3223 "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3224 check_region(®ion
, 10, 7, 9, -11);
3230 set_region(®ion
, 10, 7, 11, 6);
3231 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3232 ok((!ret
&& (GetLastError() == ERROR_INVALID_FUNCTION
|| GetLastError() == ERROR_NOT_ENOUGH_MEMORY
)) || broken(ret
/* win8 */),
3233 "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3234 check_region(®ion
, 10, 7, -11, 6);
3240 set_region(®ion
, 10, 7, 15, 11);
3241 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3242 ok((!ret
&& (GetLastError() == ERROR_INVALID_FUNCTION
|| GetLastError() == ERROR_NOT_ENOUGH_MEMORY
)) || broken(ret
/* win8 */),
3243 "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3244 check_region(®ion
, 10, 7, -15, -11);
3250 set_region(®ion
, 10, 7, 15, 11);
3251 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3252 ok((!ret
&& (GetLastError() == ERROR_INVALID_FUNCTION
|| GetLastError() == ERROR_NOT_ENOUGH_MEMORY
)) || broken(ret
/* win8 */),
3253 "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3254 check_region(®ion
, 10, 7, -15, 6);
3260 set_region(®ion
, 10, 7, 15, 11);
3261 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3262 ok(ret
, "ReadConsoleOutputW failed: %lu\n", GetLastError());
3263 check_region(®ion
, 10, 7, 13, 11);
3269 set_region(®ion
, 10, 7, 15, 11);
3270 ret
= ReadConsoleOutputW((HANDLE
)0xdeadbeef, char_info_buf
, size
, coord
, ®ion
);
3271 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "ReadConsoleOutputW returned: %x(%lu)\n", ret
, GetLastError());
3272 if (!skip_nt
) check_region(®ion
, 10, 7, 13, 11);
3278 set_region(®ion
, 10, 7, 15, 11);
3279 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3280 ok(ret
, "ReadConsoleOutputW failed: %lu\n", GetLastError());
3281 check_region(®ion
, 10, 7, 15, 10);
3287 set_region(®ion
, info
.dwSize
.X
- 2, 7, info
.dwSize
.X
+ 2, 7);
3288 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3289 ok(ret
|| GetLastError() == ERROR_INVALID_PARAMETER
, "ReadConsoleOutputW failed: %lu\n", GetLastError());
3290 if (ret
) check_region(®ion
, info
.dwSize
.X
- 2, 7, info
.dwSize
.X
- 1, 7);
3294 ret
= WriteConsoleOutputCharacterW(console
, L
"xyz", 3, coord
, &count
);
3295 ok(ret
, "WriteConsoleOutputCharacterW failed: %lu\n", GetLastError());
3296 ok(count
== 3, "count = %lu\n", count
);
3298 memset(char_info_buf
, 0xc0, sizeof(char_info_buf
));
3303 set_region(®ion
, 2, 3, 5, 3);
3304 ret
= ReadConsoleOutputW(console
, char_info_buf
, size
, coord
, ®ion
);
3305 ok(ret
, "ReadConsoleOutputW failed: %lu\n", GetLastError());
3306 check_region(®ion
, 2, 3, 5, 3);
3307 ch
= char_info_buf
[coord
.Y
* size
.X
+ coord
.X
].Char
.UnicodeChar
;
3308 ok(ch
== 'x', "unexpected char %c/%x\n", ch
, ch
);
3309 ch
= char_info_buf
[coord
.Y
* size
.X
+ coord
.X
+ 1].Char
.UnicodeChar
;
3310 ok(ch
== 'y', "unexpected char %c/%x\n", ch
, ch
);
3311 ch
= char_info_buf
[coord
.Y
* size
.X
+ coord
.X
+ 2].Char
.UnicodeChar
;
3312 ok(ch
== 'z', "unexpected char %c/%x\n", ch
, ch
);
3315 static void test_ReadConsole(HANDLE input
)
3321 SetLastError(0xdeadbeef);
3322 ret
= GetFileSize(input
, NULL
);
3323 ok(ret
== INVALID_FILE_SIZE
|| broken(TRUE
), /* only Win7 pro64 on 64bit returns a valid file size here */
3324 "expected INVALID_FILE_SIZE, got %#lx\n", ret
);
3325 if (ret
== INVALID_FILE_SIZE
)
3326 ok(GetLastError() == ERROR_INVALID_HANDLE
||
3327 GetLastError() == ERROR_INVALID_FUNCTION
, /* Win 8, 10 */
3328 "expected ERROR_INVALID_HANDLE, got %ld\n", GetLastError());
3331 SetLastError(0xdeadbeef);
3332 ret
= ReadFile(input
, buf
, -128, &bytes
, NULL
);
3333 ok(!ret
, "expected 0, got %lu\n", ret
);
3334 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
3335 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
3336 "expected ERROR_NOT_ENOUGH_MEMORY, got %ld\n", GetLastError());
3337 ok(!bytes
, "expected 0, got %lu\n", bytes
);
3340 SetLastError(0xdeadbeef);
3341 ret
= ReadConsoleA(input
, buf
, -128, &bytes
, NULL
);
3342 ok(!ret
, "expected 0, got %lu\n", ret
);
3343 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
3344 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
3345 "expected ERROR_NOT_ENOUGH_MEMORY, got %ld\n", GetLastError());
3346 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", bytes
);
3349 SetLastError(0xdeadbeef);
3350 ret
= ReadConsoleW(input
, buf
, -128, &bytes
, NULL
);
3351 ok(!ret
, "expected 0, got %lu\n", ret
);
3352 ok(GetLastError() == ERROR_NOT_ENOUGH_MEMORY
||
3353 GetLastError() == ERROR_NOACCESS
, /* Win 8, 10 */
3354 "expected ERROR_NOT_ENOUGH_MEMORY, got %ld\n", GetLastError());
3355 ok(bytes
== 0xdeadbeef, "expected 0xdeadbeef, got %#lx\n", bytes
);
3357 output
= CreateFileA("CONOUT$", GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
3358 ok(output
!= INVALID_HANDLE_VALUE
, "Could not open console\n");
3360 ret
= ReadConsoleW(output
, buf
, sizeof(buf
) / sizeof(WCHAR
), &bytes
, NULL
);
3361 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
3362 "ReadConsoleW returned %lx(%lu)\n", ret
, GetLastError());
3364 ret
= ReadConsoleA(output
, buf
, sizeof(buf
), &bytes
, NULL
);
3365 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
3366 "ReadConsoleA returned %lx(%lu)\n", ret
, GetLastError());
3368 ret
= ReadFile(output
, buf
, sizeof(buf
), &bytes
, NULL
);
3369 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
3370 "ReadFile returned %lx(%lu)\n", ret
, GetLastError());
3372 CloseHandle(output
);
3375 static void test_GetCurrentConsoleFont(HANDLE std_output
)
3378 CONSOLE_FONT_INFO cfi
;
3379 CONSOLE_SCREEN_BUFFER_INFO csbi
;
3380 short int width
, height
;
3381 HANDLE pipe1
, pipe2
;
3384 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3385 SetLastError(0xdeadbeef);
3386 ret
= GetCurrentConsoleFont(NULL
, FALSE
, &cfi
);
3387 ok(!ret
, "got %d, expected 0\n", ret
);
3388 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3389 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
3390 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
3392 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3393 SetLastError(0xdeadbeef);
3394 ret
= GetCurrentConsoleFont(NULL
, TRUE
, &cfi
);
3395 ok(!ret
, "got %d, expected 0\n", ret
);
3396 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3397 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
3398 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
3400 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3401 SetLastError(0xdeadbeef);
3402 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, &cfi
);
3403 ok(!ret
, "got %d, expected 0\n", ret
);
3404 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3405 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
3406 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
3408 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3409 SetLastError(0xdeadbeef);
3410 ret
= GetCurrentConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, &cfi
);
3411 ok(!ret
, "got %d, expected 0\n", ret
);
3412 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3413 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
3414 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
3416 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3417 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3418 SetLastError(0xdeadbeef);
3419 ret
= GetCurrentConsoleFont(pipe1
, TRUE
, &cfi
);
3420 ok(!ret
, "got %d, expected 0\n", ret
);
3421 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3422 ok(!cfi
.dwFontSize
.X
, "got %d, expected 0\n", cfi
.dwFontSize
.X
);
3423 ok(!cfi
.dwFontSize
.Y
, "got %d, expected 0\n", cfi
.dwFontSize
.Y
);
3427 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3428 SetLastError(0xdeadbeef);
3429 ret
= GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
3430 ok(ret
, "got %d, expected non-zero\n", ret
);
3431 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3432 GetConsoleScreenBufferInfo(std_output
, &csbi
);
3433 width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
3434 height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
3435 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
3436 ok(cfi
.dwFontSize
.X
== width
|| cfi
.dwFontSize
.X
== c
.X
/* Vista and higher */,
3437 "got %d, expected %d\n", cfi
.dwFontSize
.X
, width
);
3438 ok(cfi
.dwFontSize
.Y
== height
|| cfi
.dwFontSize
.Y
== c
.Y
/* Vista and higher */,
3439 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, height
);
3441 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3442 SetLastError(0xdeadbeef);
3443 ret
= GetCurrentConsoleFont(std_output
, TRUE
, &cfi
);
3444 ok(ret
, "got %d, expected non-zero\n", ret
);
3445 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3446 ok(cfi
.dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
,
3447 "got %d, expected %d\n", cfi
.dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
3448 ok(cfi
.dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
,
3449 "got %d, expected %d\n", cfi
.dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
3452 static void test_GetCurrentConsoleFontEx(HANDLE std_output
)
3455 BOOL (WINAPI
*pGetCurrentConsoleFontEx
)(HANDLE
, BOOL
, CONSOLE_FONT_INFOEX
*);
3456 CONSOLE_FONT_INFO cfi
;
3457 CONSOLE_FONT_INFOEX cfix
;
3459 HANDLE std_input
= GetStdHandle(STD_INPUT_HANDLE
);
3460 HANDLE pipe1
, pipe2
;
3463 hmod
= GetModuleHandleA("kernel32.dll");
3464 pGetCurrentConsoleFontEx
= (void *)GetProcAddress(hmod
, "GetCurrentConsoleFontEx");
3465 if (!pGetCurrentConsoleFontEx
)
3467 win_skip("GetCurrentConsoleFontEx is not available\n");
3471 SetLastError(0xdeadbeef);
3472 ret
= pGetCurrentConsoleFontEx(NULL
, FALSE
, &cfix
);
3473 ok(!ret
, "got %d, expected 0\n", ret
);
3474 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3476 SetLastError(0xdeadbeef);
3477 ret
= pGetCurrentConsoleFontEx(NULL
, TRUE
, &cfix
);
3478 ok(!ret
, "got %d, expected 0\n", ret
);
3479 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3481 SetLastError(0xdeadbeef);
3482 ret
= pGetCurrentConsoleFontEx(std_input
, FALSE
, &cfix
);
3483 ok(!ret
, "got %d, expected 0\n", ret
);
3484 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3486 SetLastError(0xdeadbeef);
3487 ret
= pGetCurrentConsoleFontEx(std_input
, TRUE
, &cfix
);
3488 ok(!ret
, "got %d, expected 0\n", ret
);
3489 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3491 SetLastError(0xdeadbeef);
3492 ret
= pGetCurrentConsoleFontEx(std_output
, FALSE
, &cfix
);
3493 ok(!ret
, "got %d, expected 0\n", ret
);
3494 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3496 SetLastError(0xdeadbeef);
3497 ret
= pGetCurrentConsoleFontEx(std_output
, TRUE
, &cfix
);
3498 ok(!ret
, "got %d, expected 0\n", ret
);
3499 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3501 cfix
.cbSize
= sizeof(CONSOLE_FONT_INFOEX
);
3503 SetLastError(0xdeadbeef);
3504 ret
= pGetCurrentConsoleFontEx(NULL
, FALSE
, &cfix
);
3505 ok(!ret
, "got %d, expected 0\n", ret
);
3506 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3508 SetLastError(0xdeadbeef);
3509 ret
= pGetCurrentConsoleFontEx(NULL
, TRUE
, &cfix
);
3510 ok(!ret
, "got %d, expected 0\n", ret
);
3511 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3513 SetLastError(0xdeadbeef);
3514 ret
= pGetCurrentConsoleFontEx(std_input
, FALSE
, &cfix
);
3515 ok(!ret
, "got %d, expected 0\n", ret
);
3516 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3518 SetLastError(0xdeadbeef);
3519 ret
= pGetCurrentConsoleFontEx(std_input
, TRUE
, &cfix
);
3520 ok(!ret
, "got %d, expected 0\n", ret
);
3521 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3523 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3524 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3525 SetLastError(0xdeadbeef);
3526 ret
= pGetCurrentConsoleFontEx(pipe1
, TRUE
, &cfix
);
3527 ok(!ret
, "got %d, expected 0\n", ret
);
3528 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3532 SetLastError(0xdeadbeef);
3533 ret
= pGetCurrentConsoleFontEx(std_output
, FALSE
, &cfix
);
3534 ok(ret
, "got %d, expected non-zero\n", ret
);
3535 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3537 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3538 SetLastError(0xdeadbeef);
3539 ret
= GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
3540 ok(ret
, "got %d, expected non-zero\n", ret
);
3541 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3543 ok(cfix
.dwFontSize
.X
== cfi
.dwFontSize
.X
, "expected values to match\n");
3544 ok(cfix
.dwFontSize
.Y
== cfi
.dwFontSize
.Y
, "expected values to match\n");
3546 SetLastError(0xdeadbeef);
3547 c
= GetConsoleFontSize(std_output
, cfix
.nFont
);
3548 ok(c
.X
&& c
.Y
, "GetConsoleFontSize failed; err = %lu\n", GetLastError());
3549 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3551 ok(cfix
.dwFontSize
.X
== c
.X
, "Font width doesn't match; got %u, expected %u\n",
3552 cfix
.dwFontSize
.X
, c
.X
);
3553 ok(cfix
.dwFontSize
.Y
== c
.Y
, "Font height doesn't match; got %u, expected %u\n",
3554 cfix
.dwFontSize
.Y
, c
.Y
);
3556 ok(cfi
.dwFontSize
.X
== c
.X
, "Font width doesn't match; got %u, expected %u\n",
3557 cfi
.dwFontSize
.X
, c
.X
);
3558 ok(cfi
.dwFontSize
.Y
== c
.Y
, "Font height doesn't match; got %u, expected %u\n",
3559 cfi
.dwFontSize
.Y
, c
.Y
);
3561 SetLastError(0xdeadbeef);
3562 ret
= pGetCurrentConsoleFontEx(std_output
, TRUE
, &cfix
);
3563 ok(ret
, "got %d, expected non-zero\n", ret
);
3564 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3566 memset(&cfi
, 0, sizeof(CONSOLE_FONT_INFO
));
3567 SetLastError(0xdeadbeef);
3568 ret
= GetCurrentConsoleFont(std_output
, TRUE
, &cfi
);
3569 ok(ret
, "got %d, expected non-zero\n", ret
);
3570 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3572 ok(cfix
.dwFontSize
.X
== cfi
.dwFontSize
.X
, "expected values to match\n");
3573 ok(cfix
.dwFontSize
.Y
== cfi
.dwFontSize
.Y
, "expected values to match\n");
3576 static void test_SetCurrentConsoleFontEx(HANDLE std_output
)
3578 CONSOLE_FONT_INFOEX orig_cfix
, cfix
;
3580 HANDLE pipe1
, pipe2
;
3581 HANDLE std_input
= GetStdHandle(STD_INPUT_HANDLE
);
3583 orig_cfix
.cbSize
= sizeof(CONSOLE_FONT_INFOEX
);
3585 ret
= GetCurrentConsoleFontEx(std_output
, FALSE
, &orig_cfix
);
3586 ok(ret
, "got %d, expected non-zero\n", ret
);
3591 SetLastError(0xdeadbeef);
3592 ret
= SetCurrentConsoleFontEx(NULL
, FALSE
, &cfix
);
3593 ok(!ret
, "got %d, expected 0\n", ret
);
3594 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3596 SetLastError(0xdeadbeef);
3597 ret
= SetCurrentConsoleFontEx(NULL
, TRUE
, &cfix
);
3598 ok(!ret
, "got %d, expected 0\n", ret
);
3599 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3601 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3602 SetLastError(0xdeadbeef);
3603 ret
= SetCurrentConsoleFontEx(pipe1
, FALSE
, &cfix
);
3604 ok(!ret
, "got %d, expected 0\n", ret
);
3605 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3609 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3610 SetLastError(0xdeadbeef);
3611 ret
= SetCurrentConsoleFontEx(pipe1
, TRUE
, &cfix
);
3612 ok(!ret
, "got %d, expected 0\n", ret
);
3613 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3617 SetLastError(0xdeadbeef);
3618 ret
= SetCurrentConsoleFontEx(std_input
, FALSE
, &cfix
);
3619 ok(!ret
, "got %d, expected 0\n", ret
);
3620 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3622 SetLastError(0xdeadbeef);
3623 ret
= SetCurrentConsoleFontEx(std_input
, TRUE
, &cfix
);
3624 ok(!ret
, "got %d, expected 0\n", ret
);
3625 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3627 SetLastError(0xdeadbeef);
3628 ret
= SetCurrentConsoleFontEx(std_output
, FALSE
, &cfix
);
3629 ok(!ret
, "got %d, expected 0\n", ret
);
3630 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3632 SetLastError(0xdeadbeef);
3633 ret
= SetCurrentConsoleFontEx(std_output
, TRUE
, &cfix
);
3634 ok(!ret
, "got %d, expected 0\n", ret
);
3635 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
3639 SetLastError(0xdeadbeef);
3640 ret
= SetCurrentConsoleFontEx(NULL
, FALSE
, &cfix
);
3641 ok(!ret
, "got %d, expected 0\n", ret
);
3642 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3644 SetLastError(0xdeadbeef);
3645 ret
= SetCurrentConsoleFontEx(NULL
, TRUE
, &cfix
);
3646 ok(!ret
, "got %d, expected 0\n", ret
);
3647 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3649 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3650 SetLastError(0xdeadbeef);
3651 ret
= SetCurrentConsoleFontEx(pipe1
, FALSE
, &cfix
);
3652 ok(!ret
, "got %d, expected 0\n", ret
);
3653 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3657 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3658 SetLastError(0xdeadbeef);
3659 ret
= SetCurrentConsoleFontEx(pipe1
, TRUE
, &cfix
);
3660 ok(!ret
, "got %d, expected 0\n", ret
);
3661 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3665 SetLastError(0xdeadbeef);
3666 ret
= SetCurrentConsoleFontEx(std_input
, FALSE
, &cfix
);
3667 ok(!ret
, "got %d, expected 0\n", ret
);
3668 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3670 SetLastError(0xdeadbeef);
3671 ret
= SetCurrentConsoleFontEx(std_input
, TRUE
, &cfix
);
3672 ok(!ret
, "got %d, expected 0\n", ret
);
3673 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3675 SetLastError(0xdeadbeef);
3676 ret
= SetCurrentConsoleFontEx(std_output
, FALSE
, &cfix
);
3677 ok(ret
, "got %d, expected non-zero\n", ret
);
3678 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3680 SetLastError(0xdeadbeef);
3681 ret
= SetCurrentConsoleFontEx(std_output
, TRUE
, &cfix
);
3682 ok(ret
, "got %d, expected non-zero\n", ret
);
3683 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3685 /* Restore original console font parameters */
3686 SetLastError(0xdeadbeef);
3687 ret
= SetCurrentConsoleFontEx(std_output
, FALSE
, &orig_cfix
);
3688 ok(ret
, "got %d, expected non-zero\n", ret
);
3689 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3692 static void test_GetConsoleFontSize(HANDLE std_output
)
3696 CONSOLE_FONT_INFO cfi
;
3698 CONSOLE_SCREEN_BUFFER_INFO csbi
;
3699 LONG font_width
, font_height
;
3701 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
3702 HANDLE pipe1
, pipe2
;
3704 memset(&c
, 10, sizeof(COORD
));
3705 SetLastError(0xdeadbeef);
3706 c
= GetConsoleFontSize(NULL
, index
);
3707 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3708 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3709 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3711 memset(&c
, 10, sizeof(COORD
));
3712 SetLastError(0xdeadbeef);
3713 c
= GetConsoleFontSize(GetStdHandle(STD_INPUT_HANDLE
), index
);
3714 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3715 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3716 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3718 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3719 memset(&c
, 10, sizeof(COORD
));
3720 SetLastError(0xdeadbeef);
3721 c
= GetConsoleFontSize(pipe1
, index
);
3722 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3723 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3724 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3728 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
3729 memset(&c
, 10, sizeof(COORD
));
3730 SetLastError(0xdeadbeef);
3731 c
= GetConsoleFontSize(std_output
, cfi
.nFont
);
3732 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3733 GetClientRect(GetConsoleWindow(), &r
);
3734 GetConsoleScreenBufferInfo(std_output
, &csbi
);
3735 font_width
= (r
.right
- r
.left
) / (csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1);
3736 font_height
= (r
.bottom
- r
.top
) / (csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1);
3737 ok(c
.X
== font_width
, "got %d, expected %ld\n", c
.X
, font_width
);
3738 ok(c
.Y
== font_height
, "got %d, expected %ld\n", c
.Y
, font_height
);
3740 hmod
= GetModuleHandleA("kernel32.dll");
3741 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
3742 if (!pGetNumberOfConsoleFonts
)
3744 win_skip("GetNumberOfConsoleFonts is not available\n");
3747 index
= pGetNumberOfConsoleFonts();
3749 memset(&c
, 10, sizeof(COORD
));
3750 SetLastError(0xdeadbeef);
3751 c
= GetConsoleFontSize(std_output
, index
);
3752 ok(GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef) /* win10 1809 */,
3753 "unexpected last error %lu\n", GetLastError());
3754 if (GetLastError() == ERROR_INVALID_PARAMETER
)
3756 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3757 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3761 static void test_GetLargestConsoleWindowSize(HANDLE std_output
)
3765 LONG workarea_w
, workarea_h
, maxcon_w
, maxcon_h
;
3766 CONSOLE_SCREEN_BUFFER_INFO sbi
;
3767 CONSOLE_FONT_INFO cfi
;
3768 HANDLE pipe1
, pipe2
;
3772 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
3773 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
3775 memset(&c
, 10, sizeof(COORD
));
3776 SetLastError(0xdeadbeef);
3777 c
= GetLargestConsoleWindowSize(NULL
);
3778 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3779 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3780 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3782 memset(&c
, 10, sizeof(COORD
));
3783 SetLastError(0xdeadbeef);
3784 c
= GetLargestConsoleWindowSize(GetStdHandle(STD_INPUT_HANDLE
));
3785 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3786 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3787 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3789 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
3790 memset(&c
, 10, sizeof(COORD
));
3791 SetLastError(0xdeadbeef);
3792 c
= GetLargestConsoleWindowSize(pipe1
);
3793 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3794 ok(!c
.X
, "got %d, expected 0\n", c
.X
);
3795 ok(!c
.Y
, "got %d, expected 0\n", c
.Y
);
3799 SystemParametersInfoW(SPI_GETWORKAREA
, 0, &r
, 0);
3800 workarea_w
= r
.right
- r
.left
;
3801 workarea_h
= r
.bottom
- r
.top
- GetSystemMetrics(SM_CYCAPTION
);
3803 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
3804 index
= cfi
.nFont
; /* save current font index */
3806 hmod
= GetModuleHandleA("kernel32.dll");
3807 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
3808 if (!pGetNumberOfConsoleFonts
)
3810 win_skip("GetNumberOfConsoleFonts is not available\n");
3813 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
3814 if (!pSetConsoleFont
)
3816 win_skip("SetConsoleFont is not available\n");
3820 for (i
= 0; i
< pGetNumberOfConsoleFonts(); i
++)
3822 pSetConsoleFont(std_output
, i
);
3823 memset(&c
, 10, sizeof(COORD
));
3824 SetLastError(0xdeadbeef);
3825 c
= GetLargestConsoleWindowSize(std_output
);
3826 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3827 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
);
3828 font
= GetConsoleFontSize(std_output
, cfi
.nFont
);
3829 maxcon_w
= workarea_w
/ font
.X
;
3830 maxcon_h
= workarea_h
/ font
.Y
;
3831 ok(c
.X
== maxcon_w
|| c
.X
== maxcon_w
- 1 /* Win10 */, "got %d, expected %ld\n", c
.X
, maxcon_w
);
3832 ok(c
.Y
== maxcon_h
|| c
.Y
== maxcon_h
- 1 /* Win10 */, "got %d, expected %ld\n", c
.Y
, maxcon_h
);
3834 ret
= GetConsoleScreenBufferInfo(std_output
, &sbi
);
3835 ok(ret
, "GetConsoleScreenBufferInfo failed %lu\n", GetLastError());
3836 ok(sbi
.dwMaximumWindowSize
.X
== min(c
.X
, sbi
.dwSize
.X
), "got %d, expected %d\n",
3837 sbi
.dwMaximumWindowSize
.X
, min(c
.X
, sbi
.dwSize
.X
));
3838 ok(sbi
.dwMaximumWindowSize
.Y
== min(c
.Y
, sbi
.dwSize
.Y
), "got %d, expected %d\n",
3839 sbi
.dwMaximumWindowSize
.Y
, min(c
.Y
, sbi
.dwSize
.Y
));
3841 pSetConsoleFont(std_output
, index
); /* restore original font size */
3844 static void test_GetConsoleFontInfo(HANDLE std_output
)
3847 BOOL (WINAPI
*pGetConsoleFontInfo
)(HANDLE
, BOOL
, DWORD
, CONSOLE_FONT_INFO
*);
3848 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
3849 DWORD num_fonts
, index
, i
;
3850 int memsize
, win_width
, win_height
, tmp_w
, tmp_h
;
3851 CONSOLE_FONT_INFO
*cfi
;
3853 CONSOLE_SCREEN_BUFFER_INFO csbi
;
3854 COORD orig_sb_size
, tmp_sb_size
, orig_font
, tmp_font
;
3856 hmod
= GetModuleHandleA("kernel32.dll");
3857 pGetConsoleFontInfo
= (void *)GetProcAddress(hmod
, "GetConsoleFontInfo");
3858 if (!pGetConsoleFontInfo
)
3860 win_skip("GetConsoleFontInfo is not available\n");
3864 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
3865 if (!pGetNumberOfConsoleFonts
)
3867 win_skip("GetNumberOfConsoleFonts is not available\n");
3871 num_fonts
= pGetNumberOfConsoleFonts();
3872 memsize
= num_fonts
* sizeof(CONSOLE_FONT_INFO
);
3873 cfi
= HeapAlloc(GetProcessHeap(), 0, memsize
);
3874 memset(cfi
, 0, memsize
);
3876 GetConsoleScreenBufferInfo(std_output
, &csbi
);
3877 orig_sb_size
= csbi
.dwSize
;
3878 tmp_sb_size
.X
= csbi
.dwSize
.X
+ 3;
3879 tmp_sb_size
.Y
= csbi
.dwSize
.Y
+ 5;
3880 SetConsoleScreenBufferSize(std_output
, tmp_sb_size
);
3882 SetLastError(0xdeadbeef);
3883 ret
= pGetConsoleFontInfo(NULL
, FALSE
, 0, cfi
);
3884 ok(!ret
, "got %d, expected zero\n", ret
);
3885 if (GetLastError() == LOWORD(E_NOTIMPL
) /* win10 1709+ */ ||
3886 broken(GetLastError() == ERROR_GEN_FAILURE
) /* win10 1607 */)
3888 skip("GetConsoleFontInfo is not implemented\n");
3889 SetConsoleScreenBufferSize(std_output
, orig_sb_size
);
3890 HeapFree(GetProcessHeap(), 0, cfi
);
3893 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3895 SetLastError(0xdeadbeef);
3896 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), FALSE
, 0, cfi
);
3897 ok(!ret
, "got %d, expected zero\n", ret
);
3898 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3900 SetLastError(0xdeadbeef);
3901 ret
= pGetConsoleFontInfo(std_output
, FALSE
, 0, cfi
);
3902 ok(!ret
, "got %d, expected zero\n", ret
);
3903 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3905 GetConsoleScreenBufferInfo(std_output
, &csbi
);
3906 win_width
= csbi
.srWindow
.Right
- csbi
.srWindow
.Left
+ 1;
3907 win_height
= csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
+ 1;
3909 GetCurrentConsoleFont(std_output
, FALSE
, &cfi
[0]);
3910 index
= cfi
[0].nFont
;
3911 orig_font
= GetConsoleFontSize(std_output
, index
);
3913 memset(cfi
, 0, memsize
);
3914 ret
= pGetConsoleFontInfo(std_output
, FALSE
, num_fonts
, cfi
);
3915 ok(ret
, "got %d, expected non-zero\n", ret
);
3916 ok(cfi
[index
].dwFontSize
.X
== win_width
, "got %d, expected %d\n",
3917 cfi
[index
].dwFontSize
.X
, win_width
);
3918 ok(cfi
[index
].dwFontSize
.Y
== win_height
, "got %d, expected %d\n",
3919 cfi
[index
].dwFontSize
.Y
, win_height
);
3921 for (i
= 0; i
< num_fonts
; i
++)
3923 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %ld, expected %ld\n", cfi
[i
].nFont
, i
);
3924 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
3925 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* win_width
;
3926 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* win_height
;
3927 ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
3928 ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
3931 SetLastError(0xdeadbeef);
3932 ret
= pGetConsoleFontInfo(NULL
, TRUE
, 0, cfi
);
3933 ok(!ret
, "got %d, expected zero\n", ret
);
3934 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3936 SetLastError(0xdeadbeef);
3937 ret
= pGetConsoleFontInfo(GetStdHandle(STD_INPUT_HANDLE
), TRUE
, 0, cfi
);
3938 ok(!ret
, "got %d, expected zero\n", ret
);
3939 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3941 SetLastError(0xdeadbeef);
3942 ret
= pGetConsoleFontInfo(std_output
, TRUE
, 0, cfi
);
3943 ok(!ret
, "got %d, expected zero\n", ret
);
3944 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
3946 memset(cfi
, 0, memsize
);
3947 ret
= pGetConsoleFontInfo(std_output
, TRUE
, num_fonts
, cfi
);
3948 ok(ret
, "got %d, expected non-zero\n", ret
);
3949 ok(cfi
[index
].dwFontSize
.X
== csbi
.dwMaximumWindowSize
.X
, "got %d, expected %d\n",
3950 cfi
[index
].dwFontSize
.X
, csbi
.dwMaximumWindowSize
.X
);
3951 ok(cfi
[index
].dwFontSize
.Y
== csbi
.dwMaximumWindowSize
.Y
, "got %d, expected %d\n",
3952 cfi
[index
].dwFontSize
.Y
, csbi
.dwMaximumWindowSize
.Y
);
3954 for (i
= 0; i
< num_fonts
; i
++)
3956 ok(cfi
[i
].nFont
== i
, "element out of order, got nFont %ld, expected %ld\n", cfi
[i
].nFont
, i
);
3957 tmp_font
= GetConsoleFontSize(std_output
, cfi
[i
].nFont
);
3958 tmp_w
= (double)orig_font
.X
/ tmp_font
.X
* csbi
.dwMaximumWindowSize
.X
;
3959 tmp_h
= (double)orig_font
.Y
/ tmp_font
.Y
* csbi
.dwMaximumWindowSize
.Y
;
3960 ok(cfi
[i
].dwFontSize
.X
== tmp_w
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.X
, tmp_w
);
3961 ok(cfi
[i
].dwFontSize
.Y
== tmp_h
, "got %d, expected %d\n", cfi
[i
].dwFontSize
.Y
, tmp_h
);
3964 HeapFree(GetProcessHeap(), 0, cfi
);
3965 SetConsoleScreenBufferSize(std_output
, orig_sb_size
);
3968 static void test_SetConsoleFont(HANDLE std_output
)
3971 BOOL (WINAPI
*pSetConsoleFont
)(HANDLE
, DWORD
);
3973 DWORD (WINAPI
*pGetNumberOfConsoleFonts
)(void);
3976 hmod
= GetModuleHandleA("kernel32.dll");
3977 pSetConsoleFont
= (void *)GetProcAddress(hmod
, "SetConsoleFont");
3978 if (!pSetConsoleFont
)
3980 win_skip("SetConsoleFont is not available\n");
3984 SetLastError(0xdeadbeef);
3985 ret
= pSetConsoleFont(NULL
, 0);
3986 ok(!ret
, "got %d, expected zero\n", ret
);
3987 if (GetLastError() == LOWORD(E_NOTIMPL
) /* win10 1709+ */ ||
3988 broken(GetLastError() == ERROR_GEN_FAILURE
) /* win10 1607 */)
3990 skip("SetConsoleFont is not implemented\n");
3993 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
3995 SetLastError(0xdeadbeef);
3996 ret
= pSetConsoleFont(GetStdHandle(STD_INPUT_HANDLE
), 0);
3997 ok(!ret
, "got %d, expected zero\n", ret
);
3998 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
4000 pGetNumberOfConsoleFonts
= (void *)GetProcAddress(hmod
, "GetNumberOfConsoleFonts");
4001 if (!pGetNumberOfConsoleFonts
)
4003 win_skip("GetNumberOfConsoleFonts is not available\n");
4007 num_fonts
= pGetNumberOfConsoleFonts();
4009 SetLastError(0xdeadbeef);
4010 ret
= pSetConsoleFont(std_output
, num_fonts
);
4011 ok(!ret
, "got %d, expected zero\n", ret
);
4012 todo_wine
ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
4015 static void test_GetConsoleScreenBufferInfoEx(HANDLE std_output
)
4018 BOOL (WINAPI
*pGetConsoleScreenBufferInfoEx
)(HANDLE
, CONSOLE_SCREEN_BUFFER_INFOEX
*);
4019 CONSOLE_SCREEN_BUFFER_INFOEX csbix
;
4020 HANDLE pipe1
, pipe2
;
4022 HANDLE std_input
= GetStdHandle(STD_INPUT_HANDLE
);
4024 hmod
= GetModuleHandleA("kernel32.dll");
4025 pGetConsoleScreenBufferInfoEx
= (void *)GetProcAddress(hmod
, "GetConsoleScreenBufferInfoEx");
4026 if (!pGetConsoleScreenBufferInfoEx
)
4028 win_skip("GetConsoleScreenBufferInfoEx is not available\n");
4032 SetLastError(0xdeadbeef);
4033 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
4034 ok(!ret
, "got %d, expected zero\n", ret
);
4035 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
4037 SetLastError(0xdeadbeef);
4038 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
4039 ok(!ret
, "got %d, expected zero\n", ret
);
4040 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
4042 SetLastError(0xdeadbeef);
4043 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
4044 ok(!ret
, "got %d, expected zero\n", ret
);
4045 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
4047 csbix
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
4049 SetLastError(0xdeadbeef);
4050 ret
= pGetConsoleScreenBufferInfoEx(NULL
, &csbix
);
4051 ok(!ret
, "got %d, expected zero\n", ret
);
4052 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
4054 SetLastError(0xdeadbeef);
4055 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
4056 ok(!ret
, "got %d, expected zero\n", ret
);
4057 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
4059 CreatePipe(&pipe1
, &pipe2
, NULL
, 0);
4060 SetLastError(0xdeadbeef);
4061 ret
= pGetConsoleScreenBufferInfoEx(std_input
, &csbix
);
4062 ok(!ret
, "got %d, expected zero\n", ret
);
4063 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
4067 SetLastError(0xdeadbeef);
4068 ret
= pGetConsoleScreenBufferInfoEx(std_output
, &csbix
);
4069 ok(ret
, "got %d, expected non-zero\n", ret
);
4070 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
4073 static void test_FreeConsole(void)
4075 HANDLE handle
, unbound_output
= NULL
, unbound_input
= NULL
;
4076 DWORD size
, mode
, type
;
4083 ok(RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
!= NULL
, "ConsoleHandle is NULL\n");
4084 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "dummy ctrl handler shouldn't be set\n");
4085 ret
= SetConsoleCtrlHandler(mydummych
, TRUE
);
4086 ok(ret
, "SetConsoleCtrlHandler failed: %lu\n", GetLastError());
4089 unbound_input
= create_unbound_handle(FALSE
, TRUE
);
4090 unbound_output
= create_unbound_handle(TRUE
, TRUE
);
4093 ret
= FreeConsole();
4094 ok(ret
, "FreeConsole failed: %lu\n", GetLastError());
4096 ok(RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
== NULL
, "ConsoleHandle = %p\n",
4097 RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
);
4099 handle
= CreateFileA("CONOUT$", GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4100 ok(handle
== INVALID_HANDLE_VALUE
&&
4101 (GetLastError() == ERROR_INVALID_HANDLE
|| broken(GetLastError() == ERROR_ACCESS_DENIED
/* winxp */)),
4102 "CreateFileA failed: %lu\n", GetLastError());
4104 handle
= CreateFileA("CONIN$", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4105 ok(handle
== INVALID_HANDLE_VALUE
&&
4106 (GetLastError() == ERROR_INVALID_HANDLE
|| broken(GetLastError() == ERROR_ACCESS_DENIED
/* winxp */)),
4107 "CreateFileA failed: %lu\n", GetLastError());
4109 handle
= CreateFileA("CON", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4110 ok(handle
== INVALID_HANDLE_VALUE
&&
4111 (GetLastError() == ERROR_INVALID_HANDLE
|| broken(GetLastError() == ERROR_ACCESS_DENIED
/* winxp */)),
4112 "CreateFileA failed: %lu\n", GetLastError());
4114 handle
= CreateFileA("CON", GENERIC_READ
| GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4115 ok(handle
== INVALID_HANDLE_VALUE
&&
4116 (GetLastError() == ERROR_INVALID_HANDLE
|| broken(GetLastError() == ERROR_FILE_NOT_FOUND
/* winxp */)),
4117 "CreateFileA failed: %lu\n", GetLastError());
4119 handle
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
,
4120 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4121 CONSOLE_TEXTMODE_BUFFER
, NULL
);
4122 ok(handle
== INVALID_HANDLE_VALUE
&& GetLastError() == ERROR_INVALID_HANDLE
,
4123 "CreateConsoleScreenBuffer returned: %p (%lu)\n", handle
, GetLastError());
4125 SetLastError(0xdeadbeef);
4126 cp
= GetConsoleCP();
4127 ok(!cp
, "cp = %x\n", cp
);
4128 ok(GetLastError() == ERROR_INVALID_HANDLE
, "last error %lu\n", GetLastError());
4130 SetLastError(0xdeadbeef);
4131 cp
= GetConsoleOutputCP();
4132 ok(!cp
, "cp = %x\n", cp
);
4133 ok(GetLastError() == ERROR_INVALID_HANDLE
, "last error %lu\n", GetLastError());
4135 SetLastError(0xdeadbeef);
4136 ret
= SetConsoleCP(GetOEMCP());
4137 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "SetConsoleCP returned %x(%lu)\n", ret
, GetLastError());
4139 SetLastError(0xdeadbeef);
4140 ret
= SetConsoleOutputCP(GetOEMCP());
4141 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "SetConsoleCP returned %x(%lu)\n", ret
, GetLastError());
4143 if (skip_nt
) return;
4145 SetLastError(0xdeadbeef);
4146 memset( title
, 0xc0, sizeof(title
) );
4147 size
= GetConsoleTitleW( title
, ARRAY_SIZE(title
) );
4148 ok(!size
, "GetConsoleTitleW returned %lu\n", size
);
4149 ok(title
[0] == 0xc0c0, "title byffer changed\n");
4150 ok(GetLastError() == ERROR_INVALID_HANDLE
, "last error %lu\n", GetLastError());
4152 SetLastError(0xdeadbeef);
4153 ret
= SetConsoleTitleW( L
"test" );
4154 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "SetConsoleTitleW returned %x(%lu)\n", ret
, GetLastError());
4156 SetLastError(0xdeadbeef);
4157 hwnd
= GetConsoleWindow();
4158 ok(!hwnd
, "hwnd = %p\n", hwnd
);
4159 ok(GetLastError() == ERROR_INVALID_HANDLE
, "last error %lu\n", GetLastError());
4161 ret
= GenerateConsoleCtrlEvent(CTRL_C_EVENT
, 0);
4162 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
, "GenerateConsoleCtrlEvent returned %x(%lu)\n",
4163 ret
, GetLastError());
4165 SetStdHandle( STD_INPUT_HANDLE
, (HANDLE
)0xdeadbeef );
4166 handle
= GetConsoleInputWaitHandle();
4167 ok(handle
== (HANDLE
)0xdeadbeef, "GetConsoleInputWaitHandle returned %p\n", handle
);
4168 SetStdHandle( STD_INPUT_HANDLE
, NULL
);
4169 handle
= GetConsoleInputWaitHandle();
4170 ok(!handle
, "GetConsoleInputWaitHandle returned %p\n", handle
);
4172 ret
= ReadFile(unbound_input
, buf
, sizeof(buf
), &size
, NULL
);
4173 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
4174 "ReadFile returned %x %lu\n", ret
, GetLastError());
4176 ret
= FlushFileBuffers(unbound_input
);
4177 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
4178 "ReadFile returned %x %lu\n", ret
, GetLastError());
4180 ret
= WriteFile(unbound_input
, "test", 4, &size
, NULL
);
4181 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
4182 "ReadFile returned %x %lu\n", ret
, GetLastError());
4184 ret
= GetConsoleMode(unbound_input
, &mode
);
4185 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
4186 "GetConsoleMode returned %x %lu\n", ret
, GetLastError());
4187 ret
= GetConsoleMode(unbound_output
, &mode
);
4188 ok(!ret
&& GetLastError() == ERROR_INVALID_HANDLE
,
4189 "GetConsoleMode returned %x %lu\n", ret
, GetLastError());
4191 type
= GetFileType(unbound_input
);
4192 ok(type
== FILE_TYPE_CHAR
, "GetFileType returned %lu\n", type
);
4193 type
= GetFileType(unbound_output
);
4194 ok(type
== FILE_TYPE_CHAR
, "GetFileType returned %lu\n", type
);
4197 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "FreeConsole() should have reset ctrl handlers' list\n");
4199 CloseHandle(unbound_input
);
4200 CloseHandle(unbound_output
);
4203 static void test_SetConsoleScreenBufferInfoEx(HANDLE std_output
)
4207 HANDLE std_input
= CreateFileA("CONIN$", GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4208 BOOL (WINAPI
*pSetConsoleScreenBufferInfoEx
)(HANDLE
, CONSOLE_SCREEN_BUFFER_INFOEX
*);
4209 BOOL (WINAPI
*pGetConsoleScreenBufferInfoEx
)(HANDLE
, CONSOLE_SCREEN_BUFFER_INFOEX
*);
4210 CONSOLE_SCREEN_BUFFER_INFOEX info
;
4212 hmod
= GetModuleHandleA("kernel32.dll");
4213 pSetConsoleScreenBufferInfoEx
= (void *)GetProcAddress(hmod
, "SetConsoleScreenBufferInfoEx");
4214 pGetConsoleScreenBufferInfoEx
= (void *)GetProcAddress(hmod
, "GetConsoleScreenBufferInfoEx");
4215 if (!pSetConsoleScreenBufferInfoEx
|| !pGetConsoleScreenBufferInfoEx
)
4217 win_skip("SetConsoleScreenBufferInfoEx is not available\n");
4221 memset(&info
, 0, sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
));
4222 info
.cbSize
= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
);
4223 pGetConsoleScreenBufferInfoEx(std_output
, &info
);
4225 SetLastError(0xdeadbeef);
4226 ret
= pSetConsoleScreenBufferInfoEx(NULL
, &info
);
4227 ok(!ret
, "got %d, expected zero\n", ret
);
4228 ok(GetLastError() == ERROR_INVALID_HANDLE
, "got %lu, expected 6\n", GetLastError());
4230 SetLastError(0xdeadbeef);
4231 ret
= pSetConsoleScreenBufferInfoEx(std_output
, &info
);
4232 ok(ret
, "got %d, expected one\n", ret
);
4233 ok(GetLastError() == 0xdeadbeef, "got %lu, expected 0xdeadbeef\n", GetLastError());
4235 SetLastError(0xdeadbeef);
4236 ret
= pSetConsoleScreenBufferInfoEx(std_input
, &info
);
4237 ok(!ret
, "got %d, expected zero\n", ret
);
4238 ok(GetLastError() == ERROR_INVALID_HANDLE
|| GetLastError() == ERROR_ACCESS_DENIED
,
4239 "got %lu, expected 5 or 6\n", GetLastError());
4242 SetLastError(0xdeadbeef);
4243 ret
= pSetConsoleScreenBufferInfoEx(std_output
, &info
);
4244 ok(!ret
, "got %d, expected zero\n", ret
);
4245 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "got %lu, expected 87\n", GetLastError());
4247 CloseHandle(std_input
);
4250 static void test_GetConsoleOriginalTitleA(void)
4252 char title
[] = "Original Console Title";
4254 DWORD ret
, title_len
= strlen(title
);
4256 ret
= GetConsoleOriginalTitleA(NULL
, 0);
4257 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4259 ret
= GetConsoleOriginalTitleA(buf
, 0);
4260 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4262 ret
= GetConsoleOriginalTitleA(buf
, ARRAY_SIZE(buf
));
4263 ok(ret
, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError());
4264 ok(!strcmp(buf
, title
), "got %s, expected %s\n", wine_dbgstr_a(buf
), wine_dbgstr_a(title
));
4265 ok(ret
== title_len
, "got %lu, expected %lu\n", ret
, title_len
);
4267 ret
= SetConsoleTitleA("test");
4268 ok(ret
, "SetConsoleTitleA failed: %lu\n", GetLastError());
4270 ret
= GetConsoleOriginalTitleA(buf
, ARRAY_SIZE(buf
));
4271 ok(ret
, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError());
4272 ok(!strcmp(buf
, title
), "got %s, expected %s\n", wine_dbgstr_a(buf
), wine_dbgstr_a(title
));
4273 ok(ret
== title_len
, "got %lu, expected %lu\n", ret
, title_len
);
4276 static void test_GetConsoleOriginalTitleW(void)
4278 WCHAR title
[] = L
"Original Console Title";
4280 DWORD ret
, title_len
= lstrlenW(title
);
4282 ret
= GetConsoleOriginalTitleW(NULL
, 0);
4283 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4285 ret
= GetConsoleOriginalTitleW(buf
, 0);
4286 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4288 ret
= GetConsoleOriginalTitleW(buf
, ARRAY_SIZE(buf
));
4289 ok(ret
, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError());
4291 ok(!wcscmp(buf
, title
), "got %s, expected %s\n", wine_dbgstr_w(buf
), wine_dbgstr_w(title
));
4292 ok(ret
== title_len
, "got %lu, expected %lu\n", ret
, title_len
);
4294 ret
= SetConsoleTitleW(L
"test");
4295 ok(ret
, "SetConsoleTitleW failed: %lu\n", GetLastError());
4297 ret
= GetConsoleOriginalTitleW(buf
, ARRAY_SIZE(buf
));
4298 ok(ret
, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError());
4299 ok(!wcscmp(buf
, title
), "got %s, expected %s\n", wine_dbgstr_w(buf
), wine_dbgstr_w(title
));
4300 ok(ret
== title_len
, "got %lu, expected %lu\n", ret
, title_len
);
4302 ret
= GetConsoleOriginalTitleW(buf
, 5);
4303 ok(ret
, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError());
4304 ok(!wcscmp(buf
, L
"Orig"), "got %s, expected 'Orig'\n", wine_dbgstr_w(buf
));
4305 ok(ret
== title_len
, "got %lu, expected %lu\n", ret
, title_len
);
4308 static void test_GetConsoleOriginalTitleW_empty(void)
4313 ret
= GetConsoleOriginalTitleW(buf
, ARRAY_SIZE(buf
));
4314 ok(!ret
, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError());
4317 static void test_GetConsoleOriginalTitle(void)
4319 STARTUPINFOA si
= { sizeof(si
) };
4320 PROCESS_INFORMATION info
;
4321 char **argv
, buf
[MAX_PATH
];
4322 char title
[] = "Original Console Title";
4325 winetest_get_mainargs(&argv
);
4326 sprintf(buf
, "\"%s\" console title_test", argv
[0]);
4328 ret
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, CREATE_NEW_CONSOLE
, NULL
, NULL
, &si
, &info
);
4329 ok(ret
, "CreateProcess failed: %lu\n", GetLastError());
4330 CloseHandle(info
.hThread
);
4331 wait_child_process(info
.hProcess
);
4332 CloseHandle(info
.hProcess
);
4334 strcat(buf
, " empty");
4336 ret
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, CREATE_NEW_CONSOLE
, NULL
, NULL
, &si
, &info
);
4337 ok(ret
, "CreateProcess failed: %lu\n", GetLastError());
4338 CloseHandle(info
.hThread
);
4339 wait_child_process(info
.hProcess
);
4340 CloseHandle(info
.hProcess
);
4343 static void test_GetConsoleTitleA(void)
4345 char buf
[64], str
[] = "test";
4348 ret
= SetConsoleTitleA(str
);
4349 ok(ret
, "SetConsoleTitleA failed: %lu\n", GetLastError());
4351 ret
= GetConsoleTitleA(NULL
, 0);
4352 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4354 ret
= GetConsoleTitleA(buf
, 0);
4355 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4357 ret
= GetConsoleTitleA(buf
, ARRAY_SIZE(buf
));
4358 ok(ret
, "GetConsoleTitleW failed: %lu\n", GetLastError());
4359 ok(ret
== strlen(str
), "Got string length %lu, expected %Iu\n", ret
, strlen(str
));
4360 ok(!strcmp(buf
, str
), "Title = %s\n", wine_dbgstr_a(buf
));
4362 ret
= SetConsoleTitleA("");
4363 ok(ret
, "SetConsoleTitleA failed: %lu\n", GetLastError());
4365 ret
= GetConsoleTitleA(buf
, ARRAY_SIZE(buf
));
4366 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4369 static void test_GetConsoleTitleW(void)
4371 WCHAR buf
[64], str
[] = L
"test";
4374 ret
= SetConsoleTitleW(str
);
4375 ok(ret
, "SetConsoleTitleW failed: %lu\n", GetLastError());
4377 ret
= GetConsoleTitleW(NULL
, 0);
4378 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4380 ret
= GetConsoleTitleW(buf
, 0);
4381 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4383 ret
= GetConsoleTitleW(buf
, ARRAY_SIZE(buf
));
4384 ok(ret
, "GetConsoleTitleW failed: %lu\n", GetLastError());
4385 ok(ret
== wcslen(str
), "Got string length %lu, expected %Iu\n", ret
, wcslen(str
));
4386 ok(!wcscmp(buf
, str
), "Title = %s\n", wine_dbgstr_w(buf
));
4388 ret
= GetConsoleTitleW(buf
, 2);
4389 ok(ret
, "GetConsoleTitleW failed: %lu\n", GetLastError());
4390 ok(ret
== wcslen(str
), "Got string length %lu, expected %Iu\n", ret
, wcslen(str
));
4391 if (!skip_nt
) ok(!wcscmp(buf
, L
"t"), "Title = %s\n", wine_dbgstr_w(buf
));
4393 ret
= GetConsoleTitleW(buf
, 4);
4394 ok(ret
, "GetConsoleTitleW failed: %lu\n", GetLastError());
4395 ok(ret
== wcslen(str
), "Got string length %lu, expected %Iu\n", ret
, wcslen(str
));
4396 if (!skip_nt
) ok(!wcscmp(buf
, L
"tes"), "Title = %s\n", wine_dbgstr_w(buf
));
4398 ret
= SetConsoleTitleW(L
"");
4399 ok(ret
, "SetConsoleTitleW failed: %lu\n", GetLastError());
4401 ret
= GetConsoleTitleW(buf
, ARRAY_SIZE(buf
));
4402 ok(!ret
, "Unexpected string length; error %lu\n", GetLastError());
4405 static void test_file_info(HANDLE input
, HANDLE output
)
4407 FILE_STANDARD_INFORMATION std_info
;
4408 FILE_FS_DEVICE_INFORMATION fs_info
;
4415 if (skip_nt
) return;
4417 status
= NtQueryInformationFile(input
, &io
, &std_info
, sizeof(std_info
), FileStandardInformation
);
4418 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtQueryInformationFile returned: %#lx\n", status
);
4420 status
= NtQueryInformationFile(output
, &io
, &std_info
, sizeof(std_info
), FileStandardInformation
);
4421 ok(status
== STATUS_INVALID_DEVICE_REQUEST
, "NtQueryInformationFile returned: %#lx\n", status
);
4423 ret
= GetFileSizeEx(input
, &size
);
4424 ok(!ret
&& GetLastError() == ERROR_INVALID_FUNCTION
,
4425 "GetFileSizeEx returned %x(%lu)\n", ret
, GetLastError());
4427 ret
= GetFileSizeEx(output
, &size
);
4428 ok(!ret
&& GetLastError() == ERROR_INVALID_FUNCTION
,
4429 "GetFileSizeEx returned %x(%lu)\n", ret
, GetLastError());
4431 status
= NtQueryVolumeInformationFile(input
, &io
, &fs_info
, sizeof(fs_info
), FileFsDeviceInformation
);
4432 ok(!status
, "NtQueryVolumeInformationFile failed: %#lx\n", status
);
4433 ok(fs_info
.DeviceType
== FILE_DEVICE_CONSOLE
, "DeviceType = %lu\n", fs_info
.DeviceType
);
4434 ok(fs_info
.Characteristics
== FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
,
4435 "Characteristics = %lx\n", fs_info
.Characteristics
);
4437 status
= NtQueryVolumeInformationFile(output
, &io
, &fs_info
, sizeof(fs_info
), FileFsDeviceInformation
);
4438 ok(!status
, "NtQueryVolumeInformationFile failed: %#lx\n", status
);
4439 ok(fs_info
.DeviceType
== FILE_DEVICE_CONSOLE
, "DeviceType = %lu\n", fs_info
.DeviceType
);
4440 ok(fs_info
.Characteristics
== FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL
,
4441 "Characteristics = %lx\n", fs_info
.Characteristics
);
4443 type
= GetFileType(input
);
4444 ok(type
== FILE_TYPE_CHAR
, "GetFileType returned %lu\n", type
);
4445 type
= GetFileType(output
);
4446 ok(type
== FILE_TYPE_CHAR
, "GetFileType returned %lu\n", type
);
4449 static void test_AttachConsole_child(DWORD console_pid
)
4451 HANDLE pipe_in
, pipe_out
;
4458 res
= CreatePipe(&pipe_in
, &pipe_out
, NULL
, 0);
4459 ok(res
, "CreatePipe failed: %lu\n", GetLastError());
4461 res
= AttachConsole(console_pid
);
4462 ok(!res
&& GetLastError() == ERROR_ACCESS_DENIED
,
4463 "AttachConsole returned: %x(%lu)\n", res
, GetLastError());
4465 ok(RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
!= NULL
, "ConsoleHandle is NULL\n");
4466 res
= FreeConsole();
4467 ok(res
, "FreeConsole failed: %lu\n", GetLastError());
4468 ok(RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
== NULL
, "ConsoleHandle = %p\n",
4469 RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
);
4471 SetStdHandle(STD_ERROR_HANDLE
, pipe_out
);
4473 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "dummy ctrl handler shouldn't be set\n");
4474 res
= SetConsoleCtrlHandler(mydummych
, TRUE
);
4475 ok(res
, "SetConsoleCtrlHandler failed: %lu\n", GetLastError());
4477 res
= AttachConsole(console_pid
);
4478 ok(res
, "AttachConsole failed: %lu\n", GetLastError());
4480 ok(pipe_out
!= GetStdHandle(STD_ERROR_HANDLE
), "std handle not set to console\n");
4481 ok(RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
!= NULL
, "ConsoleHandle is NULL\n");
4483 console
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4484 ok(console
!= INVALID_HANDLE_VALUE
, "Could not open console\n");
4486 res
= ReadConsoleOutputCharacterA(console
, buf
, 6, c
, &len
);
4487 ok(res
, "ReadConsoleOutputCharacterA failed: %lu\n", GetLastError());
4488 ok(len
== 6, "len = %lu\n", len
);
4489 ok(!memcmp(buf
, "Parent", 6), "Unexpected console output\n");
4492 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "AttachConsole() should have reset ctrl handlers' list\n");
4494 res
= FreeConsole();
4495 ok(res
, "FreeConsole failed: %lu\n", GetLastError());
4497 SetStdHandle(STD_INPUT_HANDLE
, pipe_in
);
4498 SetStdHandle(STD_OUTPUT_HANDLE
, pipe_out
);
4500 res
= AttachConsole(ATTACH_PARENT_PROCESS
);
4501 ok(res
, "AttachConsole failed: %lu\n", GetLastError());
4503 if (pGetConsoleProcessList
)
4505 DWORD list
[2] = { 0xbabebabe };
4506 DWORD pid
= GetCurrentProcessId();
4508 SetLastError(0xdeadbeef);
4509 len
= pGetConsoleProcessList(list
, 1);
4510 ok(len
== 2, "Expected 2 processes, got %ld\n", len
);
4511 ok(list
[0] == 0xbabebabe, "Unexpected value in list %lu\n", list
[0]);
4513 len
= pGetConsoleProcessList(list
, 2);
4514 ok(len
== 2, "Expected 2 processes, got %ld\n", len
);
4515 ok(list
[0] == console_pid
|| list
[1] == console_pid
, "Parent PID not in list\n");
4516 ok(list
[0] == pid
|| list
[1] == pid
, "PID not in list\n");
4517 ok(GetLastError() == 0xdeadbeef, "Unexpected last error: %lu\n", GetLastError());
4520 ok(pipe_in
!= GetStdHandle(STD_INPUT_HANDLE
), "std handle not set to console\n");
4521 ok(pipe_out
!= GetStdHandle(STD_OUTPUT_HANDLE
), "std handle not set to console\n");
4523 console
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
4524 ok(console
!= INVALID_HANDLE_VALUE
, "Could not open console\n");
4526 res
= ReadConsoleOutputCharacterA(console
, buf
, 6, c
, &len
);
4527 ok(res
, "ReadConsoleOutputCharacterA failed: %lu\n", GetLastError());
4528 ok(len
== 6, "len = %lu\n", len
);
4529 ok(!memcmp(buf
, "Parent", 6), "Unexpected console output\n");
4531 simple_write_console(console
, "Child");
4532 CloseHandle(console
);
4534 res
= FreeConsole();
4535 ok(res
, "FreeConsole failed: %lu\n", GetLastError());
4537 res
= CloseHandle(pipe_in
);
4538 ok(res
, "pipe_in is no longer valid\n");
4539 res
= CloseHandle(pipe_out
);
4540 ok(res
, "pipe_out is no longer valid\n");
4543 static void test_AttachConsole(HANDLE console
)
4545 STARTUPINFOA si
= { sizeof(si
) };
4546 PROCESS_INFORMATION info
;
4547 char **argv
, buf
[MAX_PATH
];
4552 simple_write_console(console
, "Parent console");
4554 winetest_get_mainargs(&argv
);
4555 sprintf(buf
, "\"%s\" console attach_console %lx", argv
[0], GetCurrentProcessId());
4556 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, 0, NULL
, NULL
, &si
, &info
);
4557 ok(res
, "CreateProcess failed: %lu\n", GetLastError());
4558 CloseHandle(info
.hThread
);
4560 wait_child_process(info
.hProcess
);
4561 CloseHandle(info
.hProcess
);
4563 res
= ReadConsoleOutputCharacterA(console
, buf
, 5, c
, &len
);
4564 ok(res
, "ReadConsoleOutputCharacterA failed: %lu\n", GetLastError());
4565 ok(len
== 5, "len = %lu\n", len
);
4566 ok(!memcmp(buf
, "Child", 5), "Unexpected console output\n");
4569 static void test_AllocConsole_child(void)
4571 HANDLE unbound_output
;
4572 HANDLE prev_output
, prev_error
;
4577 GetStartupInfoW(&si
);
4579 prev_output
= GetStdHandle(STD_OUTPUT_HANDLE
);
4580 res
= DuplicateHandle(GetCurrentProcess(), prev_output
, GetCurrentProcess(), &unbound_output
,
4581 0, FALSE
, DUPLICATE_SAME_ACCESS
);
4582 ok(res
, "DuplicateHandle failed: %lu\n", GetLastError());
4584 res
= GetConsoleMode(unbound_output
, &mode
);
4585 ok(res
, "GetConsoleMode failed: %lu\n", GetLastError());
4587 prev_error
= GetStdHandle(STD_ERROR_HANDLE
);
4588 if (si
.dwFlags
& STARTF_USESTDHANDLES
)
4590 res
= GetConsoleMode(prev_error
, &mode
);
4591 ok(!res
&& GetLastError() == ERROR_INVALID_HANDLE
, "GetConsoleMode failed: %lu\n", GetLastError());
4596 ok(GetStdHandle(STD_OUTPUT_HANDLE
) == prev_output
, "GetStdHandle(STD_OUTPUT_HANDLE) = %p\n", GetStdHandle(STD_OUTPUT_HANDLE
));
4597 ok(GetStdHandle(STD_ERROR_HANDLE
) == prev_error
, "GetStdHandle(STD_ERROR_HANDLE) = %p\n", GetStdHandle(STD_ERROR_HANDLE
));
4598 res
= GetConsoleMode(unbound_output
, &mode
);
4599 ok(!res
&& GetLastError() == ERROR_INVALID_HANDLE
, "GetConsoleMode failed: %lu\n", GetLastError());
4601 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "dummy ctrl handler shouldn't be set\n");
4602 res
= SetConsoleCtrlHandler(mydummych
, TRUE
);
4603 ok(res
, "SetConsoleCtrlHandler failed: %lu\n", GetLastError());
4604 res
= AllocConsole();
4605 ok(res
, "AllocConsole failed: %lu\n", GetLastError());
4607 if (si
.dwFlags
& STARTF_USESTDHANDLES
)
4609 ok(GetStdHandle(STD_OUTPUT_HANDLE
) == prev_output
, "GetStdHandle(STD_OUTPUT_HANDLE) = %p\n", GetStdHandle(STD_OUTPUT_HANDLE
));
4610 ok(GetStdHandle(STD_ERROR_HANDLE
) == prev_error
, "GetStdHandle(STD_ERROR_HANDLE) = %p\n", GetStdHandle(STD_ERROR_HANDLE
));
4613 res
= GetConsoleMode(unbound_output
, &mode
);
4614 ok(res
, "GetConsoleMode failed: %lu\n", GetLastError());
4617 ok(!SetConsoleCtrlHandler(mydummych
, FALSE
), "AllocConsole() should have reset ctrl handlers' list\n");
4620 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
4621 SetStdHandle(STD_ERROR_HANDLE
, NULL
);
4622 res
= AllocConsole();
4623 ok(res
, "AllocConsole failed: %lu\n", GetLastError());
4625 ok(GetStdHandle(STD_OUTPUT_HANDLE
) != NULL
, "GetStdHandle(STD_OUTPUT_HANDLE) = %p\n", GetStdHandle(STD_OUTPUT_HANDLE
));
4626 ok(GetStdHandle(STD_ERROR_HANDLE
) != NULL
, "GetStdHandle(STD_ERROR_HANDLE) = %p\n", GetStdHandle(STD_ERROR_HANDLE
));
4628 res
= GetConsoleMode(unbound_output
, &mode
);
4629 ok(res
, "GetConsoleMode failed: %lu\n", GetLastError());
4630 res
= GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE
), &mode
);
4631 ok(res
, "GetConsoleMode failed: %lu\n", GetLastError());
4632 res
= GetConsoleMode(GetStdHandle(STD_ERROR_HANDLE
), &mode
);
4633 ok(res
, "GetConsoleMode failed: %lu\n", GetLastError());
4635 res
= CloseHandle(unbound_output
);
4636 ok(res
, "CloseHandle failed: %lu\n", GetLastError());
4639 static void test_AllocConsole(void)
4641 SECURITY_ATTRIBUTES inheritable_attr
= { sizeof(inheritable_attr
), NULL
, TRUE
};
4642 STARTUPINFOA si
= { sizeof(si
) };
4643 PROCESS_INFORMATION info
;
4644 char **argv
, buf
[MAX_PATH
];
4645 HANDLE pipe_read
, pipe_write
;
4648 if (skip_nt
) return;
4650 winetest_get_mainargs(&argv
);
4651 sprintf(buf
, "\"%s\" console alloc_console", argv
[0]);
4652 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, FALSE
, CREATE_NEW_CONSOLE
, NULL
, NULL
, &si
, &info
);
4653 ok(res
, "CreateProcess failed: %lu\n", GetLastError());
4654 CloseHandle(info
.hThread
);
4655 wait_child_process(info
.hProcess
);
4656 CloseHandle(info
.hProcess
);
4658 res
= CreatePipe(&pipe_read
, &pipe_write
, &inheritable_attr
, 0);
4659 ok(res
, "CreatePipe failed: %lu\n", GetLastError());
4661 si
.dwFlags
= STARTF_USESTDHANDLES
;
4662 si
.hStdError
= pipe_write
;
4663 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, TRUE
, CREATE_NEW_CONSOLE
, NULL
, NULL
, &si
, &info
);
4664 ok(res
, "CreateProcess failed: %lu\n", GetLastError());
4665 CloseHandle(info
.hThread
);
4666 wait_child_process(info
.hProcess
);
4667 CloseHandle(info
.hProcess
);
4669 CloseHandle(pipe_read
);
4670 CloseHandle(pipe_write
);
4673 static void test_pseudo_console_child(HANDLE input
, HANDLE output
)
4675 CONSOLE_SCREEN_BUFFER_INFO sb_info
;
4676 CONSOLE_CURSOR_INFO cursor_info
;
4681 ret
= GetConsoleMode(input
, &mode
);
4682 ok(ret
, "GetConsoleMode failed: %lu\n", GetLastError());
4683 ok(mode
== (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_MOUSE_INPUT
|
4684 ENABLE_INSERT_MODE
| ENABLE_QUICK_EDIT_MODE
| ENABLE_EXTENDED_FLAGS
| ENABLE_AUTO_POSITION
),
4685 "mode = %lx\n", mode
);
4687 ret
= SetConsoleMode(input
, mode
& ~ENABLE_AUTO_POSITION
);
4688 ok(ret
, "SetConsoleMode failed: %lu\n", GetLastError());
4690 ret
= GetConsoleMode(input
, &mode
);
4691 ok(ret
, "GetConsoleMode failed: %lu\n", GetLastError());
4692 ok(mode
== (ENABLE_PROCESSED_INPUT
| ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
| ENABLE_MOUSE_INPUT
|
4693 ENABLE_INSERT_MODE
| ENABLE_QUICK_EDIT_MODE
| ENABLE_EXTENDED_FLAGS
), "mode = %lx\n", mode
);
4695 ret
= SetConsoleMode(input
, mode
| ENABLE_AUTO_POSITION
);
4696 ok(ret
, "SetConsoleMode failed: %lu\n", GetLastError());
4698 ret
= GetConsoleMode(output
, &mode
);
4699 ok(ret
, "GetConsoleMode failed: %lu\n", GetLastError());
4700 mode
&= ~ENABLE_VIRTUAL_TERMINAL_PROCESSING
;
4701 ok(mode
== (ENABLE_PROCESSED_OUTPUT
| ENABLE_WRAP_AT_EOL_OUTPUT
), "mode = %lx\n", mode
);
4703 ret
= SetConsoleMode(output
, mode
& ~ENABLE_WRAP_AT_EOL_OUTPUT
);
4704 ok(ret
, "SetConsoleMode failed: %lu\n", GetLastError());
4706 ret
= GetConsoleMode(output
, &mode
);
4707 ok(ret
, "GetConsoleMode failed: %lu\n", GetLastError());
4708 ok(mode
== ENABLE_PROCESSED_OUTPUT
, "mode = %lx\n", mode
);
4710 ret
= SetConsoleMode(output
, mode
| ENABLE_WRAP_AT_EOL_OUTPUT
);
4711 ok(ret
, "SetConsoleMode failed: %lu\n", GetLastError());
4713 ret
= GetConsoleScreenBufferInfo(output
, &sb_info
);
4714 ok(ret
, "GetConsoleScreenBufferInfo failed: %lu\n", GetLastError());
4715 ok(sb_info
.dwSize
.X
== 40, "dwSize.X = %u\n", sb_info
.dwSize
.X
);
4716 ok(sb_info
.dwSize
.Y
== 30, "dwSize.Y = %u\n", sb_info
.dwSize
.Y
);
4717 ok(sb_info
.dwCursorPosition
.X
== 0, "dwCursorPosition.X = %u\n", sb_info
.dwCursorPosition
.X
);
4718 ok(sb_info
.dwCursorPosition
.Y
== 0, "dwCursorPosition.Y = %u\n", sb_info
.dwCursorPosition
.Y
);
4719 ok(sb_info
.wAttributes
== 7, "wAttributes = %x\n", sb_info
.wAttributes
);
4720 ok(sb_info
.srWindow
.Left
== 0, "srWindow.Left = %u\n", sb_info
.srWindow
.Left
);
4721 ok(sb_info
.srWindow
.Top
== 0, "srWindow.Top = %u\n", sb_info
.srWindow
.Top
);
4722 ok(sb_info
.srWindow
.Right
== 39, "srWindow.Right = %u\n", sb_info
.srWindow
.Right
);
4723 ok(sb_info
.srWindow
.Bottom
== 29, "srWindow.Bottom = %u\n", sb_info
.srWindow
.Bottom
);
4724 ok(sb_info
.dwMaximumWindowSize
.X
== 40, "dwMaximumWindowSize.X = %u\n", sb_info
.dwMaximumWindowSize
.X
);
4725 ok(sb_info
.dwMaximumWindowSize
.Y
== 30, "dwMaximumWindowSize.Y = %u\n", sb_info
.dwMaximumWindowSize
.Y
);
4727 ret
= GetConsoleCursorInfo(output
, &cursor_info
);
4728 ok(ret
, "GetConsoleCursorInfo failed: %lu\n", GetLastError());
4729 ok(cursor_info
.dwSize
== 25, "dwSize = %lu\n", cursor_info
.dwSize
);
4730 ok(cursor_info
.bVisible
== TRUE
, "bVisible = %x\n", cursor_info
.bVisible
);
4732 hwnd
= GetConsoleWindow();
4733 ok(IsWindow(hwnd
), "no console window\n");
4735 test_GetConsoleTitleA();
4736 test_GetConsoleTitleW();
4737 test_WriteConsoleInputW(input
);
4740 static DWORD WINAPI
read_pipe_proc( void *handle
)
4744 while (ReadFile(handle
, buf
, sizeof(buf
), &size
, NULL
));
4745 ok(GetLastError() == ERROR_BROKEN_PIPE
, "ReadFile returned %lu\n", GetLastError());
4746 CloseHandle(handle
);
4750 static void test_pseudo_console(void)
4752 STARTUPINFOEXA startup
= {{ sizeof(startup
) }};
4753 HANDLE console_pipe
, console_pipe2
, thread
;
4754 char **argv
, cmdline
[MAX_PATH
];
4755 PROCESS_INFORMATION info
;
4756 HPCON pseudo_console
;
4762 if (!pCreatePseudoConsole
)
4764 win_skip("CreatePseudoConsole not available\n");
4768 console_pipe
= CreateNamedPipeW(L
"\\\\.\\pipe\\pseudoconsoleconn", PIPE_ACCESS_DUPLEX
,
4769 PIPE_WAIT
| PIPE_TYPE_BYTE
, 1, 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT
, NULL
);
4770 ok(console_pipe
!= INVALID_HANDLE_VALUE
, "CreateNamedPipeW failed: %lu\n", GetLastError());
4772 console_pipe2
= CreateFileW(L
"\\\\.\\pipe\\pseudoconsoleconn", GENERIC_READ
| GENERIC_WRITE
, 0, NULL
,
4773 OPEN_EXISTING
, FILE_FLAG_OVERLAPPED
, NULL
);
4774 ok(console_pipe2
!= INVALID_HANDLE_VALUE
, "CreateFile failed: %lu\n", GetLastError());
4776 thread
= CreateThread( NULL
, 0, read_pipe_proc
, console_pipe
, 0, NULL
);
4777 CloseHandle(thread
);
4781 hres
= pCreatePseudoConsole(size
, console_pipe2
, console_pipe2
, 0, &pseudo_console
);
4782 ok(hres
== E_INVALIDARG
, "CreatePseudoConsole failed: %08lx\n", hres
);
4786 hres
= pCreatePseudoConsole(size
, console_pipe2
, console_pipe2
, 0, &pseudo_console
);
4787 ok(hres
== E_INVALIDARG
, "CreatePseudoConsole failed: %08lx\n", hres
);
4791 hres
= pCreatePseudoConsole(size
, console_pipe2
, console_pipe2
, 0, &pseudo_console
);
4792 ok(hres
== S_OK
, "CreatePseudoConsole failed: %08lx\n", hres
);
4793 CloseHandle(console_pipe2
);
4795 InitializeProcThreadAttributeList(NULL
, 1, 0, &attr_size
);
4796 startup
.lpAttributeList
= HeapAlloc(GetProcessHeap(), 0, attr_size
);
4797 InitializeProcThreadAttributeList(startup
.lpAttributeList
, 1, 0, &attr_size
);
4798 UpdateProcThreadAttribute(startup
.lpAttributeList
, 0, PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE
, pseudo_console
,
4799 sizeof(pseudo_console
), NULL
, NULL
);
4801 winetest_get_mainargs(&argv
);
4802 sprintf(cmdline
, "\"%s\" %s --pseudo-console", argv
[0], argv
[1]);
4803 ret
= CreateProcessA(NULL
, cmdline
, NULL
, NULL
, FALSE
, EXTENDED_STARTUPINFO_PRESENT
, NULL
, NULL
, &startup
.StartupInfo
, &info
);
4804 ok(ret
, "CreateProcessW failed: %lu\n", GetLastError());
4806 CloseHandle(info
.hThread
);
4807 HeapFree(GetProcessHeap(), 0, startup
.lpAttributeList
);
4808 wait_child_process(info
.hProcess
);
4809 CloseHandle(info
.hProcess
);
4811 pClosePseudoConsole(pseudo_console
);
4814 /* copy an executable, but changing its subsystem */
4815 static void copy_change_subsystem(const char* in
, const char* out
, DWORD subsyst
)
4820 IMAGE_NT_HEADERS
*nthdr
;
4822 ret
= CopyFileA(in
, out
, FALSE
);
4823 ok(ret
, "Failed to copy executable %s in %s (%lu)\n", in
, out
, GetLastError());
4825 hFile
= CreateFileA(out
, GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
4826 OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
, NULL
);
4827 ok(hFile
!= INVALID_HANDLE_VALUE
, "Couldn't open file %s (%lu)\n", out
, GetLastError());
4828 hMap
= CreateFileMappingW(hFile
, NULL
, PAGE_READWRITE
, 0, 0, NULL
);
4829 ok(hMap
!= NULL
, "Couldn't create map (%lu)\n", GetLastError());
4830 mapping
= MapViewOfFile(hMap
, FILE_MAP_ALL_ACCESS
, 0, 0, 0);
4831 ok(mapping
!= NULL
, "Couldn't map (%lu)\n", GetLastError());
4832 nthdr
= RtlImageNtHeader(mapping
);
4833 ok(nthdr
!= NULL
, "Cannot get NT headers out of %s\n", out
);
4834 if (nthdr
) nthdr
->OptionalHeader
.Subsystem
= subsyst
;
4835 ret
= UnmapViewOfFile(mapping
);
4836 ok(ret
, "Couldn't unmap (%lu)\n", GetLastError());
4841 enum inheritance_model
{NULL_STD
, CONSOLE_STD
, STARTUPINFO_STD
};
4843 static DWORD
check_child_console_bits(const char* exec
, DWORD flags
, enum inheritance_model inherit
)
4845 SECURITY_ATTRIBUTES sa
= {0, NULL
, TRUE
};
4846 STARTUPINFOA si
= { sizeof(si
) };
4847 PROCESS_INFORMATION info
;
4853 BOOL inherit_handles
= FALSE
;
4855 sprintf(buf
, "\"%s\" console check_console", exec
);
4859 SetStdHandle(STD_INPUT_HANDLE
, NULL
);
4860 SetStdHandle(STD_OUTPUT_HANDLE
, NULL
);
4861 SetStdHandle(STD_ERROR_HANDLE
, NULL
);
4864 handle
= CreateFileA("CONIN$", GENERIC_READ
, 0, &sa
, OPEN_EXISTING
, 0, 0);
4865 ok(handle
!= INVALID_HANDLE_VALUE
, "Couldn't create input to console\n");
4866 SetStdHandle(STD_INPUT_HANDLE
, handle
);
4867 handle
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, &sa
, OPEN_EXISTING
, 0, 0);
4868 ok(handle
!= INVALID_HANDLE_VALUE
, "Couldn't create input to console\n");
4869 SetStdHandle(STD_OUTPUT_HANDLE
, handle
);
4870 SetStdHandle(STD_ERROR_HANDLE
, handle
);
4872 case STARTUPINFO_STD
:
4873 si
.dwFlags
|= STARTF_USESTDHANDLES
;
4874 si
.hStdInput
= CreateFileA("CONIN$", GENERIC_READ
, 0, &sa
, OPEN_EXISTING
, 0, 0);
4875 ok(si
.hStdInput
!= INVALID_HANDLE_VALUE
, "Couldn't create input to console\n");
4876 si
.hStdOutput
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, &sa
, OPEN_EXISTING
, 0, 0);
4877 ok(si
.hStdInput
!= INVALID_HANDLE_VALUE
, "Couldn't create output to console\n");
4878 si
.hStdError
= INVALID_HANDLE_VALUE
;
4879 inherit_handles
= TRUE
;
4882 res
= CreateProcessA(NULL
, buf
, NULL
, NULL
, inherit_handles
, flags
, NULL
, NULL
, &si
, &info
);
4883 ok(res
, "CreateProcess failed: %lu %s\n", GetLastError(), buf
);
4884 CloseHandle(info
.hThread
);
4885 ret
= WaitForSingleObject(info
.hProcess
, 30000);
4886 ok(ret
== WAIT_OBJECT_0
, "Could not wait for the child process: %ld le=%lu\n",
4887 ret
, GetLastError());
4888 res
= GetExitCodeProcess(info
.hProcess
, &exit_code
);
4889 ok(res
&& exit_code
<= 255, "Couldn't get exit_code\n");
4890 CloseHandle(info
.hProcess
);
4896 CloseHandle(GetStdHandle(STD_INPUT_HANDLE
));
4897 CloseHandle(GetStdHandle(STD_OUTPUT_HANDLE
));
4899 case STARTUPINFO_STD
:
4900 CloseHandle(si
.hStdInput
);
4901 CloseHandle(si
.hStdOutput
);
4907 #define CP_WITH_CONSOLE 0x01 /* attached to a console */
4908 #define CP_WITH_HANDLE 0x02 /* child has a console handle */
4909 #define CP_WITH_WINDOW 0x04 /* child has a console window */
4910 #define CP_ALONE 0x08 /* whether child is the single process attached to console */
4911 #define CP_GROUP_LEADER 0x10 /* whether the child is the process group leader */
4912 #define CP_INPUT_VALID 0x20 /* whether StdHandle(INPUT) is a valid console handle */
4913 #define CP_OUTPUT_VALID 0x40 /* whether StdHandle(OUTPUT) is a valid console handle */
4915 #define CP_OWN_CONSOLE (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_INPUT_VALID | CP_OUTPUT_VALID | CP_ALONE)
4916 #define CP_INH_CONSOLE (CP_WITH_CONSOLE | CP_WITH_HANDLE | CP_INPUT_VALID | CP_OUTPUT_VALID)
4918 static void test_CreateProcessCUI(void)
4921 static char guiexec
[MAX_PATH
];
4922 static char cuiexec
[MAX_PATH
];
4931 enum inheritance_model inherit
;
4936 no_console_tests
[] =
4938 /* 0*/ {FALSE
, 0, NULL_STD
, 0},
4939 {FALSE
, DETACHED_PROCESS
, NULL_STD
, 0},
4940 {FALSE
, CREATE_NEW_CONSOLE
, NULL_STD
, 0},
4941 {FALSE
, CREATE_NO_WINDOW
, NULL_STD
, 0},
4942 {FALSE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4943 /* 5*/ {FALSE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4945 {TRUE
, 0, NULL_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4946 {TRUE
, DETACHED_PROCESS
, NULL_STD
, 0},
4947 {TRUE
, CREATE_NEW_CONSOLE
, NULL_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4948 {TRUE
, CREATE_NO_WINDOW
, NULL_STD
, CP_OWN_CONSOLE
},
4949 /*10*/ {TRUE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4950 {TRUE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, NULL_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4952 with_console_tests
[] =
4954 /* 0*/ {FALSE
, 0, NULL_STD
, 0},
4955 {FALSE
, DETACHED_PROCESS
, NULL_STD
, 0},
4956 {FALSE
, CREATE_NEW_CONSOLE
, NULL_STD
, 0},
4957 {FALSE
, CREATE_NO_WINDOW
, NULL_STD
, 0},
4958 {FALSE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4959 /* 5*/ {FALSE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4961 {FALSE
, 0, CONSOLE_STD
, 0, TRUE
},
4962 {FALSE
, DETACHED_PROCESS
, CONSOLE_STD
, 0},
4963 {FALSE
, CREATE_NEW_CONSOLE
, CONSOLE_STD
, 0},
4964 {FALSE
, CREATE_NO_WINDOW
, CONSOLE_STD
, 0, TRUE
},
4965 /*10*/ {FALSE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, CONSOLE_STD
, 0},
4966 {FALSE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, CONSOLE_STD
, 0},
4968 {FALSE
, 0, STARTUPINFO_STD
, 0, TRUE
},
4969 {FALSE
, DETACHED_PROCESS
, STARTUPINFO_STD
, 0, TRUE
},
4970 {FALSE
, CREATE_NEW_CONSOLE
, STARTUPINFO_STD
, 0, TRUE
},
4971 /*15*/ {FALSE
, CREATE_NO_WINDOW
, STARTUPINFO_STD
, 0, TRUE
},
4972 {FALSE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, STARTUPINFO_STD
, 0, TRUE
},
4973 {FALSE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, STARTUPINFO_STD
, 0, TRUE
},
4975 {TRUE
, 0, NULL_STD
, CP_WITH_CONSOLE
| CP_WITH_HANDLE
| CP_WITH_WINDOW
},
4976 {TRUE
, DETACHED_PROCESS
, NULL_STD
, 0},
4977 /*20*/ {TRUE
, CREATE_NEW_CONSOLE
, NULL_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4978 {TRUE
, CREATE_NO_WINDOW
, NULL_STD
, CP_OWN_CONSOLE
},
4979 {TRUE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, NULL_STD
, 0},
4980 {TRUE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, NULL_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4982 {TRUE
, 0, CONSOLE_STD
, CP_INH_CONSOLE
| CP_WITH_WINDOW
},
4983 /*25*/ {TRUE
, DETACHED_PROCESS
, CONSOLE_STD
, 0},
4984 {TRUE
, CREATE_NEW_CONSOLE
, CONSOLE_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4985 {TRUE
, CREATE_NO_WINDOW
, CONSOLE_STD
, CP_OWN_CONSOLE
},
4986 {TRUE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, CONSOLE_STD
, 0},
4987 {TRUE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, CONSOLE_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
},
4989 /*30*/ {TRUE
, 0, STARTUPINFO_STD
, CP_INH_CONSOLE
| CP_WITH_WINDOW
},
4990 {TRUE
, DETACHED_PROCESS
, STARTUPINFO_STD
, CP_INPUT_VALID
| CP_OUTPUT_VALID
, .is_broken
= 0x100},
4991 {TRUE
, CREATE_NEW_CONSOLE
, STARTUPINFO_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
, .is_broken
= CP_WITH_CONSOLE
| CP_WITH_HANDLE
| CP_WITH_WINDOW
| CP_ALONE
},
4992 {TRUE
, CREATE_NO_WINDOW
, STARTUPINFO_STD
, CP_OWN_CONSOLE
, .is_broken
= CP_WITH_CONSOLE
| CP_WITH_HANDLE
| CP_ALONE
},
4993 {TRUE
, DETACHED_PROCESS
| CREATE_NO_WINDOW
, STARTUPINFO_STD
, CP_INPUT_VALID
| CP_OUTPUT_VALID
, .is_broken
= 0x100},
4994 /*35*/ {TRUE
, CREATE_NEW_CONSOLE
| CREATE_NO_WINDOW
, STARTUPINFO_STD
, CP_OWN_CONSOLE
| CP_WITH_WINDOW
, .is_broken
= CP_WITH_CONSOLE
| CP_WITH_HANDLE
| CP_WITH_WINDOW
| CP_ALONE
},
4997 hstd
[0] = GetStdHandle(STD_INPUT_HANDLE
);
4998 hstd
[1] = GetStdHandle(STD_OUTPUT_HANDLE
);
4999 hstd
[2] = GetStdHandle(STD_ERROR_HANDLE
);
5001 winetest_get_mainargs(&argv
);
5002 GetTempPathA(ARRAY_SIZE(guiexec
), guiexec
);
5003 strcat(guiexec
, "console_gui.exe");
5004 copy_change_subsystem(argv
[0], guiexec
, IMAGE_SUBSYSTEM_WINDOWS_GUI
);
5005 GetTempPathA(ARRAY_SIZE(cuiexec
), cuiexec
);
5006 strcat(cuiexec
, "console_cui.exe");
5007 copy_change_subsystem(argv
[0], cuiexec
, IMAGE_SUBSYSTEM_WINDOWS_CUI
);
5011 for (i
= 0; i
< ARRAY_SIZE(no_console_tests
); i
++)
5013 res
= check_child_console_bits(no_console_tests
[i
].use_cui
? cuiexec
: guiexec
,
5014 no_console_tests
[i
].cp_flags
,
5015 no_console_tests
[i
].inherit
);
5016 todo_wine_if(no_console_tests
[i
].is_todo
)
5017 ok(res
== no_console_tests
[i
].expected
, "[%d] Unexpected result %x (%lx)\n",
5018 i
, res
, no_console_tests
[i
].expected
);
5023 for (i
= 0; i
< ARRAY_SIZE(with_console_tests
); i
++)
5025 res
= check_child_console_bits(with_console_tests
[i
].use_cui
? cuiexec
: guiexec
,
5026 with_console_tests
[i
].cp_flags
,
5027 with_console_tests
[i
].inherit
);
5028 todo_wine_if(with_console_tests
[i
].is_todo
)
5029 ok(res
== with_console_tests
[i
].expected
||
5030 broken(with_console_tests
[i
].is_broken
&& res
== (with_console_tests
[i
].is_broken
& 0xff)),
5031 "[%d] Unexpected result %x (%lx)\n",
5032 i
, res
, with_console_tests
[i
].expected
);
5035 DeleteFileA(guiexec
);
5036 DeleteFileA(cuiexec
);
5038 SetStdHandle(STD_INPUT_HANDLE
, hstd
[0]);
5039 SetStdHandle(STD_OUTPUT_HANDLE
, hstd
[1]);
5040 SetStdHandle(STD_ERROR_HANDLE
, hstd
[2]);
5045 HANDLE hConIn
, hConOut
, revert_output
= NULL
, unbound_output
;
5046 BOOL ret
, test_current
;
5047 CONSOLE_SCREEN_BUFFER_INFO sbi
;
5048 BOOL using_pseudo_console
;
5053 init_function_pointers();
5055 argc
= winetest_get_mainargs(&argv
);
5057 if (argc
> 3 && !strcmp(argv
[2], "attach_console"))
5060 sscanf(argv
[3], "%lx", &parent_pid
);
5061 test_AttachConsole_child(parent_pid
);
5065 if (argc
== 3 && !strcmp(argv
[2], "alloc_console"))
5067 test_AllocConsole_child();
5071 if (argc
== 3 && !strcmp(argv
[2], "check_console"))
5073 DWORD exit_code
= 0, pcslist
;
5074 if (GetConsoleCP() != 0) exit_code
|= CP_WITH_CONSOLE
;
5075 if (RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
) exit_code
|= CP_WITH_HANDLE
;
5076 if (IsWindow(GetConsoleWindow())) exit_code
|= CP_WITH_WINDOW
;
5077 if (pGetConsoleProcessList
&& GetConsoleProcessList(&pcslist
, 1) == 1)
5078 exit_code
|= CP_ALONE
;
5079 if (RtlGetCurrentPeb()->ProcessParameters
->ProcessGroupId
== GetCurrentProcessId())
5080 exit_code
|= CP_GROUP_LEADER
;
5081 if (GetFileType(GetStdHandle(STD_INPUT_HANDLE
)) == FILE_TYPE_CHAR
)
5082 exit_code
|= CP_INPUT_VALID
;
5083 if (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE
)) == FILE_TYPE_CHAR
)
5084 exit_code
|= CP_OUTPUT_VALID
;
5085 ExitProcess(exit_code
);
5088 if (argc
>= 3 && !strcmp(argv
[2], "title_test"))
5092 test_GetConsoleOriginalTitleA();
5093 test_GetConsoleOriginalTitleW();
5096 test_GetConsoleOriginalTitleW_empty();
5100 test_current
= argc
>= 3 && !strcmp(argv
[2], "--current");
5101 using_pseudo_console
= argc
>= 3 && !strcmp(argv
[2], "--pseudo-console");
5103 if (!test_current
&& !using_pseudo_console
)
5105 static const char font_name
[] = "Lucida Console";
5107 char old_font
[LF_FACESIZE
];
5108 BOOL
delete = FALSE
;
5111 /* ReadConsoleOutputW doesn't retrieve characters from the output buffer
5112 * correctly for characters that don't have a glyph in the console font. So,
5113 * we first set the console font to Lucida Console (which has a wider
5114 * selection of glyphs available than the default raster fonts). We want
5115 * to be able to restore the original font afterwards, so don't change
5116 * if we can't read the original font.
5118 err
= RegOpenKeyExA(HKEY_CURRENT_USER
, "Console", 0,
5119 KEY_QUERY_VALUE
| KEY_SET_VALUE
, &console_key
);
5120 if (err
== ERROR_SUCCESS
)
5122 size
= sizeof(old_font
);
5123 err
= RegQueryValueExA(console_key
, "FaceName", NULL
, NULL
,
5124 (LPBYTE
) old_font
, &size
);
5125 if (err
== ERROR_SUCCESS
|| err
== ERROR_FILE_NOT_FOUND
)
5127 delete = (err
== ERROR_FILE_NOT_FOUND
);
5128 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
5129 (const BYTE
*) font_name
, sizeof(font_name
));
5130 if (err
!= ERROR_SUCCESS
)
5131 trace("Unable to change default console font, error %ld\n", err
);
5135 trace("Unable to query default console font, error %ld\n", err
);
5136 RegCloseKey(console_key
);
5142 trace("Unable to open HKCU\\Console, error %ld\n", err
);
5146 /* Now detach and open a fresh console to play with */
5148 ok(AllocConsole(), "Couldn't alloc console\n");
5150 /* Restore default console font if needed */
5151 if (console_key
!= NULL
)
5154 err
= RegDeleteValueA(console_key
, "FaceName");
5156 err
= RegSetValueExA(console_key
, "FaceName", 0, REG_SZ
,
5157 (const BYTE
*) old_font
, strlen(old_font
) + 1);
5158 ok(err
== ERROR_SUCCESS
, "Unable to restore default console font, error %ld\n", err
);
5162 unbound_output
= create_unbound_handle(TRUE
, FALSE
);
5163 if (!unbound_output
)
5165 win_skip("Skipping NT path tests, not supported on this Windows version\n");
5172 revert_output
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
5173 sb
= CreateConsoleScreenBuffer(GENERIC_READ
| GENERIC_WRITE
, FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
,
5174 CONSOLE_TEXTMODE_BUFFER
, NULL
);
5175 ok(sb
!= INVALID_HANDLE_VALUE
, "Could not allocate screen buffer: %lu\n", GetLastError());
5176 SetConsoleActiveScreenBuffer(sb
);
5179 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
5180 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
5182 /* now verify everything's ok */
5183 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
5184 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
5186 if (using_pseudo_console
)
5188 test_pseudo_console_child(hConIn
, hConOut
);
5192 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
5193 ok(ret
, "Getting sb info\n");
5196 /* Reduce the size of the buffer to the visible area plus 3 lines to speed
5199 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
);
5200 sbi
.dwSize
.Y
= size
= (sbi
.srWindow
.Bottom
+ 1) + 3;
5201 ret
= SetConsoleScreenBufferSize(hConOut
, sbi
.dwSize
);
5202 ok(ret
, "Setting sb info\n");
5203 ret
= GetConsoleScreenBufferInfo(hConOut
, &sbi
);
5204 ok(ret
, "Getting sb info\n");
5205 ok(sbi
.dwSize
.Y
== size
, "Unexpected buffer size: %d instead of %ld\n", sbi
.dwSize
.Y
, size
);
5208 test_ReadConsole(hConIn
);
5209 /* Non interactive tests */
5210 testCursor(hConOut
, sbi
.dwSize
);
5211 /* test parameters (FIXME: test functionality) */
5212 testCursorInfo(hConOut
);
5213 /* will test wrapped (on/off) & processed (on/off) strings output */
5214 testWrite(hConOut
, sbi
.dwSize
);
5215 /* will test line scrolling at the bottom of the screen */
5216 /* testBottomScroll(); */
5217 /* will test all the scrolling operations */
5218 testScroll(hConOut
, sbi
.dwSize
);
5219 /* will test sb creation / modification / codepage handling */
5220 if (!test_current
) testScreenBuffer(hConOut
);
5221 test_new_screen_buffer_properties(hConOut
);
5222 test_new_screen_buffer_color_attributes(hConOut
);
5223 /* Test waiting for a console handle */
5224 testWaitForConsoleInput(hConIn
);
5225 test_wait(hConIn
, hConOut
);
5229 /* clear duplicated console font table */
5230 CloseHandle(hConIn
);
5231 CloseHandle(hConOut
);
5233 ok(AllocConsole(), "Couldn't alloc console\n");
5234 hConIn
= CreateFileA("CONIN$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
5235 hConOut
= CreateFileA("CONOUT$", GENERIC_READ
|GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, 0);
5236 ok(hConIn
!= INVALID_HANDLE_VALUE
, "Opening ConIn\n");
5237 ok(hConOut
!= INVALID_HANDLE_VALUE
, "Opening ConOut\n");
5241 /* still to be done: access rights & access on objects */
5243 if (!pGetConsoleInputExeNameA
|| !pSetConsoleInputExeNameA
)
5244 win_skip("GetConsoleInputExeNameA and/or SetConsoleInputExeNameA is not available\n");
5246 test_GetSetConsoleInputExeName();
5248 if (!test_current
) test_GetConsoleProcessList();
5249 test_OpenConsoleW();
5252 test_VerifyConsoleIoHandle(hConOut
);
5253 test_GetSetStdHandle();
5254 test_DuplicateConsoleHandle();
5255 test_GetNumberOfConsoleInputEvents(hConIn
);
5256 test_WriteConsoleInputA(hConIn
);
5257 test_WriteConsoleInputW(hConIn
);
5258 test_FlushConsoleInputBuffer(hConIn
, hConOut
);
5259 test_WriteConsoleOutputCharacterA(hConOut
);
5260 test_WriteConsoleOutputCharacterW(hConOut
);
5261 test_WriteConsoleOutputAttribute(hConOut
);
5262 test_WriteConsoleOutput(hConOut
);
5263 test_FillConsoleOutputCharacterA(hConOut
);
5264 test_FillConsoleOutputCharacterW(hConOut
);
5265 test_FillConsoleOutputAttribute(hConOut
);
5266 test_ReadConsoleOutputCharacterA(hConOut
);
5267 test_ReadConsoleOutputCharacterW(hConOut
);
5268 test_ReadConsoleOutputAttribute(hConOut
);
5269 test_ReadConsoleOutput(hConOut
);
5272 test_GetCurrentConsoleFont(hConOut
);
5273 test_GetCurrentConsoleFontEx(hConOut
);
5274 test_SetCurrentConsoleFontEx(hConOut
);
5275 test_GetConsoleFontSize(hConOut
);
5276 test_GetLargestConsoleWindowSize(hConOut
);
5277 test_GetConsoleFontInfo(hConOut
);
5278 test_SetConsoleFont(hConOut
);
5280 test_GetConsoleScreenBufferInfoEx(hConOut
);
5281 test_SetConsoleScreenBufferInfoEx(hConOut
);
5282 test_file_info(hConIn
, hConOut
);
5283 test_GetConsoleOriginalTitle();
5284 test_GetConsoleTitleA();
5285 test_GetConsoleTitleW();
5288 test_pseudo_console();
5289 test_AttachConsole(hConOut
);
5290 test_AllocConsole();
5292 test_CreateProcessCUI();
5294 else if (revert_output
) SetConsoleActiveScreenBuffer(revert_output
);
5296 CloseHandle(unbound_output
);