2 * Win32 console functions
4 * Copyright 1995 Martin von Loewis and Cameron Heide
5 * Copyright 1997 Karl Garrison
6 * Copyright 1998 John Richardson
7 * Copyright 1998 Marcus Meissner
8 * Copyright 2001,2002,2004,2005,2010 Eric Pouech
9 * Copyright 2001 Alexandre Julliard
10 * Copyright 2020 Jacek Caban for CodeWeavers
12 * This library is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public
14 * License as published by the Free Software Foundation; either
15 * version 2.1 of the License, or (at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Lesser General Public License for more details.
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this library; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #define WIN32_NO_STATUS
40 #include "wine/condrv.h"
41 #include "wine/exception.h"
42 #include "wine/debug.h"
43 #include "kernelbase.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(console
);
48 static CRITICAL_SECTION console_section
;
49 static CRITICAL_SECTION_DEBUG critsect_debug
=
51 0, 0, &console_section
,
52 { &critsect_debug
.ProcessLocksList
, &critsect_debug
.ProcessLocksList
},
53 0, 0, { (DWORD_PTR
)(__FILE__
": console_section") }
55 static CRITICAL_SECTION console_section
= { &critsect_debug
, -1, 0, 0, 0, 0 };
57 static HANDLE console_connection
;
58 static unsigned int console_flags
;
60 #define CONSOLE_INPUT_HANDLE 0x01
61 #define CONSOLE_OUTPUT_HANDLE 0x02
62 #define CONSOLE_ERROR_HANDLE 0x04
64 static WCHAR input_exe
[MAX_PATH
+ 1];
68 PHANDLER_ROUTINE func
;
69 struct ctrl_handler
*next
;
72 static BOOL WINAPI
default_ctrl_handler( DWORD type
)
74 FIXME( "Terminating process %lx on event %lx\n", GetCurrentProcessId(), type
);
75 RtlExitUserProcess( 0 );
79 static struct ctrl_handler default_handler
= { default_ctrl_handler
, NULL
};
80 static struct ctrl_handler
*ctrl_handlers
= &default_handler
;
82 static BOOL
console_ioctl( HANDLE handle
, DWORD code
, void *in_buff
, DWORD in_count
,
83 void *out_buff
, DWORD out_count
, DWORD
*read
)
88 if (handle
== CONSOLE_HANDLE_SHELL_NO_WINDOW
)
90 WARN("Incorrect access to Shell-no-window console (ioctl=%lx)\n", code
);
91 SetLastError( ERROR_INVALID_ACCESS
);
94 status
= NtDeviceIoControlFile( handle
, NULL
, NULL
, NULL
, &io
, code
, in_buff
, in_count
,
95 out_buff
, out_count
);
99 if (read
) *read
= io
.Information
;
101 case STATUS_INVALID_PARAMETER
:
104 status
= STATUS_INVALID_HANDLE
;
108 return set_ntstatus( status
);
111 /* map input records to ASCII */
112 static void input_records_WtoA( INPUT_RECORD
*buffer
, int count
)
114 UINT cp
= GetConsoleCP();
118 for (i
= 0; i
< count
; i
++)
120 if (buffer
[i
].EventType
!= KEY_EVENT
) continue;
121 WideCharToMultiByte( cp
, 0, &buffer
[i
].Event
.KeyEvent
.uChar
.UnicodeChar
, 1, &ch
, 1, NULL
, NULL
);
122 buffer
[i
].Event
.KeyEvent
.uChar
.AsciiChar
= ch
;
126 /* map input records to Unicode */
127 static void input_records_AtoW( INPUT_RECORD
*buffer
, int count
)
129 UINT cp
= GetConsoleCP();
133 for (i
= 0; i
< count
; i
++)
135 if (buffer
[i
].EventType
!= KEY_EVENT
) continue;
136 MultiByteToWideChar( cp
, 0, &buffer
[i
].Event
.KeyEvent
.uChar
.AsciiChar
, 1, &ch
, 1 );
137 buffer
[i
].Event
.KeyEvent
.uChar
.UnicodeChar
= ch
;
141 /* map char infos to ASCII */
142 static void char_info_WtoA( UINT cp
, CHAR_INFO
*buffer
, int count
)
148 WideCharToMultiByte( cp
, 0, &buffer
->Char
.UnicodeChar
, 1, &ch
, 1, NULL
, NULL
);
149 buffer
->Char
.AsciiChar
= ch
;
154 /* map char infos to Unicode */
155 static void char_info_AtoW( CHAR_INFO
*buffer
, int count
)
157 UINT cp
= GetConsoleOutputCP();
162 MultiByteToWideChar( cp
, 0, &buffer
->Char
.AsciiChar
, 1, &ch
, 1 );
163 buffer
->Char
.UnicodeChar
= ch
;
168 /* helper function for GetLargestConsoleWindowSize */
169 static COORD
get_largest_console_window_size( HANDLE handle
)
171 struct condrv_output_info info
;
174 if (!console_ioctl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0, &info
, sizeof(info
), NULL
))
177 c
.X
= info
.max_width
;
178 c
.Y
= info
.max_height
;
179 TRACE( "(%p), returning %dx%d\n", handle
, c
.X
, c
.Y
);
183 /* helper function for GetConsoleFontSize */
184 static COORD
get_console_font_size( HANDLE handle
, DWORD index
)
186 struct condrv_output_info info
;
189 if (index
>= 1 /* number of console fonts */)
191 SetLastError(ERROR_INVALID_PARAMETER
);
195 if (DeviceIoControl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0, &info
, sizeof(info
), NULL
, NULL
))
197 c
.X
= info
.font_width
;
198 c
.Y
= info
.font_height
;
200 else SetLastError( ERROR_INVALID_HANDLE
);
204 /* helper function for GetConsoleTitle and GetConsoleOriginalTitle */
205 static DWORD
get_console_title( WCHAR
*title
, DWORD size
, BOOL current_title
)
207 struct condrv_title_params
*params
;
208 size_t max_size
= sizeof(*params
) + (size
- 1) * sizeof(WCHAR
);
210 if (!title
|| !size
) return 0;
212 if (!(params
= HeapAlloc( GetProcessHeap(), 0, max_size
)))
215 if (console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
, IOCTL_CONDRV_GET_TITLE
,
216 ¤t_title
, sizeof(current_title
), params
, max_size
, &size
) &&
217 size
>= sizeof(*params
))
219 size
-= sizeof(*params
);
220 memcpy( title
, params
->buffer
, size
);
221 title
[ size
/ sizeof(WCHAR
) ] = 0;
222 size
= params
->title_len
;
226 HeapFree( GetProcessHeap(), 0, params
);
230 static HANDLE
create_console_server( void )
232 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
233 UNICODE_STRING string
= RTL_CONSTANT_STRING( L
"\\Device\\ConDrv\\Server" );
234 IO_STATUS_BLOCK iosb
;
238 attr
.ObjectName
= &string
;
239 attr
.Attributes
= OBJ_INHERIT
;
240 status
= NtCreateFile( &handle
, FILE_WRITE_PROPERTIES
| FILE_READ_PROPERTIES
| SYNCHRONIZE
,
241 &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
242 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
243 return set_ntstatus( status
) ? handle
: NULL
;
246 static HANDLE
create_console_reference( HANDLE root
)
248 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
249 UNICODE_STRING string
= RTL_CONSTANT_STRING( L
"Reference" );
250 IO_STATUS_BLOCK iosb
;
254 attr
.RootDirectory
= root
;
255 attr
.ObjectName
= &string
;
256 status
= NtCreateFile( &handle
, FILE_READ_DATA
| FILE_WRITE_DATA
| FILE_WRITE_PROPERTIES
|
257 FILE_READ_PROPERTIES
| SYNCHRONIZE
, &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
,
258 0, FILE_OPEN
, FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
259 return set_ntstatus( status
) ? handle
: NULL
;
262 static BOOL
create_console_connection( HANDLE root
)
264 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
265 UNICODE_STRING string
;
266 IO_STATUS_BLOCK iosb
;
269 RtlInitUnicodeString( &string
, root
? L
"Connection" : L
"\\Device\\ConDrv\\Connection" );
270 attr
.RootDirectory
= root
;
271 attr
.ObjectName
= &string
;
272 status
= NtCreateFile( &console_connection
, FILE_WRITE_PROPERTIES
| FILE_READ_PROPERTIES
| SYNCHRONIZE
, &attr
,
273 &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
, FILE_NON_DIRECTORY_FILE
, NULL
, 0 );
274 return set_ntstatus( status
);
277 static BOOL
init_console_std_handles( BOOL override_all
)
279 HANDLE std_out
= NULL
, std_err
= NULL
, handle
;
280 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
281 IO_STATUS_BLOCK iosb
;
285 attr
.ObjectName
= &name
;
286 attr
.Attributes
= OBJ_INHERIT
;
288 if (override_all
|| !GetStdHandle( STD_INPUT_HANDLE
))
290 RtlInitUnicodeString( &name
, L
"\\Device\\ConDrv\\Input" );
291 status
= NtCreateFile( &handle
, FILE_READ_DATA
| FILE_WRITE_DATA
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
|
292 FILE_WRITE_ATTRIBUTES
, &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
,
293 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_CREATE
,
294 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
295 if (!set_ntstatus( status
)) return FALSE
;
296 console_flags
|= CONSOLE_INPUT_HANDLE
;
297 SetStdHandle( STD_INPUT_HANDLE
, handle
);
302 std_out
= GetStdHandle( STD_OUTPUT_HANDLE
);
303 std_err
= GetStdHandle( STD_ERROR_HANDLE
);
304 if (std_out
&& std_err
) return TRUE
;
307 RtlInitUnicodeString( &name
, L
"\\Device\\ConDrv\\Output" );
308 status
= NtCreateFile( &handle
, FILE_READ_DATA
| FILE_WRITE_DATA
| SYNCHRONIZE
| FILE_READ_ATTRIBUTES
|
309 FILE_WRITE_ATTRIBUTES
, &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
,
310 FILE_SHARE_READ
| FILE_SHARE_WRITE
| FILE_SHARE_DELETE
, FILE_CREATE
,
311 FILE_NON_DIRECTORY_FILE
| FILE_SYNCHRONOUS_IO_NONALERT
, NULL
, 0 );
312 if (!set_ntstatus( status
)) return FALSE
;
315 console_flags
|= CONSOLE_OUTPUT_HANDLE
;
316 SetStdHandle( STD_OUTPUT_HANDLE
, handle
);
321 if (!std_out
&& !DuplicateHandle( GetCurrentProcess(), handle
, GetCurrentProcess(),
322 &handle
, 0, TRUE
, DUPLICATE_SAME_ACCESS
))
324 console_flags
|= CONSOLE_ERROR_HANDLE
;
325 SetStdHandle( STD_ERROR_HANDLE
, handle
);
332 /******************************************************************
333 * AddConsoleAliasA (kernelbase.@)
335 BOOL WINAPI
AddConsoleAliasA( LPSTR source
, LPSTR target
, LPSTR exename
)
337 FIXME( ": (%s, %s, %s) stub!\n", debugstr_a(source
), debugstr_a(target
), debugstr_a(exename
) );
338 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
343 /******************************************************************
344 * AddConsoleAliasW (kernelbase.@)
346 BOOL WINAPI
AddConsoleAliasW( LPWSTR source
, LPWSTR target
, LPWSTR exename
)
348 FIXME( ": (%s, %s, %s) stub!\n", debugstr_w(source
), debugstr_w(target
), debugstr_w(exename
) );
349 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
354 /******************************************************************
355 * AttachConsole (kernelbase.@)
357 BOOL WINAPI DECLSPEC_HOTPATCH
AttachConsole( DWORD pid
)
361 TRACE( "(%lx)\n", pid
);
363 RtlEnterCriticalSection( &console_section
);
365 if (RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
)
367 RtlLeaveCriticalSection( &console_section
);
368 WARN( "console already attached\n" );
369 SetLastError( ERROR_ACCESS_DENIED
);
373 ret
= create_console_connection( NULL
) &&
374 console_ioctl( console_connection
, IOCTL_CONDRV_BIND_PID
, &pid
, sizeof(pid
), NULL
, 0, NULL
);
377 RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
= create_console_reference( console_connection
);
378 if (RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
)
381 GetStartupInfoW( &si
);
382 init_console_std_handles( !(si
.dwFlags
& STARTF_USESTDHANDLES
) );
387 if (!ret
) FreeConsole();
388 RtlLeaveCriticalSection( &console_section
);
393 static BOOL
alloc_console( BOOL headless
)
395 SECURITY_ATTRIBUTES inheritable_attr
= { sizeof(inheritable_attr
), NULL
, TRUE
};
396 STARTUPINFOEXW console_si
;
398 HANDLE server
, console
= NULL
;
399 WCHAR buffer
[1024], cmd
[256], conhost_path
[MAX_PATH
];
400 PROCESS_INFORMATION pi
;
407 RtlEnterCriticalSection( &console_section
);
409 if (RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
)
411 /* we already have a console opened on this process, don't create a new one */
412 RtlLeaveCriticalSection( &console_section
);
413 SetLastError( ERROR_ACCESS_DENIED
);
417 memset( &console_si
, 0, sizeof(console_si
) );
418 console_si
.StartupInfo
.cb
= sizeof(console_si
);
419 InitializeProcThreadAttributeList( NULL
, 1, 0, &size
);
420 if (!(console_si
.lpAttributeList
= HeapAlloc( GetProcessHeap(), 0, size
))) return FALSE
;
421 InitializeProcThreadAttributeList( console_si
.lpAttributeList
, 1, 0, &size
);
423 if (!(server
= create_console_server()) || !(console
= create_console_reference( server
))) goto error
;
425 GetStartupInfoW(&app_si
);
427 /* setup a view arguments for conhost (it'll use them as default values) */
428 if (app_si
.dwFlags
& STARTF_USECOUNTCHARS
)
430 console_si
.StartupInfo
.dwFlags
|= STARTF_USECOUNTCHARS
;
431 console_si
.StartupInfo
.dwXCountChars
= app_si
.dwXCountChars
;
432 console_si
.StartupInfo
.dwYCountChars
= app_si
.dwYCountChars
;
434 if (app_si
.dwFlags
& STARTF_USEFILLATTRIBUTE
)
436 console_si
.StartupInfo
.dwFlags
|= STARTF_USEFILLATTRIBUTE
;
437 console_si
.StartupInfo
.dwFillAttribute
= app_si
.dwFillAttribute
;
439 if (app_si
.dwFlags
& STARTF_USESHOWWINDOW
)
441 console_si
.StartupInfo
.dwFlags
|= STARTF_USESHOWWINDOW
;
442 console_si
.StartupInfo
.wShowWindow
= app_si
.wShowWindow
;
445 console_si
.StartupInfo
.lpTitle
= app_si
.lpTitle
;
446 else if (GetModuleFileNameW(0, buffer
, ARRAY_SIZE(buffer
)))
448 buffer
[ARRAY_SIZE(buffer
) - 1] = 0;
449 console_si
.StartupInfo
.lpTitle
= buffer
;
453 UpdateProcThreadAttribute( console_si
.lpAttributeList
, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST
,
454 &server
, sizeof(server
), NULL
, NULL
);
455 swprintf( conhost_path
, ARRAY_SIZE(conhost_path
), L
"%s\\conhost.exe", system_dir
);
456 swprintf( cmd
, ARRAY_SIZE(cmd
), L
"\"%s\" --server 0x%x", conhost_path
, condrv_handle( server
));
457 if (headless
) wcscat( cmd
, L
" --headless" );
458 Wow64DisableWow64FsRedirection( &redir
);
459 ret
= CreateProcessW( conhost_path
, cmd
, NULL
, NULL
, TRUE
, DETACHED_PROCESS
| EXTENDED_STARTUPINFO_PRESENT
,
460 NULL
, NULL
, &console_si
.StartupInfo
, &pi
);
461 Wow64RevertWow64FsRedirection( redir
);
463 if (!ret
|| !create_console_connection( console
)) goto error
;
464 if (!init_console_std_handles( !(app_si
.dwFlags
& STARTF_USESTDHANDLES
) )) goto error
;
466 RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
= console
;
467 TRACE( "Started conhost pid=%08lx tid=%08lx\n", pi
.dwProcessId
, pi
.dwThreadId
);
469 HeapFree( GetProcessHeap(), 0, console_si
.lpAttributeList
);
470 CloseHandle( server
);
471 RtlLeaveCriticalSection( &console_section
);
472 SetLastError( ERROR_SUCCESS
);
476 ERR("Can't allocate console\n");
477 HeapFree( GetProcessHeap(), 0, console_si
.lpAttributeList
);
481 RtlLeaveCriticalSection( &console_section
);
486 /******************************************************************
487 * AllocConsole (kernelbase.@)
489 BOOL WINAPI
AllocConsole(void)
491 return alloc_console( FALSE
);
495 /******************************************************************************
496 * CreateConsoleScreenBuffer (kernelbase.@)
498 HANDLE WINAPI DECLSPEC_HOTPATCH
CreateConsoleScreenBuffer( DWORD access
, DWORD share
,
499 SECURITY_ATTRIBUTES
*sa
, DWORD flags
,
502 OBJECT_ATTRIBUTES attr
= {sizeof(attr
)};
503 IO_STATUS_BLOCK iosb
;
504 UNICODE_STRING name
= RTL_CONSTANT_STRING( L
"\\Device\\ConDrv\\ScreenBuffer" );
508 TRACE( "(%lx,%lx,%p,%lx,%p)\n", access
, share
, sa
, flags
, data
);
510 if (flags
!= CONSOLE_TEXTMODE_BUFFER
|| data
)
512 SetLastError( ERROR_INVALID_PARAMETER
);
513 return INVALID_HANDLE_VALUE
;
516 attr
.ObjectName
= &name
;
517 attr
.SecurityDescriptor
= sa
? sa
->lpSecurityDescriptor
: NULL
;
518 if (sa
&& sa
->bInheritHandle
) attr
.Attributes
|= OBJ_INHERIT
;
519 status
= NtCreateFile( &handle
, access
, &attr
, &iosb
, NULL
, FILE_ATTRIBUTE_NORMAL
, 0, FILE_OPEN
,
520 FILE_NON_DIRECTORY_FILE
, NULL
, 0 );
521 return set_ntstatus( status
) ? handle
: INVALID_HANDLE_VALUE
;
525 /******************************************************************************
526 * CtrlRoutine (kernelbase.@)
528 DWORD WINAPI
CtrlRoutine( void *arg
)
530 DWORD_PTR event
= (DWORD_PTR
)arg
;
531 struct ctrl_handler
*handler
;
533 if (event
== CTRL_C_EVENT
)
535 BOOL caught_by_dbg
= TRUE
;
536 /* First, try to pass the ctrl-C event to the debugger (if any)
537 * If it continues, there's nothing more to do
538 * Otherwise, we need to send the ctrl-C event to the handlers
542 RaiseException( DBG_CONTROL_C
, 0, 0, NULL
);
546 caught_by_dbg
= FALSE
;
549 if (caught_by_dbg
) return 0;
552 if (NtCurrentTeb()->Peb
->ProcessParameters
->ConsoleFlags
& 1) return 0;
554 RtlEnterCriticalSection( &console_section
);
555 for (handler
= ctrl_handlers
; handler
; handler
= handler
->next
)
557 if (handler
->func( event
)) break;
559 RtlLeaveCriticalSection( &console_section
);
564 /******************************************************************
565 * ExpungeConsoleCommandHistoryA (kernelbase.@)
567 void WINAPI
ExpungeConsoleCommandHistoryA( LPCSTR exename
)
569 FIXME( ": (%s) stub!\n", debugstr_a(exename
) );
570 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
574 /******************************************************************
575 * ExpungeConsoleCommandHistoryW (kernelbase.@)
577 void WINAPI
ExpungeConsoleCommandHistoryW( LPCWSTR exename
)
579 FIXME( ": (%s) stub!\n", debugstr_w(exename
) );
580 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
584 /******************************************************************************
585 * FillConsoleOutputAttribute (kernelbase.@)
587 BOOL WINAPI DECLSPEC_HOTPATCH
FillConsoleOutputAttribute( HANDLE handle
, WORD attr
, DWORD length
,
588 COORD coord
, DWORD
*written
)
590 struct condrv_fill_output_params params
;
592 TRACE( "(%p,%d,%ld,(%dx%d),%p)\n", handle
, attr
, length
, coord
.X
, coord
.Y
, written
);
596 SetLastError( ERROR_INVALID_ACCESS
);
602 params
.mode
= CHAR_INFO_MODE_ATTR
;
605 params
.count
= length
;
609 return console_ioctl( handle
, IOCTL_CONDRV_FILL_OUTPUT
, ¶ms
, sizeof(params
),
610 written
, sizeof(*written
), NULL
);
614 /******************************************************************************
615 * FillConsoleOutputCharacterA (kernelbase.@)
617 BOOL WINAPI DECLSPEC_HOTPATCH
FillConsoleOutputCharacterA( HANDLE handle
, CHAR ch
, DWORD length
,
618 COORD coord
, DWORD
*written
)
622 MultiByteToWideChar( GetConsoleOutputCP(), 0, &ch
, 1, &wch
, 1 );
623 return FillConsoleOutputCharacterW( handle
, wch
, length
, coord
, written
);
627 /******************************************************************************
628 * FillConsoleOutputCharacterW (kernelbase.@)
630 BOOL WINAPI DECLSPEC_HOTPATCH
FillConsoleOutputCharacterW( HANDLE handle
, WCHAR ch
, DWORD length
,
631 COORD coord
, DWORD
*written
)
633 struct condrv_fill_output_params params
;
635 TRACE( "(%p,%s,%ld,(%dx%d),%p)\n", handle
, debugstr_wn(&ch
, 1), length
, coord
.X
, coord
.Y
, written
);
639 SetLastError( ERROR_INVALID_ACCESS
);
645 params
.mode
= CHAR_INFO_MODE_TEXT
;
648 params
.count
= length
;
652 return console_ioctl( handle
, IOCTL_CONDRV_FILL_OUTPUT
, ¶ms
, sizeof(params
),
653 written
, sizeof(*written
), NULL
);
657 /***********************************************************************
658 * FreeConsole (kernelbase.@)
660 BOOL WINAPI DECLSPEC_HOTPATCH
FreeConsole(void)
662 RtlEnterCriticalSection( &console_section
);
664 if (RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
!= CONSOLE_HANDLE_SHELL_NO_WINDOW
)
666 NtClose( console_connection
);
667 console_connection
= NULL
;
669 NtClose( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
);
671 RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
673 if (console_flags
& CONSOLE_INPUT_HANDLE
) NtClose( GetStdHandle( STD_INPUT_HANDLE
));
674 if (console_flags
& CONSOLE_OUTPUT_HANDLE
) NtClose( GetStdHandle( STD_OUTPUT_HANDLE
));
675 if (console_flags
& CONSOLE_ERROR_HANDLE
) NtClose( GetStdHandle( STD_ERROR_HANDLE
));
678 RtlLeaveCriticalSection( &console_section
);
683 /******************************************************************************
684 * GenerateConsoleCtrlEvent (kernelbase.@)
686 BOOL WINAPI DECLSPEC_HOTPATCH
GenerateConsoleCtrlEvent( DWORD event
, DWORD group
)
688 struct condrv_ctrl_event ctrl_event
;
690 TRACE( "(%ld, %lx)\n", event
, group
);
692 if (event
!= CTRL_C_EVENT
&& event
!= CTRL_BREAK_EVENT
)
694 ERR( "Invalid event %ld for PGID %lx\n", event
, group
);
698 ctrl_event
.event
= event
;
699 ctrl_event
.group_id
= group
;
700 return console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
701 IOCTL_CONDRV_CTRL_EVENT
, &ctrl_event
, sizeof(ctrl_event
), NULL
, 0, NULL
);
705 /******************************************************************
706 * GetConsoleAliasA (kernelbase.@)
708 DWORD WINAPI
GetConsoleAliasA( LPSTR source
, LPSTR buffer
, DWORD len
, LPSTR exename
)
710 FIXME( "(%s,%p,%ld,%s): stub\n", debugstr_a(source
), buffer
, len
, debugstr_a(exename
) );
711 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
716 /******************************************************************
717 * GetConsoleAliasW (kernelbase.@)
719 DWORD WINAPI
GetConsoleAliasW( LPWSTR source
, LPWSTR buffer
, DWORD len
, LPWSTR exename
)
721 FIXME( "(%s,%p,%ld,%s): stub\n", debugstr_w(source
), buffer
, len
, debugstr_w(exename
) );
722 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
727 /******************************************************************
728 * GetConsoleAliasExesLengthA (kernelbase.@)
730 DWORD WINAPI
GetConsoleAliasExesLengthA(void)
733 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
738 /******************************************************************
739 * GetConsoleAliasExesLengthW (kernelbase.@)
741 DWORD WINAPI
GetConsoleAliasExesLengthW(void)
744 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
749 /******************************************************************
750 * GetConsoleAliasesLengthA (kernelbase.@)
752 DWORD WINAPI
GetConsoleAliasesLengthA( LPSTR unknown
)
754 FIXME( ": (%s) stub!\n", debugstr_a(unknown
) );
755 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
760 /******************************************************************
761 * GetConsoleAliasesLengthW (kernelbase.@)
763 DWORD WINAPI
GetConsoleAliasesLengthW( LPWSTR unknown
)
765 FIXME( ": (%s) stub!\n", debugstr_w(unknown
) );
766 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
771 /******************************************************************
772 * GetConsoleCommandHistoryA (kernelbase.@)
774 DWORD WINAPI
GetConsoleCommandHistoryA( LPSTR buffer
, DWORD len
, LPCSTR exename
)
776 FIXME( ": (%p, 0x%lx, %s) stub\n", buffer
, len
, debugstr_a(exename
) );
777 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
782 /******************************************************************
783 * GetConsoleCommandHistoryW (kernelbase.@)
785 DWORD WINAPI
GetConsoleCommandHistoryW( LPWSTR buffer
, DWORD len
, LPCWSTR exename
)
787 FIXME( ": (%p, 0x%lx, %s) stub\n", buffer
, len
, debugstr_w(exename
) );
788 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
793 /******************************************************************
794 * GetConsoleCommandHistoryLengthA (kernelbase.@)
796 DWORD WINAPI
GetConsoleCommandHistoryLengthA( LPCSTR exename
)
798 FIXME( ": (%s) stub!\n", debugstr_a(exename
) );
799 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
804 /******************************************************************
805 * GetConsoleCommandHistoryLengthW (kernelbase.@)
807 DWORD WINAPI
GetConsoleCommandHistoryLengthW( LPCWSTR exename
)
809 FIXME( ": (%s) stub!\n", debugstr_w(exename
) );
810 SetLastError( ERROR_CALL_NOT_IMPLEMENTED
);
815 /******************************************************************************
816 * GetConsoleCP (kernelbase.@)
818 UINT WINAPI DECLSPEC_HOTPATCH
GetConsoleCP(void)
820 struct condrv_input_info info
;
822 if (!console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
823 IOCTL_CONDRV_GET_INPUT_INFO
, NULL
, 0, &info
, sizeof(info
), NULL
))
825 return info
.input_cp
;
829 /******************************************************************************
830 * GetConsoleCursorInfo (kernelbase.@)
832 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleCursorInfo( HANDLE handle
, CONSOLE_CURSOR_INFO
*info
)
834 struct condrv_output_info condrv_info
;
836 if (!console_ioctl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0, &condrv_info
, sizeof(condrv_info
), NULL
))
841 SetLastError( ERROR_INVALID_ACCESS
);
845 info
->dwSize
= condrv_info
.cursor_size
;
846 info
->bVisible
= condrv_info
.cursor_visible
;
847 TRACE("(%p) returning (%ld,%d)\n", handle
, info
->dwSize
, info
->bVisible
);
852 /***********************************************************************
853 * GetConsoleDisplayMode (kernelbase.@)
855 BOOL WINAPI
GetConsoleDisplayMode( LPDWORD flags
)
857 TRACE( "semi-stub: %p\n", flags
);
858 /* It is safe to successfully report windowed mode */
864 /***********************************************************************
865 * GetConsoleFontSize (kernelbase.@)
867 #if defined(__i386__) && !defined(__MINGW32__) && !defined(_MSC_VER)
868 #undef GetConsoleFontSize
869 DWORD WINAPI
GetConsoleFontSize( HANDLE handle
, DWORD index
)
876 x
.c
= get_console_font_size( handle
, index
);
880 COORD WINAPI
GetConsoleFontSize( HANDLE handle
, DWORD index
)
882 return get_console_font_size( handle
, index
);
884 #endif /* !defined(__i386__) */
887 /***********************************************************************
888 * GetConsoleInputExeNameA (kernelbase.@)
890 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleInputExeNameA( DWORD len
, LPSTR buffer
)
892 RtlEnterCriticalSection( &console_section
);
893 if (WideCharToMultiByte( CP_ACP
, 0, input_exe
, -1, NULL
, 0, NULL
, NULL
) <= len
)
894 WideCharToMultiByte( CP_ACP
, 0, input_exe
, -1, buffer
, len
, NULL
, NULL
);
895 else SetLastError(ERROR_BUFFER_OVERFLOW
);
896 RtlLeaveCriticalSection( &console_section
);
901 /***********************************************************************
902 * GetConsoleInputExeNameW (kernelbase.@)
904 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleInputExeNameW( DWORD len
, LPWSTR buffer
)
906 RtlEnterCriticalSection( &console_section
);
907 if (len
> lstrlenW(input_exe
)) lstrcpyW( buffer
, input_exe
);
908 else SetLastError( ERROR_BUFFER_OVERFLOW
);
909 RtlLeaveCriticalSection( &console_section
);
914 /***********************************************************************
915 * GetConsoleMode (kernelbase.@)
917 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleMode( HANDLE handle
, DWORD
*mode
)
919 return console_ioctl( handle
, IOCTL_CONDRV_GET_MODE
, NULL
, 0, mode
, sizeof(*mode
), NULL
);
923 /***********************************************************************
924 * GetConsoleOriginalTitleA (kernelbase.@)
926 DWORD WINAPI DECLSPEC_HOTPATCH
GetConsoleOriginalTitleA( LPSTR title
, DWORD size
)
928 WCHAR
*ptr
= HeapAlloc( GetProcessHeap(), 0, size
* sizeof(WCHAR
) );
933 ret
= GetConsoleOriginalTitleW( ptr
, size
);
935 WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr
, -1, title
, size
, NULL
, NULL
);
937 HeapFree( GetProcessHeap(), 0, ptr
);
942 /***********************************************************************
943 * GetConsoleOriginalTitleW (kernelbase.@)
945 DWORD WINAPI DECLSPEC_HOTPATCH
GetConsoleOriginalTitleW( LPWSTR title
, DWORD size
)
947 return get_console_title( title
, size
, FALSE
);
951 /***********************************************************************
952 * GetConsoleOutputCP (kernelbase.@)
954 UINT WINAPI DECLSPEC_HOTPATCH
GetConsoleOutputCP(void)
956 struct condrv_input_info info
;
958 if (!console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
959 IOCTL_CONDRV_GET_INPUT_INFO
, NULL
, 0, &info
, sizeof(info
), NULL
))
961 return info
.output_cp
;
965 /***********************************************************************
966 * GetConsoleProcessList (kernelbase.@)
968 DWORD WINAPI
GetConsoleProcessList( DWORD
*list
, DWORD count
)
974 TRACE( "(%p,%ld)\n", list
, count
);
976 if (!list
|| count
< 1)
978 SetLastError(ERROR_INVALID_PARAMETER
);
983 status
= NtDeviceIoControlFile( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
984 NULL
, NULL
, NULL
, &io
, IOCTL_CONDRV_GET_PROCESS_LIST
,
985 NULL
, 0, list
, count
* sizeof(DWORD
) );
987 if (!status
) return io
.Information
/ sizeof(DWORD
);
988 if (status
== STATUS_BUFFER_TOO_SMALL
)
996 set_ntstatus( status
);
1001 /***********************************************************************
1002 * GetConsoleScreenBufferInfo (kernelbase.@)
1004 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleScreenBufferInfo( HANDLE handle
, CONSOLE_SCREEN_BUFFER_INFO
*info
)
1006 struct condrv_output_info condrv_info
;
1008 if (!console_ioctl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0,
1009 &condrv_info
, sizeof(condrv_info
), NULL
))
1012 info
->dwSize
.X
= condrv_info
.width
;
1013 info
->dwSize
.Y
= condrv_info
.height
;
1014 info
->dwCursorPosition
.X
= condrv_info
.cursor_x
;
1015 info
->dwCursorPosition
.Y
= condrv_info
.cursor_y
;
1016 info
->wAttributes
= condrv_info
.attr
;
1017 info
->srWindow
.Left
= condrv_info
.win_left
;
1018 info
->srWindow
.Right
= condrv_info
.win_right
;
1019 info
->srWindow
.Top
= condrv_info
.win_top
;
1020 info
->srWindow
.Bottom
= condrv_info
.win_bottom
;
1021 info
->dwMaximumWindowSize
.X
= min(condrv_info
.width
, condrv_info
.max_width
);
1022 info
->dwMaximumWindowSize
.Y
= min(condrv_info
.height
, condrv_info
.max_height
);
1024 TRACE( "(%p,(%d,%d) (%d,%d) %d (%d,%d-%d,%d) (%d,%d)\n", handle
,
1025 info
->dwSize
.X
, info
->dwSize
.Y
, info
->dwCursorPosition
.X
, info
->dwCursorPosition
.Y
,
1026 info
->wAttributes
, info
->srWindow
.Left
, info
->srWindow
.Top
, info
->srWindow
.Right
,
1027 info
->srWindow
.Bottom
, info
->dwMaximumWindowSize
.X
, info
->dwMaximumWindowSize
.Y
);
1032 /***********************************************************************
1033 * GetConsoleScreenBufferInfoEx (kernelbase.@)
1035 BOOL WINAPI DECLSPEC_HOTPATCH
GetConsoleScreenBufferInfoEx( HANDLE handle
,
1036 CONSOLE_SCREEN_BUFFER_INFOEX
*info
)
1038 struct condrv_output_info condrv_info
;
1040 if (info
->cbSize
!= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
))
1042 SetLastError( ERROR_INVALID_PARAMETER
);
1046 if (!console_ioctl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0, &condrv_info
,
1047 sizeof(condrv_info
), NULL
))
1050 info
->dwSize
.X
= condrv_info
.width
;
1051 info
->dwSize
.Y
= condrv_info
.height
;
1052 info
->dwCursorPosition
.X
= condrv_info
.cursor_x
;
1053 info
->dwCursorPosition
.Y
= condrv_info
.cursor_y
;
1054 info
->wAttributes
= condrv_info
.attr
;
1055 info
->srWindow
.Left
= condrv_info
.win_left
;
1056 info
->srWindow
.Top
= condrv_info
.win_top
;
1057 info
->srWindow
.Right
= condrv_info
.win_right
;
1058 info
->srWindow
.Bottom
= condrv_info
.win_bottom
;
1059 info
->dwMaximumWindowSize
.X
= min( condrv_info
.width
, condrv_info
.max_width
);
1060 info
->dwMaximumWindowSize
.Y
= min( condrv_info
.height
, condrv_info
.max_height
);
1061 info
->wPopupAttributes
= condrv_info
.popup_attr
;
1062 info
->bFullscreenSupported
= FALSE
;
1063 memcpy( info
->ColorTable
, condrv_info
.color_map
, sizeof(info
->ColorTable
) );
1068 /******************************************************************************
1069 * GetConsoleTitleA (kernelbase.@)
1071 DWORD WINAPI DECLSPEC_HOTPATCH
GetConsoleTitleA( LPSTR title
, DWORD size
)
1073 WCHAR
*ptr
= HeapAlloc( GetProcessHeap(), 0, sizeof(WCHAR
) * size
);
1078 ret
= GetConsoleTitleW( ptr
, size
);
1080 WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr
, -1, title
, size
, NULL
, NULL
);
1082 HeapFree( GetProcessHeap(), 0, ptr
);
1087 /******************************************************************************
1088 * GetConsoleTitleW (kernelbase.@)
1090 DWORD WINAPI DECLSPEC_HOTPATCH
GetConsoleTitleW( LPWSTR title
, DWORD size
)
1092 return get_console_title( title
, size
, TRUE
);
1096 /******************************************************************************
1097 * GetConsoleWindow (kernelbase.@)
1099 HWND WINAPI
GetConsoleWindow(void)
1101 condrv_handle_t win
;
1104 ret
= DeviceIoControl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
1105 IOCTL_CONDRV_GET_WINDOW
, NULL
, 0, &win
, sizeof(win
), NULL
, NULL
);
1106 return ret
? LongToHandle( win
) : NULL
;
1110 /***********************************************************************
1111 * GetCurrentConsoleFontEx (kernelbase.@)
1113 BOOL WINAPI
GetCurrentConsoleFontEx( HANDLE handle
, BOOL maxwindow
, CONSOLE_FONT_INFOEX
*info
)
1118 struct condrv_output_info info
;
1119 WCHAR face_name
[LF_FACESIZE
- 1];
1122 if (info
->cbSize
!= sizeof(CONSOLE_FONT_INFOEX
))
1124 SetLastError(ERROR_INVALID_PARAMETER
);
1128 if (!DeviceIoControl( handle
, IOCTL_CONDRV_GET_OUTPUT_INFO
, NULL
, 0,
1129 &data
, sizeof(data
), &size
, NULL
))
1131 SetLastError( ERROR_INVALID_HANDLE
);
1138 info
->dwFontSize
.X
= min( data
.info
.width
, data
.info
.max_width
);
1139 info
->dwFontSize
.Y
= min( data
.info
.height
, data
.info
.max_height
);
1143 info
->dwFontSize
.X
= data
.info
.font_width
;
1144 info
->dwFontSize
.Y
= data
.info
.font_height
;
1146 size
-= sizeof(data
.info
);
1147 if (size
) memcpy( info
->FaceName
, data
.face_name
, size
);
1148 info
->FaceName
[size
/ sizeof(WCHAR
)] = 0;
1149 info
->FontFamily
= data
.info
.font_pitch_family
;
1150 info
->FontWeight
= data
.info
.font_weight
;
1155 /***********************************************************************
1156 * GetCurrentConsoleFont (kernelbase.@)
1158 BOOL WINAPI
GetCurrentConsoleFont( HANDLE handle
, BOOL maxwindow
, CONSOLE_FONT_INFO
*info
)
1161 CONSOLE_FONT_INFOEX res
;
1163 res
.cbSize
= sizeof(CONSOLE_FONT_INFOEX
);
1165 ret
= GetCurrentConsoleFontEx( handle
, maxwindow
, &res
);
1168 info
->nFont
= res
.nFont
;
1169 info
->dwFontSize
.X
= res
.dwFontSize
.X
;
1170 info
->dwFontSize
.Y
= res
.dwFontSize
.Y
;
1176 /***********************************************************************
1177 * GetLargestConsoleWindowSize (kernelbase.@)
1179 #if defined(__i386__) && !defined(__MINGW32__) && !defined(_MSC_VER)
1180 #undef GetLargestConsoleWindowSize
1181 DWORD WINAPI DECLSPEC_HOTPATCH
GetLargestConsoleWindowSize( HANDLE handle
)
1187 x
.c
= get_largest_console_window_size( handle
);
1193 COORD WINAPI DECLSPEC_HOTPATCH
GetLargestConsoleWindowSize( HANDLE handle
)
1195 return get_largest_console_window_size( handle
);
1198 #endif /* !defined(__i386__) */
1201 /***********************************************************************
1202 * GetNumberOfConsoleInputEvents (kernelbase.@)
1204 BOOL WINAPI DECLSPEC_HOTPATCH
GetNumberOfConsoleInputEvents( HANDLE handle
, DWORD
*count
)
1206 struct condrv_input_info info
;
1207 if (!console_ioctl( handle
, IOCTL_CONDRV_GET_INPUT_INFO
, NULL
, 0, &info
, sizeof(info
), NULL
))
1209 *count
= info
.input_count
;
1214 /***********************************************************************
1215 * GetNumberOfConsoleMouseButtons (kernelbase.@)
1217 BOOL WINAPI
GetNumberOfConsoleMouseButtons( DWORD
*count
)
1219 FIXME( "(%p): stub\n", count
);
1225 /***********************************************************************
1226 * PeekConsoleInputA (kernelbase.@)
1228 BOOL WINAPI DECLSPEC_HOTPATCH
PeekConsoleInputA( HANDLE handle
, INPUT_RECORD
*buffer
,
1229 DWORD length
, DWORD
*count
)
1233 if (!PeekConsoleInputW( handle
, buffer
, length
, &read
)) return FALSE
;
1234 input_records_WtoA( buffer
, read
);
1235 if (count
) *count
= read
;
1240 /***********************************************************************
1241 * PeekConsoleInputW (kernelbase.@)
1243 BOOL WINAPI DECLSPEC_HOTPATCH
PeekConsoleInputW( HANDLE handle
, INPUT_RECORD
*buffer
,
1244 DWORD length
, DWORD
*count
)
1247 if (!console_ioctl( handle
, IOCTL_CONDRV_PEEK
, NULL
, 0, buffer
, length
* sizeof(*buffer
), &read
))
1249 if (count
) *count
= read
/ sizeof(*buffer
);
1254 /******************************************************************************
1255 * ReadConsoleOutputAttribute (kernelbase.@)
1257 BOOL WINAPI DECLSPEC_HOTPATCH
ReadConsoleOutputAttribute( HANDLE handle
, WORD
*attr
, DWORD length
,
1258 COORD coord
, DWORD
*count
)
1260 struct condrv_output_params params
;
1263 TRACE( "(%p,%p,%ld,%dx%d,%p)\n", handle
, attr
, length
, coord
.X
, coord
.Y
, count
);
1267 SetLastError( ERROR_INVALID_ACCESS
);
1271 params
.mode
= CHAR_INFO_MODE_ATTR
;
1275 ret
= console_ioctl( handle
, IOCTL_CONDRV_READ_OUTPUT
, ¶ms
, sizeof(params
),
1276 attr
, length
* sizeof(*attr
), count
);
1277 *count
/= sizeof(*attr
);
1282 /******************************************************************************
1283 * ReadConsoleOutputCharacterA (kernelbase.@)
1285 BOOL WINAPI DECLSPEC_HOTPATCH
ReadConsoleOutputCharacterA( HANDLE handle
, LPSTR buffer
, DWORD length
,
1286 COORD coord
, DWORD
*count
)
1294 SetLastError( ERROR_INVALID_ACCESS
);
1299 if (!(wptr
= HeapAlloc( GetProcessHeap(), 0, length
* sizeof(WCHAR
) )))
1301 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1304 if ((ret
= ReadConsoleOutputCharacterW( handle
, wptr
, length
, coord
, &read
)))
1306 read
= WideCharToMultiByte( GetConsoleOutputCP(), 0, wptr
, read
, buffer
, length
, NULL
, NULL
);
1309 HeapFree( GetProcessHeap(), 0, wptr
);
1314 /******************************************************************************
1315 * ReadConsoleOutputCharacterW (kernelbase.@)
1317 BOOL WINAPI DECLSPEC_HOTPATCH
ReadConsoleOutputCharacterW( HANDLE handle
, LPWSTR buffer
, DWORD length
,
1318 COORD coord
, DWORD
*count
)
1320 struct condrv_output_params params
;
1323 TRACE( "(%p,%p,%ld,%dx%d,%p)\n", handle
, buffer
, length
, coord
.X
, coord
.Y
, count
);
1327 SetLastError( ERROR_INVALID_ACCESS
);
1331 params
.mode
= CHAR_INFO_MODE_TEXT
;
1335 ret
= console_ioctl( handle
, IOCTL_CONDRV_READ_OUTPUT
, ¶ms
, sizeof(params
), buffer
,
1336 length
* sizeof(*buffer
), count
);
1337 *count
/= sizeof(*buffer
);
1342 /******************************************************************************
1343 * ReadConsoleOutputA (kernelbase.@)
1345 BOOL WINAPI DECLSPEC_HOTPATCH
ReadConsoleOutputA( HANDLE handle
, CHAR_INFO
*buffer
, COORD size
,
1346 COORD coord
, SMALL_RECT
*region
)
1351 ret
= ReadConsoleOutputW( handle
, buffer
, size
, coord
, region
);
1352 if (ret
&& region
->Right
>= region
->Left
)
1354 UINT cp
= GetConsoleOutputCP();
1355 for (y
= 0; y
<= region
->Bottom
- region
->Top
; y
++)
1356 char_info_WtoA( cp
, &buffer
[(coord
.Y
+ y
) * size
.X
+ coord
.X
], region
->Right
- region
->Left
+ 1 );
1362 /******************************************************************************
1363 * ReadConsoleOutputW (kernelbase.@)
1365 BOOL WINAPI DECLSPEC_HOTPATCH
ReadConsoleOutputW( HANDLE handle
, CHAR_INFO
*buffer
, COORD size
,
1366 COORD coord
, SMALL_RECT
*region
)
1368 struct condrv_output_params params
;
1369 unsigned int width
, height
, y
;
1374 if (region
->Left
> region
->Right
|| region
->Top
> region
->Bottom
)
1376 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1379 if (size
.X
<= coord
.X
|| size
.Y
<= coord
.Y
)
1381 region
->Right
= region
->Left
- 1;
1382 region
->Bottom
= region
->Top
- 1;
1383 SetLastError( ERROR_INVALID_FUNCTION
);
1386 width
= min( region
->Right
- region
->Left
+ 1, size
.X
- coord
.X
);
1387 height
= min( region
->Bottom
- region
->Top
+ 1, size
.Y
- coord
.Y
);
1388 region
->Right
= region
->Left
+ width
- 1;
1389 region
->Bottom
= region
->Top
+ height
- 1;
1391 count
= sizeof(*result
) + width
* height
* sizeof(*buffer
);
1392 if (!(result
= HeapAlloc( GetProcessHeap(), 0, count
)))
1394 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1398 params
.mode
= CHAR_INFO_MODE_TEXTATTR
;
1399 params
.x
= region
->Left
;
1400 params
.y
= region
->Top
;
1401 params
.width
= width
;
1402 if ((ret
= console_ioctl( handle
, IOCTL_CONDRV_READ_OUTPUT
, ¶ms
, sizeof(params
), result
, count
, &count
)) && count
)
1404 CHAR_INFO
*char_info
= (CHAR_INFO
*)(result
+ 1);
1406 width
= region
->Right
- region
->Left
+ 1;
1407 height
= region
->Bottom
- region
->Top
+ 1;
1408 for (y
= 0; y
< height
; y
++)
1409 memcpy( &buffer
[(y
+ coord
.Y
) * size
.X
+ coord
.X
], &char_info
[y
* width
], width
* sizeof(*buffer
) );
1411 HeapFree( GetProcessHeap(), 0, result
);
1416 /******************************************************************************
1417 * ScrollConsoleScreenBufferA (kernelbase.@)
1419 BOOL WINAPI DECLSPEC_HOTPATCH
ScrollConsoleScreenBufferA( HANDLE handle
, const SMALL_RECT
*scroll
,
1420 const SMALL_RECT
*clip
, COORD origin
, const CHAR_INFO
*fill
)
1424 ciW
.Attributes
= fill
->Attributes
;
1425 MultiByteToWideChar( GetConsoleOutputCP(), 0, &fill
->Char
.AsciiChar
, 1, &ciW
.Char
.UnicodeChar
, 1 );
1427 return ScrollConsoleScreenBufferW( handle
, scroll
, clip
, origin
, &ciW
);
1431 /******************************************************************************
1432 * ScrollConsoleScreenBufferW (kernelbase.@)
1434 BOOL WINAPI DECLSPEC_HOTPATCH
ScrollConsoleScreenBufferW( HANDLE handle
, const SMALL_RECT
*scroll
,
1435 const SMALL_RECT
*clip_rect
, COORD origin
,
1436 const CHAR_INFO
*fill
)
1438 struct condrv_scroll_params params
;
1441 TRACE( "(%p,(%d,%d-%d,%d),(%d,%d-%d,%d),%d-%d,%p)\n", handle
,
1442 scroll
->Left
, scroll
->Top
, scroll
->Right
, scroll
->Bottom
,
1443 clip_rect
->Left
, clip_rect
->Top
, clip_rect
->Right
, clip_rect
->Bottom
,
1444 origin
.X
, origin
.Y
, fill
);
1446 TRACE("(%p,(%d,%d-%d,%d),(nil),%d-%d,%p)\n", handle
,
1447 scroll
->Left
, scroll
->Top
, scroll
->Right
, scroll
->Bottom
,
1448 origin
.X
, origin
.Y
, fill
);
1450 params
.scroll
= *scroll
;
1451 params
.origin
= origin
;
1452 params
.fill
.ch
= fill
->Char
.UnicodeChar
;
1453 params
.fill
.attr
= fill
->Attributes
;
1456 params
.clip
.Left
= params
.clip
.Top
= 0;
1457 params
.clip
.Right
= params
.clip
.Bottom
= SHRT_MAX
;
1459 else params
.clip
= *clip_rect
;
1460 return console_ioctl( handle
, IOCTL_CONDRV_SCROLL
, (void *)¶ms
, sizeof(params
), NULL
, 0, NULL
);
1464 /******************************************************************************
1465 * SetConsoleActiveScreenBuffer (kernelbase.@)
1467 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleActiveScreenBuffer( HANDLE handle
)
1469 TRACE( "(%p)\n", handle
);
1470 return console_ioctl( handle
, IOCTL_CONDRV_ACTIVATE
, NULL
, 0, NULL
, 0, NULL
);
1474 /******************************************************************************
1475 * SetConsoleCP (kernelbase.@)
1477 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleCP( UINT cp
)
1479 struct condrv_input_info_params params
= { SET_CONSOLE_INPUT_INFO_INPUT_CODEPAGE
};
1481 params
.info
.input_cp
= cp
;
1482 return console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
1483 IOCTL_CONDRV_SET_INPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1487 /******************************************************************************
1488 * SetConsoleCtrlHandler (kernelbase.@)
1490 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleCtrlHandler( PHANDLER_ROUTINE func
, BOOL add
)
1492 struct ctrl_handler
*handler
;
1495 TRACE( "(%p,%d)\n", func
, add
);
1497 RtlEnterCriticalSection( &console_section
);
1501 if (add
) NtCurrentTeb()->Peb
->ProcessParameters
->ConsoleFlags
|= 1;
1502 else NtCurrentTeb()->Peb
->ProcessParameters
->ConsoleFlags
&= ~1;
1507 if ((handler
= RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*handler
) )))
1509 handler
->func
= func
;
1510 handler
->next
= ctrl_handlers
;
1511 ctrl_handlers
= handler
;
1517 struct ctrl_handler
**p_handler
;
1519 for (p_handler
= &ctrl_handlers
; *p_handler
; p_handler
= &(*p_handler
)->next
)
1521 if ((*p_handler
)->func
== func
) break;
1523 if (*p_handler
&& *p_handler
!= &default_handler
)
1525 handler
= *p_handler
;
1526 *p_handler
= handler
->next
;
1527 RtlFreeHeap( GetProcessHeap(), 0, handler
);
1530 else SetLastError( ERROR_INVALID_PARAMETER
);
1533 RtlLeaveCriticalSection( &console_section
);
1538 /******************************************************************************
1539 * SetConsoleCursorInfo (kernelbase.@)
1541 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleCursorInfo( HANDLE handle
, CONSOLE_CURSOR_INFO
*info
)
1543 struct condrv_output_info_params params
= { SET_CONSOLE_OUTPUT_INFO_CURSOR_GEOM
};
1545 TRACE( "(%p,%ld,%d)\n", handle
, info
->dwSize
, info
->bVisible
);
1547 params
.info
.cursor_size
= info
->dwSize
;
1548 params
.info
.cursor_visible
= info
->bVisible
;
1549 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
),
1554 /******************************************************************************
1555 * SetConsoleCursorPosition (kernelbase.@)
1557 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleCursorPosition( HANDLE handle
, COORD pos
)
1559 struct condrv_output_info_params params
= { SET_CONSOLE_OUTPUT_INFO_CURSOR_POS
};
1561 TRACE( "%p %d %d\n", handle
, pos
.X
, pos
.Y
);
1563 params
.info
.cursor_x
= pos
.X
;
1564 params
.info
.cursor_y
= pos
.Y
;
1565 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1569 /***********************************************************************
1570 * SetConsoleDisplayMode (kernelbase.@)
1572 BOOL WINAPI
SetConsoleDisplayMode( HANDLE handle
, DWORD flags
, COORD
*size
)
1574 TRACE( "(%p, %lx, (%d, %d))\n", handle
, flags
, size
->X
, size
->Y
);
1577 /* We cannot switch to fullscreen */
1584 /******************************************************************************
1585 * SetConsoleInputExeNameA (kernelbase.@)
1587 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleInputExeNameA( LPCSTR name
)
1589 if (!name
|| !name
[0])
1591 SetLastError( ERROR_INVALID_PARAMETER
);
1594 RtlEnterCriticalSection( &console_section
);
1595 MultiByteToWideChar( CP_ACP
, 0, name
, -1, input_exe
, ARRAY_SIZE(input_exe
) );
1596 RtlLeaveCriticalSection( &console_section
);
1601 /******************************************************************************
1602 * SetConsoleInputExeNameW (kernelbase.@)
1604 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleInputExeNameW( LPCWSTR name
)
1606 if (!name
|| !name
[0])
1608 SetLastError( ERROR_INVALID_PARAMETER
);
1611 RtlEnterCriticalSection( &console_section
);
1612 lstrcpynW( input_exe
, name
, ARRAY_SIZE(input_exe
) );
1613 RtlLeaveCriticalSection( &console_section
);
1618 /******************************************************************************
1619 * SetConsoleMode (kernelbase.@)
1621 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleMode( HANDLE handle
, DWORD mode
)
1623 TRACE( "(%p,%lx)\n", handle
, mode
);
1624 return console_ioctl( handle
, IOCTL_CONDRV_SET_MODE
, &mode
, sizeof(mode
), NULL
, 0, NULL
);
1628 /******************************************************************************
1629 * SetConsoleOutputCP (kernelbase.@)
1631 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleOutputCP( UINT cp
)
1633 struct condrv_input_info_params params
= { SET_CONSOLE_INPUT_INFO_OUTPUT_CODEPAGE
};
1635 params
.info
.output_cp
= cp
;
1636 return console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
1637 IOCTL_CONDRV_SET_INPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1641 /******************************************************************************
1642 * SetConsoleScreenBufferInfoEx (kernelbase.@)
1644 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleScreenBufferInfoEx( HANDLE handle
,
1645 CONSOLE_SCREEN_BUFFER_INFOEX
*info
)
1647 struct condrv_output_info_params params
=
1648 { SET_CONSOLE_OUTPUT_INFO_CURSOR_POS
| SET_CONSOLE_OUTPUT_INFO_SIZE
|
1649 SET_CONSOLE_OUTPUT_INFO_ATTR
| SET_CONSOLE_OUTPUT_INFO_POPUP_ATTR
|
1650 SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW
| SET_CONSOLE_OUTPUT_INFO_MAX_SIZE
};
1652 TRACE("(%p, %p)\n", handle
, info
);
1654 if (info
->cbSize
!= sizeof(CONSOLE_SCREEN_BUFFER_INFOEX
))
1656 SetLastError(ERROR_INVALID_PARAMETER
);
1660 params
.info
.width
= info
->dwSize
.X
;
1661 params
.info
.height
= info
->dwSize
.Y
;
1662 params
.info
.cursor_x
= info
->dwCursorPosition
.X
;
1663 params
.info
.cursor_y
= info
->dwCursorPosition
.Y
;
1664 params
.info
.attr
= info
->wAttributes
;
1665 params
.info
.win_left
= info
->srWindow
.Left
;
1666 params
.info
.win_top
= info
->srWindow
.Top
;
1667 params
.info
.win_right
= info
->srWindow
.Right
;
1668 params
.info
.win_bottom
= info
->srWindow
.Bottom
;
1669 params
.info
.popup_attr
= info
->wPopupAttributes
;
1670 params
.info
.max_width
= min( info
->dwMaximumWindowSize
.X
, info
->dwSize
.X
);
1671 params
.info
.max_height
= min( info
->dwMaximumWindowSize
.Y
, info
->dwSize
.Y
);
1672 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1676 /******************************************************************************
1677 * SetConsoleScreenBufferSize (kernelbase.@)
1679 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleScreenBufferSize( HANDLE handle
, COORD size
)
1681 struct condrv_output_info_params params
= { SET_CONSOLE_OUTPUT_INFO_SIZE
};
1683 TRACE( "(%p,(%d,%d))\n", handle
, size
.X
, size
.Y
);
1685 params
.info
.width
= size
.X
;
1686 params
.info
.height
= size
.Y
;
1687 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1691 /******************************************************************************
1692 * SetConsoleTextAttribute (kernelbase.@)
1694 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleTextAttribute( HANDLE handle
, WORD attr
)
1696 struct condrv_output_info_params params
= { SET_CONSOLE_OUTPUT_INFO_ATTR
};
1698 TRACE( "(%p,%d)\n", handle
, attr
);
1700 params
.info
.attr
= attr
;
1701 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1705 /******************************************************************************
1706 * SetConsoleTitleA (kernelbase.@)
1708 BOOL WINAPI
SetConsoleTitleA( LPCSTR title
)
1712 DWORD len
= MultiByteToWideChar( GetConsoleOutputCP(), 0, title
, -1, NULL
, 0 );
1713 if (!(titleW
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) ))) return FALSE
;
1714 MultiByteToWideChar( GetConsoleOutputCP(), 0, title
, -1, titleW
, len
);
1715 ret
= SetConsoleTitleW(titleW
);
1716 HeapFree( GetProcessHeap(), 0, titleW
);
1721 /******************************************************************************
1722 * SetConsoleTitleW (kernelbase.@)
1724 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleTitleW( LPCWSTR title
)
1726 TRACE( "%s\n", debugstr_w( title
));
1728 return console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
, IOCTL_CONDRV_SET_TITLE
,
1729 (void *)title
, lstrlenW(title
) * sizeof(WCHAR
), NULL
, 0, NULL
);
1733 /******************************************************************************
1734 * SetConsoleWindowInfo (kernelbase.@)
1736 BOOL WINAPI DECLSPEC_HOTPATCH
SetConsoleWindowInfo( HANDLE handle
, BOOL absolute
, SMALL_RECT
*window
)
1738 struct condrv_output_info_params params
= { SET_CONSOLE_OUTPUT_INFO_DISPLAY_WINDOW
};
1739 SMALL_RECT rect
= *window
;
1741 TRACE( "(%p,%d,(%d,%d-%d,%d))\n", handle
, absolute
, rect
.Left
, rect
.Top
, rect
.Right
, rect
.Bottom
);
1745 CONSOLE_SCREEN_BUFFER_INFO info
;
1747 if (!GetConsoleScreenBufferInfo( handle
, &info
)) return FALSE
;
1748 rect
.Left
+= info
.srWindow
.Left
;
1749 rect
.Top
+= info
.srWindow
.Top
;
1750 rect
.Right
+= info
.srWindow
.Right
;
1751 rect
.Bottom
+= info
.srWindow
.Bottom
;
1754 params
.info
.win_left
= rect
.Left
;
1755 params
.info
.win_top
= rect
.Top
;
1756 params
.info
.win_right
= rect
.Right
;
1757 params
.info
.win_bottom
= rect
.Bottom
;
1758 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, ¶ms
, sizeof(params
), NULL
, 0, NULL
);
1762 /******************************************************************************
1763 * SetCurrentConsoleFontEx (kernelbase.@)
1765 BOOL WINAPI
SetCurrentConsoleFontEx( HANDLE handle
, BOOL maxwindow
, CONSOLE_FONT_INFOEX
*info
)
1769 struct condrv_output_info_params params
;
1770 WCHAR face_name
[LF_FACESIZE
];
1775 TRACE( "(%p %d %p)\n", handle
, maxwindow
, info
);
1777 if (info
->cbSize
!= sizeof(*info
))
1779 SetLastError(ERROR_INVALID_PARAMETER
);
1783 data
.params
.mask
= SET_CONSOLE_OUTPUT_INFO_FONT
;
1785 data
.params
.info
.font_width
= info
->dwFontSize
.X
;
1786 data
.params
.info
.font_height
= info
->dwFontSize
.Y
;
1787 data
.params
.info
.font_pitch_family
= info
->FontFamily
;
1788 data
.params
.info
.font_weight
= info
->FontWeight
;
1790 size
= wcsnlen( info
->FaceName
, LF_FACESIZE
- 1 ) * sizeof(WCHAR
);
1791 memcpy( data
.face_name
, info
->FaceName
, size
);
1793 size
+= sizeof(struct condrv_output_info_params
);
1794 return console_ioctl( handle
, IOCTL_CONDRV_SET_OUTPUT_INFO
, &data
, size
, NULL
, 0, NULL
);
1798 /***********************************************************************
1799 * ReadConsoleInputA (kernelbase.@)
1801 BOOL WINAPI
ReadConsoleInputA( HANDLE handle
, INPUT_RECORD
*buffer
, DWORD length
, DWORD
*count
)
1805 if (!ReadConsoleInputW( handle
, buffer
, length
, &read
)) return FALSE
;
1806 input_records_WtoA( buffer
, read
);
1807 if (count
) *count
= read
;
1812 /***********************************************************************
1813 * ReadConsoleInputW (kernelbase.@)
1815 BOOL WINAPI
ReadConsoleInputW( HANDLE handle
, INPUT_RECORD
*buffer
, DWORD length
, DWORD
*count
)
1817 if (!console_ioctl( handle
, IOCTL_CONDRV_READ_INPUT
, NULL
, 0,
1818 buffer
, length
* sizeof(*buffer
), count
))
1820 *count
/= sizeof(*buffer
);
1825 /******************************************************************************
1826 * WriteConsoleInputA (kernelbase.@)
1828 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleInputA( HANDLE handle
, const INPUT_RECORD
*buffer
,
1829 DWORD count
, DWORD
*written
)
1831 INPUT_RECORD
*recW
= NULL
;
1838 SetLastError( ERROR_INVALID_ACCESS
);
1841 if (!(recW
= HeapAlloc( GetProcessHeap(), 0, count
* sizeof(*recW
) )))
1843 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1846 memcpy( recW
, buffer
, count
* sizeof(*recW
) );
1847 input_records_AtoW( recW
, count
);
1849 ret
= WriteConsoleInputW( handle
, recW
, count
, written
);
1850 HeapFree( GetProcessHeap(), 0, recW
);
1855 /******************************************************************************
1856 * WriteConsoleInputW (kernelbase.@)
1858 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleInputW( HANDLE handle
, const INPUT_RECORD
*buffer
,
1859 DWORD count
, DWORD
*written
)
1861 TRACE( "(%p,%p,%ld,%p)\n", handle
, buffer
, count
, written
);
1863 if (count
> 0 && !buffer
)
1865 SetLastError( ERROR_INVALID_ACCESS
);
1869 if (!DeviceIoControl( handle
, IOCTL_CONDRV_WRITE_INPUT
, (void *)buffer
, count
* sizeof(*buffer
), NULL
, 0, NULL
, NULL
))
1874 SetLastError( ERROR_INVALID_ACCESS
);
1882 /***********************************************************************
1883 * WriteConsoleOutputA (kernelbase.@)
1885 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleOutputA( HANDLE handle
, const CHAR_INFO
*buffer
,
1886 COORD size
, COORD coord
, SMALL_RECT
*region
)
1890 COORD new_size
, new_coord
;
1893 new_size
.X
= min( region
->Right
- region
->Left
+ 1, size
.X
- coord
.X
);
1894 new_size
.Y
= min( region
->Bottom
- region
->Top
+ 1, size
.Y
- coord
.Y
);
1896 if (new_size
.X
<= 0 || new_size
.Y
<= 0)
1898 region
->Bottom
= region
->Top
+ new_size
.Y
- 1;
1899 region
->Right
= region
->Left
+ new_size
.X
- 1;
1903 /* only copy the useful rectangle */
1904 if (!(ciW
= HeapAlloc( GetProcessHeap(), 0, sizeof(CHAR_INFO
) * new_size
.X
* new_size
.Y
)))
1906 for (y
= 0; y
< new_size
.Y
; y
++)
1907 memcpy( &ciW
[y
* new_size
.X
], &buffer
[(y
+ coord
.Y
) * size
.X
+ coord
.X
],
1908 new_size
.X
* sizeof(CHAR_INFO
) );
1909 char_info_AtoW( ciW
, new_size
.X
* new_size
.Y
);
1910 new_coord
.X
= new_coord
.Y
= 0;
1911 ret
= WriteConsoleOutputW( handle
, ciW
, new_size
, new_coord
, region
);
1912 HeapFree( GetProcessHeap(), 0, ciW
);
1917 /***********************************************************************
1918 * WriteConsoleOutputW (kernelbase.@)
1920 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleOutputW( HANDLE handle
, const CHAR_INFO
*buffer
,
1921 COORD size
, COORD coord
, SMALL_RECT
*region
)
1923 struct condrv_output_params
*params
;
1924 unsigned int width
, height
, y
;
1928 TRACE( "(%p,%p,(%d,%d),(%d,%d),(%d,%dx%d,%d)\n",
1929 handle
, buffer
, size
.X
, size
.Y
, coord
.X
, coord
.Y
,
1930 region
->Left
, region
->Top
, region
->Right
, region
->Bottom
);
1932 if (region
->Left
> region
->Right
|| region
->Top
> region
->Bottom
|| size
.X
<= coord
.X
|| size
.Y
<= coord
.Y
)
1934 SetLastError( ERROR_INVALID_PARAMETER
);
1938 width
= min( region
->Right
- region
->Left
+ 1, size
.X
- coord
.X
);
1939 height
= min( region
->Bottom
- region
->Top
+ 1, size
.Y
- coord
.Y
);
1940 region
->Right
= region
->Left
+ width
- 1;
1941 region
->Bottom
= region
->Top
+ height
- 1;
1943 params_size
= sizeof(*params
) + width
* height
* sizeof(*buffer
);
1944 if (!(params
= HeapAlloc( GetProcessHeap(), 0, params_size
)))
1946 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
1950 params
->mode
= CHAR_INFO_MODE_TEXTATTR
;
1951 params
->x
= region
->Left
;
1952 params
->y
= region
->Top
;
1953 params
->width
= width
;
1955 for (y
= 0; y
< height
; y
++)
1956 memcpy( &((CHAR_INFO
*)(params
+ 1))[y
* width
], &buffer
[(y
+ coord
.Y
) * size
.X
+ coord
.X
], width
* sizeof(CHAR_INFO
) );
1958 ret
= console_ioctl( handle
, IOCTL_CONDRV_WRITE_OUTPUT
, params
, params_size
, region
, sizeof(*region
), NULL
);
1959 HeapFree( GetProcessHeap(), 0, params
);
1964 /******************************************************************************
1965 * WriteConsoleOutputAttribute (kernelbase.@)
1967 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleOutputAttribute( HANDLE handle
, const WORD
*attr
, DWORD length
,
1968 COORD coord
, DWORD
*written
)
1970 struct condrv_output_params
*params
;
1974 TRACE( "(%p,%p,%ld,%dx%d,%p)\n", handle
, attr
, length
, coord
.X
, coord
.Y
, written
);
1976 if ((length
> 0 && !attr
) || !written
)
1978 SetLastError( ERROR_INVALID_ACCESS
);
1983 size
= sizeof(*params
) + length
* sizeof(WORD
);
1984 if (!(params
= HeapAlloc( GetProcessHeap(), 0, size
))) return FALSE
;
1985 params
->mode
= CHAR_INFO_MODE_ATTR
;
1986 params
->x
= coord
.X
;
1987 params
->y
= coord
.Y
;
1989 memcpy( params
+ 1, attr
, length
* sizeof(*attr
) );
1990 ret
= console_ioctl( handle
, IOCTL_CONDRV_WRITE_OUTPUT
, params
, size
, written
, sizeof(*written
), NULL
);
1991 HeapFree( GetProcessHeap(), 0, params
);
1996 /******************************************************************************
1997 * WriteConsoleOutputCharacterA (kernelbase.@)
1999 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleOutputCharacterA( HANDLE handle
, LPCSTR str
, DWORD length
,
2000 COORD coord
, DWORD
*written
)
2006 TRACE( "(%p,%s,%ld,%dx%d,%p)\n", handle
, debugstr_an(str
, length
), length
, coord
.X
, coord
.Y
, written
);
2010 UINT cp
= GetConsoleOutputCP();
2013 SetLastError( ERROR_INVALID_ACCESS
);
2016 lenW
= MultiByteToWideChar( cp
, 0, str
, length
, NULL
, 0 );
2018 if (!(strW
= HeapAlloc( GetProcessHeap(), 0, lenW
* sizeof(WCHAR
) )))
2020 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
2023 MultiByteToWideChar( cp
, 0, str
, length
, strW
, lenW
);
2025 ret
= WriteConsoleOutputCharacterW( handle
, strW
, lenW
, coord
, written
);
2026 HeapFree( GetProcessHeap(), 0, strW
);
2031 /******************************************************************************
2032 * WriteConsoleOutputCharacterW (kernelbase.@)
2034 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleOutputCharacterW( HANDLE handle
, LPCWSTR str
, DWORD length
,
2035 COORD coord
, DWORD
*written
)
2037 struct condrv_output_params
*params
;
2041 TRACE( "(%p,%s,%ld,%dx%d,%p)\n", handle
, debugstr_wn(str
, length
), length
, coord
.X
, coord
.Y
, written
);
2043 if ((length
> 0 && !str
) || !written
)
2045 SetLastError( ERROR_INVALID_ACCESS
);
2050 size
= sizeof(*params
) + length
* sizeof(WCHAR
);
2051 if (!(params
= HeapAlloc( GetProcessHeap(), 0, size
))) return FALSE
;
2052 params
->mode
= CHAR_INFO_MODE_TEXT
;
2053 params
->x
= coord
.X
;
2054 params
->y
= coord
.Y
;
2056 memcpy( params
+ 1, str
, length
* sizeof(*str
) );
2057 ret
= console_ioctl( handle
, IOCTL_CONDRV_WRITE_OUTPUT
, params
, size
, written
, sizeof(*written
), NULL
);
2058 HeapFree( GetProcessHeap(), 0, params
);
2063 /***********************************************************************
2064 * ReadConsoleA (kernelbase.@)
2066 BOOL WINAPI
ReadConsoleA( HANDLE handle
, void *buffer
, DWORD length
, DWORD
*count
, void *reserved
)
2068 if (length
> INT_MAX
)
2070 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
2074 return console_ioctl( handle
, IOCTL_CONDRV_READ_FILE
, NULL
, 0, buffer
, length
, count
);
2078 /***********************************************************************
2079 * ReadConsoleW (kernelbase.@)
2081 BOOL WINAPI
ReadConsoleW( HANDLE handle
, void *buffer
, DWORD length
, DWORD
*count
, void *reserved
)
2085 TRACE( "(%p,%p,%ld,%p,%p)\n", handle
, buffer
, length
, count
, reserved
);
2087 if (length
> INT_MAX
)
2089 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2095 CONSOLE_READCONSOLE_CONTROL
* crc
= reserved
;
2098 if (crc
->nLength
!= sizeof(*crc
) || crc
->nInitialChars
>= length
)
2100 SetLastError( ERROR_INVALID_PARAMETER
);
2103 if (!(tmp
= HeapAlloc( GetProcessHeap(), 0, sizeof(DWORD
) + length
* sizeof(WCHAR
) )))
2105 SetLastError( ERROR_NOT_ENOUGH_MEMORY
);
2109 memcpy( tmp
, &crc
->dwCtrlWakeupMask
, sizeof(DWORD
) );
2110 memcpy( tmp
+ sizeof(DWORD
), buffer
, crc
->nInitialChars
* sizeof(WCHAR
) );
2111 ret
= console_ioctl( handle
, IOCTL_CONDRV_READ_CONSOLE_CONTROL
,
2112 tmp
, sizeof(DWORD
) + crc
->nInitialChars
* sizeof(WCHAR
),
2113 tmp
, sizeof(DWORD
) + length
* sizeof(WCHAR
), count
);
2116 memcpy( &crc
->dwConsoleKeyState
, tmp
, sizeof(DWORD
) );
2117 *count
-= sizeof(DWORD
);
2118 memcpy( buffer
, tmp
+ sizeof(DWORD
), *count
);
2120 HeapFree( GetProcessHeap(), 0, tmp
);
2124 ret
= console_ioctl( handle
, IOCTL_CONDRV_READ_CONSOLE
, NULL
, 0, buffer
,
2125 length
* sizeof(WCHAR
), count
);
2127 if (ret
) *count
/= sizeof(WCHAR
);
2132 /***********************************************************************
2133 * WriteConsoleA (kernelbase.@)
2135 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleA( HANDLE handle
, const void *buffer
, DWORD length
,
2136 DWORD
*written
, void *reserved
)
2140 TRACE( "(%p,%s,%ld,%p,%p)\n", handle
, debugstr_an(buffer
, length
), length
, written
, reserved
);
2142 ret
= console_ioctl( handle
, IOCTL_CONDRV_WRITE_FILE
, (void *)buffer
, length
, NULL
, 0, NULL
);
2143 if (written
) *written
= ret
? length
: 0;
2148 /***********************************************************************
2149 * WriteConsoleW (kernelbase.@)
2151 BOOL WINAPI DECLSPEC_HOTPATCH
WriteConsoleW( HANDLE handle
, const void *buffer
, DWORD length
,
2152 DWORD
*written
, void *reserved
)
2156 TRACE( "(%p,%s,%ld,%p,%p)\n", handle
, debugstr_wn(buffer
, length
), length
, written
, reserved
);
2158 ret
= console_ioctl( handle
, IOCTL_CONDRV_WRITE_CONSOLE
, (void *)buffer
,
2159 length
* sizeof(WCHAR
), NULL
, 0, NULL
);
2160 if (written
) *written
= ret
? length
: 0;
2165 /***********************************************************************
2166 * FlushConsoleInputBuffer (kernelbase.@)
2168 BOOL WINAPI
FlushConsoleInputBuffer( HANDLE handle
)
2170 return console_ioctl( handle
, IOCTL_CONDRV_FLUSH
, NULL
, 0, NULL
, 0, NULL
);
2174 /***********************************************************************
2175 * Beep (kernelbase.@)
2177 BOOL WINAPI
Beep( DWORD frequency
, DWORD duration
)
2179 /* FIXME: we should not require a console to be attached */
2180 console_ioctl( RtlGetCurrentPeb()->ProcessParameters
->ConsoleHandle
,
2181 IOCTL_CONDRV_BEEP
, NULL
, 0, NULL
, 0, NULL
);
2186 static HANDLE
create_pseudo_console( COORD size
, HANDLE input
, HANDLE output
, HANDLE signal
,
2187 DWORD flags
, HANDLE
*process
)
2189 WCHAR cmd
[MAX_PATH
], conhost_path
[MAX_PATH
];
2190 unsigned int inherit_count
;
2191 PROCESS_INFORMATION pi
;
2192 HANDLE server
, console
;
2199 if (!(server
= create_console_server())) return NULL
;
2201 console
= create_console_reference( server
);
2208 memset( &si
, 0, sizeof(si
) );
2209 si
.StartupInfo
.cb
= sizeof(STARTUPINFOEXW
);
2210 si
.StartupInfo
.hStdInput
= input
;
2211 si
.StartupInfo
.hStdOutput
= output
;
2212 si
.StartupInfo
.hStdError
= output
;
2213 si
.StartupInfo
.dwFlags
= STARTF_USESTDHANDLES
;
2215 inherit
[0] = server
;
2216 inherit
[1] = signal
;
2217 inherit_count
= signal
? 2 : 1;
2218 InitializeProcThreadAttributeList( NULL
, inherit_count
, 0, &attr_size
);
2219 if (!(si
.lpAttributeList
= HeapAlloc( GetProcessHeap(), 0, attr_size
)))
2225 InitializeProcThreadAttributeList( si
.lpAttributeList
, inherit_count
, 0, &attr_size
);
2226 UpdateProcThreadAttribute( si
.lpAttributeList
, 0, PROC_THREAD_ATTRIBUTE_HANDLE_LIST
,
2227 inherit
, sizeof(*inherit
) * inherit_count
, NULL
, NULL
);
2229 swprintf( conhost_path
, ARRAY_SIZE(conhost_path
), L
"%s\\conhost.exe", system_dir
);
2232 swprintf( cmd
, ARRAY_SIZE(cmd
),
2233 L
"\"%s\" --headless %s--width %u --height %u --signal 0x%x --server 0x%x",
2234 conhost_path
, (flags
& PSEUDOCONSOLE_INHERIT_CURSOR
) ? L
"--inheritcursor " : L
"",
2235 size
.X
, size
.Y
, signal
, server
);
2239 swprintf( cmd
, ARRAY_SIZE(cmd
), L
"\"%s\" --unix --width %u --height %u --server 0x%x",
2240 conhost_path
, size
.X
, size
.Y
, server
);
2242 Wow64DisableWow64FsRedirection( &redir
);
2243 res
= CreateProcessW( conhost_path
, cmd
, NULL
, NULL
, TRUE
, DETACHED_PROCESS
| EXTENDED_STARTUPINFO_PRESENT
,
2244 NULL
, NULL
, &si
.StartupInfo
, &pi
);
2245 HeapFree( GetProcessHeap(), 0, si
.lpAttributeList
);
2246 Wow64RevertWow64FsRedirection( redir
);
2254 NtClose( pi
.hThread
);
2255 *process
= pi
.hProcess
;
2259 /******************************************************************************
2260 * CreatePseudoConsole (kernelbase.@)
2262 HRESULT WINAPI
CreatePseudoConsole( COORD size
, HANDLE input
, HANDLE output
, DWORD flags
, HPCON
*ret
)
2264 SECURITY_ATTRIBUTES inherit_attr
= { sizeof(inherit_attr
), NULL
, TRUE
};
2265 struct pseudo_console
*pseudo_console
;
2266 HANDLE tty_input
= NULL
, tty_output
;
2267 HANDLE signal
= NULL
;
2268 WCHAR pipe_name
[64];
2270 TRACE( "(%u,%u) %p %p %lx %p\n", size
.X
, size
.Y
, input
, output
, flags
, ret
);
2272 if (!size
.X
|| !size
.Y
|| !ret
) return E_INVALIDARG
;
2274 if (!(pseudo_console
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(*pseudo_console
) ))) return E_OUTOFMEMORY
;
2276 swprintf( pipe_name
, ARRAY_SIZE(pipe_name
), L
"\\\\.\\pipe\\wine_pty_signal_pipe%x",
2277 GetCurrentThreadId() );
2278 signal
= CreateNamedPipeW( pipe_name
, PIPE_ACCESS_INBOUND
| FILE_FLAG_OVERLAPPED
, PIPE_TYPE_BYTE
,
2279 PIPE_UNLIMITED_INSTANCES
, 4096, 4096, NMPWAIT_USE_DEFAULT_WAIT
, &inherit_attr
);
2280 if (signal
== INVALID_HANDLE_VALUE
)
2282 HeapFree( GetProcessHeap(), 0, pseudo_console
);
2283 return HRESULT_FROM_WIN32( GetLastError() );
2285 pseudo_console
->signal
= CreateFileW( pipe_name
, GENERIC_WRITE
, 0, NULL
, OPEN_EXISTING
, 0, NULL
);
2286 if (pseudo_console
->signal
!= INVALID_HANDLE_VALUE
&&
2287 DuplicateHandle( GetCurrentProcess(), input
, GetCurrentProcess(), &tty_input
, 0, TRUE
, DUPLICATE_SAME_ACCESS
) &&
2288 DuplicateHandle( GetCurrentProcess(), output
, GetCurrentProcess(), &tty_output
, 0, TRUE
, DUPLICATE_SAME_ACCESS
))
2290 pseudo_console
->reference
= create_pseudo_console( size
, tty_input
, tty_output
, signal
, flags
,
2291 &pseudo_console
->process
);
2292 NtClose( tty_output
);
2294 NtClose( tty_input
);
2296 if (!pseudo_console
->reference
)
2298 ClosePseudoConsole( pseudo_console
);
2299 return HRESULT_FROM_WIN32( GetLastError() );
2302 *ret
= pseudo_console
;
2306 /******************************************************************************
2307 * ClosePseudoConsole (kernelbase.@)
2309 void WINAPI
ClosePseudoConsole( HPCON handle
)
2311 struct pseudo_console
*pseudo_console
= handle
;
2313 TRACE( "%p\n", handle
);
2315 if (!pseudo_console
) return;
2316 if (pseudo_console
->signal
) CloseHandle( pseudo_console
->signal
);
2317 if (pseudo_console
->process
)
2319 WaitForSingleObject( pseudo_console
->process
, INFINITE
);
2320 CloseHandle( pseudo_console
->process
);
2322 if (pseudo_console
->reference
) CloseHandle( pseudo_console
->reference
);
2325 /******************************************************************************
2326 * ResizePseudoConsole (kernelbase.@)
2328 HRESULT WINAPI
ResizePseudoConsole( HPCON handle
, COORD size
)
2330 FIXME( "%p (%u,%u)\n", handle
, size
.X
, size
.Y
);
2334 static BOOL
is_tty_handle( HANDLE handle
)
2336 return ((UINT_PTR
)handle
& 3) == 1;
2339 void init_console( void )
2341 RTL_USER_PROCESS_PARAMETERS
*params
= RtlGetCurrentPeb()->ProcessParameters
;
2343 if (params
->ConsoleHandle
== CONSOLE_HANDLE_SHELL
)
2345 HANDLE tty_in
= NULL
, tty_out
= NULL
, process
= NULL
;
2348 if (is_tty_handle( params
->hStdInput
))
2350 tty_in
= params
->hStdInput
;
2351 params
->hStdInput
= NULL
;
2353 if (is_tty_handle( params
->hStdOutput
))
2355 tty_out
= params
->hStdOutput
;
2356 params
->hStdOutput
= NULL
;
2358 if (is_tty_handle( params
->hStdError
))
2360 if (tty_out
) CloseHandle( params
->hStdError
);
2361 else tty_out
= params
->hStdError
;
2362 params
->hStdError
= NULL
;
2365 size
.X
= params
->dwXCountChars
;
2366 size
.Y
= params
->dwYCountChars
;
2367 TRACE( "creating unix console (size %u %u)\n", size
.X
, size
.Y
);
2368 params
->ConsoleHandle
= create_pseudo_console( size
, tty_in
, tty_out
, NULL
, 0, &process
);
2369 CloseHandle( process
);
2370 CloseHandle( tty_in
);
2371 CloseHandle( tty_out
);
2373 if (params
->ConsoleHandle
&& create_console_connection( params
->ConsoleHandle
))
2375 init_console_std_handles( FALSE
);
2378 else if (params
->ConsoleHandle
== CONSOLE_HANDLE_ALLOC
||
2379 params
->ConsoleHandle
== CONSOLE_HANDLE_ALLOC_NO_WINDOW
)
2381 BOOL no_window
= params
->ConsoleHandle
== CONSOLE_HANDLE_ALLOC_NO_WINDOW
;
2382 HMODULE mod
= GetModuleHandleW( NULL
);
2383 params
->ConsoleHandle
= NULL
;
2384 if (RtlImageNtHeader( mod
)->OptionalHeader
.Subsystem
== IMAGE_SUBSYSTEM_WINDOWS_CUI
)
2385 alloc_console( no_window
);
2387 else if (params
->ConsoleHandle
&& params
->ConsoleHandle
!= CONSOLE_HANDLE_SHELL_NO_WINDOW
)
2388 create_console_connection( params
->ConsoleHandle
);