2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/console/console.c
5 * PURPOSE: Win32 server console functions
6 * PROGRAMMERS: James Tabor
7 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
10 /* INCLUDES *******************************************************************/
18 /* GLOBALS ********************************************************************/
20 extern RTL_CRITICAL_SECTION ConsoleLock
;
21 extern BOOL ConsoleInitialized
;
22 extern BOOL WINAPI
IsDebuggerPresent(VOID
);
24 /* Console reserved "file" names */
25 static LPCWSTR BaseConFileName
= CONSOLE_FILE_NAME
;
26 static LPCWSTR BaseConInputFileName
= CONSOLE_INPUT_FILE_NAME
;
27 static LPCWSTR BaseConOutputFileName
= CONSOLE_OUTPUT_FILE_NAME
;
29 PHANDLER_ROUTINE InitialHandler
[1];
30 PHANDLER_ROUTINE
* CtrlHandlers
;
32 ULONG NrAllocatedHandlers
;
34 HANDLE InputWaitHandle
= INVALID_HANDLE_VALUE
;
36 #define INPUTEXENAME_BUFLEN 256
37 static WCHAR InputExeName
[INPUTEXENAME_BUFLEN
];
40 /* Default Console Control Handler ********************************************/
44 DefaultConsoleCtrlHandler(DWORD Event
)
46 DPRINT("Default handler called: %lx\n", Event
);
50 DPRINT("Ctrl-C Event\n");
53 case CTRL_BREAK_EVENT
:
54 DPRINT("Ctrl-Break Event\n");
57 case CTRL_CLOSE_EVENT
:
58 DPRINT("Ctrl Close Event\n");
61 case CTRL_LOGOFF_EVENT
:
62 DPRINT("Ctrl Logoff Event\n");
65 case CTRL_SHUTDOWN_EVENT
:
66 DPRINT("Ctrl Shutdown Event\n");
70 ExitProcess(CONTROL_C_EXIT
);
76 ConsoleControlDispatcher(IN LPVOID lpThreadParameter
)
79 DWORD CodeAndFlag
= PtrToUlong(lpThreadParameter
);
80 DWORD nCode
= CodeAndFlag
& MAXLONG
;
82 EXCEPTION_RECORD erException
;
84 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag
, nCode
);
85 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST
);
90 case CTRL_BREAK_EVENT
:
92 if (IsDebuggerPresent())
94 erException
.ExceptionCode
= (nCode
== CTRL_C_EVENT
?
95 DBG_CONTROL_C
: DBG_CONTROL_BREAK
);
96 erException
.ExceptionFlags
= 0;
97 erException
.ExceptionRecord
= NULL
;
98 erException
.ExceptionAddress
= DefaultConsoleCtrlHandler
;
99 erException
.NumberParameters
= 0;
103 RtlRaiseException(&erException
);
105 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
107 RtlEnterCriticalSection(&ConsoleLock
);
109 if ((nCode
!= CTRL_C_EVENT
) ||
110 (NtCurrentPeb()->ProcessParameters
->ConsoleFlags
!= 1))
112 for (i
= NrCtrlHandlers
; i
> 0; i
--)
114 if (CtrlHandlers
[i
- 1](nCode
)) break;
118 RtlLeaveCriticalSection(&ConsoleLock
);
127 case CTRL_CLOSE_EVENT
:
128 case CTRL_LOGOFF_EVENT
:
129 case CTRL_SHUTDOWN_EVENT
:
137 ExitProcess(CONTROL_C_EXIT
);
145 ASSERT(ConsoleInitialized
);
147 RtlEnterCriticalSection(&ConsoleLock
);
150 if ((nCode
!= CTRL_C_EVENT
) || (NtCurrentPeb()->ProcessParameters
->ConsoleFlags
!= 1))
152 for (i
= NrCtrlHandlers
; i
> 0; i
--)
155 (CodeAndFlag
& MINLONG
) &&
156 ((nCode
== CTRL_LOGOFF_EVENT
) || (nCode
== CTRL_SHUTDOWN_EVENT
)))
158 DPRINT("Skipping system/service apps\n");
162 if (CtrlHandlers
[i
- 1](nCode
))
166 case CTRL_CLOSE_EVENT
:
167 case CTRL_LOGOFF_EVENT
:
168 case CTRL_SHUTDOWN_EVENT
:
170 nExitCode
= CodeAndFlag
;
178 RtlLeaveCriticalSection(&ConsoleLock
);
180 ExitThread(nExitCode
);
181 return STATUS_SUCCESS
;
186 InitConsoleCtrlHandling(VOID
)
188 /* Initialize Console Ctrl Handler */
189 NrAllocatedHandlers
= NrCtrlHandlers
= 1;
190 CtrlHandlers
= InitialHandler
;
191 CtrlHandlers
[0] = DefaultConsoleCtrlHandler
;
195 /* FUNCTIONS ******************************************************************/
198 IntCheckForConsoleFileName(IN LPCWSTR pszName
,
199 IN DWORD dwDesiredAccess
)
201 LPCWSTR ConsoleName
= pszName
;
202 ULONG DeviceNameInfo
;
205 * Check whether we deal with a DOS device, and if so,
206 * strip the path till the file name.
207 * Therefore, things like \\.\CON or C:\some_path\CONIN$
208 * are transformed into CON or CONIN$, for example.
210 DeviceNameInfo
= RtlIsDosDeviceName_U(pszName
);
211 if (DeviceNameInfo
!= 0)
213 ConsoleName
= (LPCWSTR
)((ULONG_PTR
)ConsoleName
+ ((DeviceNameInfo
>> 16) & 0xFFFF));
216 /* Return a standard console "file" name according to what we passed in parameters */
217 if (_wcsicmp(ConsoleName
, BaseConInputFileName
) == 0)
219 return BaseConInputFileName
;
221 else if (_wcsicmp(ConsoleName
, BaseConOutputFileName
) == 0)
223 return BaseConOutputFileName
;
225 else if (_wcsicmp(ConsoleName
, BaseConFileName
) == 0)
227 if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_READ
)
229 return BaseConInputFileName
;
231 else if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_WRITE
)
233 return BaseConOutputFileName
;
237 /* If we are there, that means that either the file name or the desired access are wrong */
243 * @unimplemented (Undocumented)
247 ConsoleMenuControl(HANDLE hConsole
,
251 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole
, Unknown1
, Unknown2
);
252 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
262 DuplicateConsoleHandle(HANDLE hConsole
,
263 DWORD dwDesiredAccess
,
268 CONSOLE_API_MESSAGE ApiMessage
;
269 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest
= &ApiMessage
.Data
.DuplicateHandleRequest
;
271 if ( (dwOptions
& ~(DUPLICATE_CLOSE_SOURCE
| DUPLICATE_SAME_ACCESS
)) ||
272 (!(dwOptions
& DUPLICATE_SAME_ACCESS
) &&
273 (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
))) )
275 SetLastError (ERROR_INVALID_PARAMETER
);
276 return INVALID_HANDLE_VALUE
;
279 DuplicateHandleRequest
->ConsoleHandle
= hConsole
;
280 DuplicateHandleRequest
->Access
= dwDesiredAccess
;
281 DuplicateHandleRequest
->Inheritable
= bInheritHandle
;
282 DuplicateHandleRequest
->Options
= dwOptions
;
284 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
286 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepDuplicateHandle
),
287 sizeof(CONSOLE_DUPLICATEHANDLE
));
288 if (!NT_SUCCESS(Status
))
290 BaseSetLastNTError(Status
);
291 return INVALID_HANDLE_VALUE
;
294 return DuplicateHandleRequest
->ConsoleHandle
;
303 GetConsoleDisplayMode(LPDWORD lpModeFlags
)
306 CONSOLE_API_MESSAGE ApiMessage
;
307 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest
= &ApiMessage
.Data
.GetDisplayModeRequest
;
309 if (lpModeFlags
== NULL
)
311 SetLastError(ERROR_INVALID_PARAMETER
);
315 // GetDisplayModeRequest->OutputHandle = hConsoleOutput;
317 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
319 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetDisplayMode
),
320 sizeof(CONSOLE_GETDISPLAYMODE
));
321 if (!NT_SUCCESS(Status
))
323 BaseSetLastNTError(Status
);
327 *lpModeFlags
= GetDisplayModeRequest
->DisplayMode
;
333 * @unimplemented (Undocumented)
337 GetConsoleFontInfo(DWORD Unknown0
,
342 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
343 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
353 GetConsoleFontSize(HANDLE hConsoleOutput
,
356 COORD Empty
= {0, 0};
357 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, nFont
);
358 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
364 * @implemented (Undocumented)
368 GetConsoleHardwareState(HANDLE hConsoleOutput
,
373 CONSOLE_API_MESSAGE ApiMessage
;
374 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
376 DPRINT1("GetConsoleHardwareState(%d, 0x%p) UNIMPLEMENTED!\n", Flags
, State
);
380 SetLastError(ERROR_INVALID_PARAMETER
);
384 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
386 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
388 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetHardwareState
),
389 sizeof(CONSOLE_GETSETHWSTATE
));
390 if (!NT_SUCCESS(Status
))
392 BaseSetLastNTError(Status
);
396 *State
= HardwareStateRequest
->State
;
402 * @implemented (Undocumented)
406 GetConsoleInputWaitHandle(VOID
)
408 return InputWaitHandle
;
417 GetCurrentConsoleFont(HANDLE hConsoleOutput
,
419 PCONSOLE_FONT_INFO lpConsoleCurrentFont
)
421 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, bMaximumWindow
, lpConsoleCurrentFont
);
422 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
428 * @unimplemented (Undocumented)
432 GetNumberOfConsoleFonts(VOID
)
434 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
435 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
441 * @implemented (Undocumented)
442 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
446 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput
,
447 IN PSMALL_RECT lpRect
)
450 CONSOLE_API_MESSAGE ApiMessage
;
451 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest
= &ApiMessage
.Data
.InvalidateDIBitsRequest
;
455 SetLastError(ERROR_INVALID_PARAMETER
);
459 InvalidateDIBitsRequest
->OutputHandle
= hConsoleOutput
;
460 InvalidateDIBitsRequest
->Region
= *lpRect
;
462 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
464 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepInvalidateBitMapRect
),
465 sizeof(CONSOLE_INVALIDATEDIBITS
));
466 if (!NT_SUCCESS(Status
))
468 BaseSetLastNTError(Status
);
477 * @unimplemented (Undocumented)
481 OpenConsoleW(LPCWSTR wsName
,
482 DWORD dwDesiredAccess
,
486 NTSTATUS Status
= STATUS_SUCCESS
;
487 CONSOLE_API_MESSAGE ApiMessage
;
488 PCONSOLE_OPENCONSOLE OpenConsoleRequest
= &ApiMessage
.Data
.OpenConsoleRequest
;
489 CONSOLE_HANDLE_TYPE HandleType
;
491 if (wsName
&& 0 == _wcsicmp(wsName
, BaseConInputFileName
))
493 HandleType
= HANDLE_INPUT
;
495 else if (wsName
&& 0 == _wcsicmp(wsName
, BaseConOutputFileName
))
497 HandleType
= HANDLE_OUTPUT
;
501 SetLastError(ERROR_INVALID_PARAMETER
);
502 return INVALID_HANDLE_VALUE
;
505 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
506 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) )
508 SetLastError(ERROR_INVALID_PARAMETER
);
509 return INVALID_HANDLE_VALUE
;
512 OpenConsoleRequest
->HandleType
= HandleType
;
513 OpenConsoleRequest
->Access
= dwDesiredAccess
;
514 OpenConsoleRequest
->Inheritable
= bInheritHandle
;
515 OpenConsoleRequest
->ShareMode
= dwShareMode
;
517 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
519 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepOpenConsole
),
520 sizeof(CONSOLE_OPENCONSOLE
));
521 if (!NT_SUCCESS(Status
))
523 BaseSetLastNTError(Status
);
524 return INVALID_HANDLE_VALUE
;
527 return OpenConsoleRequest
->ConsoleHandle
;
532 * @unimplemented (Undocumented)
536 SetConsoleCursor(DWORD Unknown0
,
539 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
540 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
550 SetConsoleDisplayMode(HANDLE hConsoleOutput
,
552 PCOORD lpNewScreenBufferDimensions
)
555 CONSOLE_API_MESSAGE ApiMessage
;
556 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest
= &ApiMessage
.Data
.SetDisplayModeRequest
;
558 SetDisplayModeRequest
->OutputHandle
= hConsoleOutput
;
559 SetDisplayModeRequest
->DisplayMode
= dwFlags
;
560 SetDisplayModeRequest
->NewSBDim
.X
= 0;
561 SetDisplayModeRequest
->NewSBDim
.Y
= 0;
563 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
565 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetDisplayMode
),
566 sizeof(CONSOLE_SETDISPLAYMODE
));
567 if (!NT_SUCCESS(Status
))
569 BaseSetLastNTError(Status
);
573 if (lpNewScreenBufferDimensions
)
574 *lpNewScreenBufferDimensions
= SetDisplayModeRequest
->NewSBDim
;
581 * @unimplemented (Undocumented)
585 SetConsoleFont(DWORD Unknown0
,
588 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
589 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
595 * @implemented (Undocumented)
599 SetConsoleHardwareState(HANDLE hConsoleOutput
,
604 CONSOLE_API_MESSAGE ApiMessage
;
605 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
607 DPRINT1("SetConsoleHardwareState(%d, %d) UNIMPLEMENTED!\n", Flags
, State
);
609 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
610 HardwareStateRequest
->State
= State
;
612 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
614 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetHardwareState
),
615 sizeof(CONSOLE_GETSETHWSTATE
));
616 if (!NT_SUCCESS(Status
))
618 BaseSetLastNTError(Status
);
627 * @unimplemented (Undocumented)
631 SetConsoleKeyShortcuts(DWORD Unknown0
,
636 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
637 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
643 * @unimplemented (Undocumented)
647 SetConsoleMaximumWindowSize(DWORD Unknown0
,
650 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
651 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
657 * @unimplemented (Undocumented)
661 SetConsoleMenuClose(DWORD Unknown0
)
663 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0
);
664 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
670 * @unimplemented (Undocumented)
674 SetConsolePalette(DWORD Unknown0
,
678 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
);
679 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
684 * @unimplemented (Undocumented)
688 ShowConsoleCursor(DWORD Unknown0
,
691 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
692 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
698 * FUNCTION: Checks whether the given handle is a valid console handle.
701 * Handle - Handle to be checked
704 * TRUE: Handle is a valid console handle
705 * FALSE: Handle is not a valid console handle.
707 * STATUS: Officially undocumented
713 VerifyConsoleIoHandle(HANDLE Handle
)
716 CONSOLE_API_MESSAGE ApiMessage
;
718 ApiMessage
.Data
.VerifyHandleRequest
.ConsoleHandle
= Handle
;
720 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
722 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepVerifyIoHandle
),
723 sizeof(CONSOLE_VERIFYHANDLE
));
724 if (!NT_SUCCESS(Status
))
726 BaseSetLastNTError(Status
);
739 WriteConsoleInputVDMA(DWORD Unknown0
,
744 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
745 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
755 WriteConsoleInputVDMW(DWORD Unknown0
,
760 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
761 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
767 * @implemented (Undocumented)
771 CloseConsoleHandle(HANDLE Handle
)
774 CONSOLE_API_MESSAGE ApiMessage
;
776 ApiMessage
.Data
.CloseHandleRequest
.ConsoleHandle
= Handle
;
778 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
780 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCloseHandle
),
781 sizeof(CONSOLE_CLOSEHANDLE
));
782 if (!NT_SUCCESS(Status
))
784 BaseSetLastNTError(Status
);
797 GetStdHandle(DWORD nStdHandle
)
799 * FUNCTION: Get a handle for the standard input, standard output
800 * and a standard error device.
803 * nStdHandle - Specifies the device for which to return the handle.
805 * RETURNS: If the function succeeds, the return value is the handle
806 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
809 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
813 case STD_INPUT_HANDLE
:
814 return Ppb
->StandardInput
;
816 case STD_OUTPUT_HANDLE
:
817 return Ppb
->StandardOutput
;
819 case STD_ERROR_HANDLE
:
820 return Ppb
->StandardError
;
823 SetLastError(ERROR_INVALID_HANDLE
);
824 return INVALID_HANDLE_VALUE
;
833 SetStdHandle(DWORD nStdHandle
,
836 * FUNCTION: Set the handle for the standard input, standard output or
837 * the standard error device.
840 * nStdHandle - Specifies the handle to be set.
841 * hHandle - The handle to set.
843 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
846 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
848 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
852 case STD_INPUT_HANDLE
:
853 Ppb
->StandardInput
= hHandle
;
856 case STD_OUTPUT_HANDLE
:
857 Ppb
->StandardOutput
= hHandle
;
860 case STD_ERROR_HANDLE
:
861 Ppb
->StandardError
= hHandle
;
865 /* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
866 SetLastError(ERROR_INVALID_HANDLE
);
871 /*--------------------------------------------------------------
881 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
882 CONSOLE_API_MESSAGE ApiMessage
;
883 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest
= &ApiMessage
.Data
.AllocConsoleRequest
;
884 PCSR_CAPTURE_BUFFER CaptureBuffer
;
885 LPWSTR AppPath
= NULL
;
888 if (Parameters
->ConsoleHandle
)
890 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
891 SetLastError(ERROR_ACCESS_DENIED
);
895 CaptureBuffer
= CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO
));
896 if (CaptureBuffer
== NULL
)
898 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
899 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
903 CsrAllocateMessagePointer(CaptureBuffer
,
904 sizeof(CONSOLE_START_INFO
),
905 (PVOID
*)&AllocConsoleRequest
->ConsoleStartInfo
);
907 /** Copied from BasepInitConsole **********************************************/
908 InitConsoleInfo(AllocConsoleRequest
->ConsoleStartInfo
);
910 AppPath
= AllocConsoleRequest
->ConsoleStartInfo
->AppPath
;
911 Length
= min(MAX_PATH
, Parameters
->ImagePathName
.Length
/ sizeof(WCHAR
));
912 wcsncpy(AppPath
, Parameters
->ImagePathName
.Buffer
, Length
);
913 AppPath
[Length
] = L
'\0';
914 /******************************************************************************/
916 AllocConsoleRequest
->Console
= NULL
;
917 AllocConsoleRequest
->CtrlDispatcher
= ConsoleControlDispatcher
;
918 AllocConsoleRequest
->PropDispatcher
= PropDialogHandler
;
920 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
922 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAlloc
),
923 sizeof(CONSOLE_ALLOCCONSOLE
));
925 CsrFreeCaptureBuffer(CaptureBuffer
);
927 if (!NT_SUCCESS(Status
))
929 BaseSetLastNTError(Status
);
933 Parameters
->ConsoleHandle
= AllocConsoleRequest
->Console
;
934 SetStdHandle(STD_INPUT_HANDLE
, AllocConsoleRequest
->InputHandle
);
935 SetStdHandle(STD_OUTPUT_HANDLE
, AllocConsoleRequest
->OutputHandle
);
936 SetStdHandle(STD_ERROR_HANDLE
, AllocConsoleRequest
->ErrorHandle
);
938 /* Initialize Console Ctrl Handler */
939 InitConsoleCtrlHandling();
941 InputWaitHandle
= AllocConsoleRequest
->InputWaitHandle
;
947 /*--------------------------------------------------------------
956 // AG: I'm not sure if this is correct (what happens to std handles?)
957 // but I just tried to reverse what AllocConsole() does...
960 CONSOLE_API_MESSAGE ApiMessage
;
962 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
964 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFree
),
965 sizeof(CONSOLE_FREECONSOLE
));
966 if (!NT_SUCCESS(Status
))
968 BaseSetLastNTError(Status
);
972 NtCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
974 CloseHandle(InputWaitHandle
);
975 InputWaitHandle
= INVALID_HANDLE_VALUE
;
981 /*--------------------------------------------------------------
982 * GetConsoleScreenBufferInfo
988 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput
,
989 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
)
992 CONSOLE_API_MESSAGE ApiMessage
;
994 if (lpConsoleScreenBufferInfo
== NULL
)
996 SetLastError(ERROR_INVALID_PARAMETER
);
1000 ApiMessage
.Data
.ScreenBufferInfoRequest
.OutputHandle
= hConsoleOutput
;
1002 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1004 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetScreenBufferInfo
),
1005 sizeof(CONSOLE_GETSCREENBUFFERINFO
));
1006 if (!NT_SUCCESS(Status
))
1008 BaseSetLastNTError(Status
);
1012 *lpConsoleScreenBufferInfo
= ApiMessage
.Data
.ScreenBufferInfoRequest
.Info
;
1018 /*--------------------------------------------------------------
1019 * SetConsoleCursorPosition
1025 SetConsoleCursorPosition(HANDLE hConsoleOutput
,
1026 COORD dwCursorPosition
)
1029 CONSOLE_API_MESSAGE ApiMessage
;
1031 ApiMessage
.Data
.SetCursorPositionRequest
.OutputHandle
= hConsoleOutput
;
1032 ApiMessage
.Data
.SetCursorPositionRequest
.Position
= dwCursorPosition
;
1034 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1036 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorPosition
),
1037 sizeof(CONSOLE_SETCURSORPOSITION
));
1038 if (!NT_SUCCESS(Status
))
1040 BaseSetLastNTError(Status
);
1048 /*--------------------------------------------------------------
1055 GetConsoleMode(HANDLE hConsoleHandle
,
1059 CONSOLE_API_MESSAGE ApiMessage
;
1060 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1064 SetLastError(ERROR_INVALID_PARAMETER
);
1068 ConsoleModeRequest
->ConsoleHandle
= hConsoleHandle
;
1070 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1072 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetMode
),
1073 sizeof(CONSOLE_GETSETCONSOLEMODE
));
1074 if (!NT_SUCCESS(Status
))
1076 BaseSetLastNTError(Status
);
1080 *lpMode
= ConsoleModeRequest
->ConsoleMode
;
1086 /*--------------------------------------------------------------
1087 * GetNumberOfConsoleInputEvents
1093 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput
,
1094 LPDWORD lpNumberOfEvents
)
1097 CONSOLE_API_MESSAGE ApiMessage
;
1098 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest
= &ApiMessage
.Data
.GetNumInputEventsRequest
;
1100 GetNumInputEventsRequest
->InputHandle
= hConsoleInput
;
1101 GetNumInputEventsRequest
->NumInputEvents
= 0;
1103 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1105 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetNumberOfInputEvents
),
1106 sizeof(CONSOLE_GETNUMINPUTEVENTS
));
1107 if (!NT_SUCCESS(Status
))
1109 BaseSetLastNTError(Status
);
1113 if (lpNumberOfEvents
== NULL
)
1115 SetLastError(ERROR_INVALID_ACCESS
);
1119 *lpNumberOfEvents
= GetNumInputEventsRequest
->NumInputEvents
;
1125 /*--------------------------------------------------------------
1126 * GetLargestConsoleWindowSize
1132 GetLargestConsoleWindowSize(HANDLE hConsoleOutput
)
1135 CONSOLE_API_MESSAGE ApiMessage
;
1136 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest
= &ApiMessage
.Data
.GetLargestWindowSizeRequest
;
1138 GetLargestWindowSizeRequest
->OutputHandle
= hConsoleOutput
;
1139 GetLargestWindowSizeRequest
->Size
.X
= 0;
1140 GetLargestWindowSizeRequest
->Size
.Y
= 0;
1142 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1144 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetLargestWindowSize
),
1145 sizeof(CONSOLE_GETLARGESTWINDOWSIZE
));
1146 if (!NT_SUCCESS(Status
))
1148 BaseSetLastNTError(Status
);
1151 DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest
->Size
.X
, GetLargestWindowSizeRequest
->Size
.Y
);
1152 return GetLargestWindowSizeRequest
->Size
;
1156 /*--------------------------------------------------------------
1157 * GetConsoleCursorInfo
1163 GetConsoleCursorInfo(HANDLE hConsoleOutput
,
1164 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)
1167 CONSOLE_API_MESSAGE ApiMessage
;
1169 if (!lpConsoleCursorInfo
)
1171 if (!hConsoleOutput
)
1172 SetLastError(ERROR_INVALID_HANDLE
);
1174 SetLastError(ERROR_INVALID_ACCESS
);
1179 ApiMessage
.Data
.CursorInfoRequest
.OutputHandle
= hConsoleOutput
;
1181 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1183 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCursorInfo
),
1184 sizeof(CONSOLE_GETSETCURSORINFO
));
1185 if (!NT_SUCCESS(Status
))
1187 BaseSetLastNTError(Status
);
1191 *lpConsoleCursorInfo
= ApiMessage
.Data
.CursorInfoRequest
.Info
;
1197 /*--------------------------------------------------------------
1198 * GetNumberOfConsoleMouseButtons
1204 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons
)
1206 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons
);
1207 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1212 /*--------------------------------------------------------------
1219 SetConsoleMode(HANDLE hConsoleHandle
,
1223 CONSOLE_API_MESSAGE ApiMessage
;
1224 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1226 ConsoleModeRequest
->ConsoleHandle
= hConsoleHandle
;
1227 ConsoleModeRequest
->ConsoleMode
= dwMode
;
1229 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1231 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetMode
),
1232 sizeof(CONSOLE_GETSETCONSOLEMODE
));
1233 if (!NT_SUCCESS(Status
))
1235 BaseSetLastNTError(Status
);
1243 /*--------------------------------------------------------------
1244 * SetConsoleActiveScreenBuffer
1250 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput
)
1253 CONSOLE_API_MESSAGE ApiMessage
;
1255 ApiMessage
.Data
.SetScreenBufferRequest
.OutputHandle
= hConsoleOutput
;
1257 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1259 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetActiveScreenBuffer
),
1260 sizeof(CONSOLE_SETACTIVESCREENBUFFER
));
1261 if (!NT_SUCCESS(Status
))
1263 BaseSetLastNTError(Status
);
1271 /*--------------------------------------------------------------
1272 * FlushConsoleInputBuffer
1278 FlushConsoleInputBuffer(HANDLE hConsoleInput
)
1281 CONSOLE_API_MESSAGE ApiMessage
;
1283 ApiMessage
.Data
.FlushInputBufferRequest
.InputHandle
= hConsoleInput
;
1285 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1287 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFlushInputBuffer
),
1288 sizeof(CONSOLE_FLUSHINPUTBUFFER
));
1289 if (!NT_SUCCESS(Status
))
1291 BaseSetLastNTError(Status
);
1299 /*--------------------------------------------------------------
1300 * SetConsoleScreenBufferSize
1306 SetConsoleScreenBufferSize(HANDLE hConsoleOutput
,
1310 CONSOLE_API_MESSAGE ApiMessage
;
1312 ApiMessage
.Data
.SetScreenBufferSizeRequest
.OutputHandle
= hConsoleOutput
;
1313 ApiMessage
.Data
.SetScreenBufferSizeRequest
.Size
= dwSize
;
1315 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1317 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetScreenBufferSize
),
1318 sizeof(CONSOLE_SETSCREENBUFFERSIZE
));
1319 if (!NT_SUCCESS(Status
))
1321 BaseSetLastNTError(Status
);
1329 /*--------------------------------------------------------------
1330 * SetConsoleCursorInfo
1336 SetConsoleCursorInfo(HANDLE hConsoleOutput
,
1337 CONST CONSOLE_CURSOR_INFO
*lpConsoleCursorInfo
)
1340 CONSOLE_API_MESSAGE ApiMessage
;
1342 ApiMessage
.Data
.CursorInfoRequest
.OutputHandle
= hConsoleOutput
;
1343 ApiMessage
.Data
.CursorInfoRequest
.Info
= *lpConsoleCursorInfo
;
1345 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1347 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorInfo
),
1348 sizeof(CONSOLE_GETSETCURSORINFO
));
1349 if (!NT_SUCCESS(Status
))
1351 BaseSetLastNTError(Status
);
1361 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput
,
1362 const SMALL_RECT
*lpScrollRectangle
,
1363 const SMALL_RECT
*lpClipRectangle
,
1364 COORD dwDestinationOrigin
,
1365 const CHAR_INFO
*lpFill
,
1369 CONSOLE_API_MESSAGE ApiMessage
;
1370 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest
= &ApiMessage
.Data
.ScrollScreenBufferRequest
;
1372 ScrollScreenBufferRequest
->OutputHandle
= hConsoleOutput
;
1373 ScrollScreenBufferRequest
->Unicode
= bUnicode
;
1374 ScrollScreenBufferRequest
->ScrollRectangle
= *lpScrollRectangle
;
1376 if (lpClipRectangle
!= NULL
)
1378 ScrollScreenBufferRequest
->UseClipRectangle
= TRUE
;
1379 ScrollScreenBufferRequest
->ClipRectangle
= *lpClipRectangle
;
1383 ScrollScreenBufferRequest
->UseClipRectangle
= FALSE
;
1386 ScrollScreenBufferRequest
->DestinationOrigin
= dwDestinationOrigin
;
1387 ScrollScreenBufferRequest
->Fill
= *lpFill
;
1389 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1391 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepScrollScreenBuffer
),
1392 sizeof(CONSOLE_SCROLLSCREENBUFFER
));
1394 if (!NT_SUCCESS(Status
))
1396 BaseSetLastNTError(Status
);
1404 /*--------------------------------------------------------------
1405 * ScrollConsoleScreenBufferA
1411 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput
,
1412 CONST SMALL_RECT
*lpScrollRectangle
,
1413 CONST SMALL_RECT
*lpClipRectangle
,
1414 COORD dwDestinationOrigin
,
1415 CONST CHAR_INFO
*lpFill
)
1417 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1418 (PSMALL_RECT
)lpScrollRectangle
,
1419 (PSMALL_RECT
)lpClipRectangle
,
1420 dwDestinationOrigin
,
1426 /*--------------------------------------------------------------
1427 * ScrollConsoleScreenBufferW
1433 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput
,
1434 CONST SMALL_RECT
*lpScrollRectangle
,
1435 CONST SMALL_RECT
*lpClipRectangle
,
1436 COORD dwDestinationOrigin
,
1437 CONST CHAR_INFO
*lpFill
)
1439 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1442 dwDestinationOrigin
,
1448 /*--------------------------------------------------------------
1449 * SetConsoleWindowInfo
1455 SetConsoleWindowInfo(HANDLE hConsoleOutput
,
1457 CONST SMALL_RECT
*lpConsoleWindow
)
1460 CONSOLE_API_MESSAGE ApiMessage
;
1461 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest
= &ApiMessage
.Data
.SetWindowInfoRequest
;
1463 if (lpConsoleWindow
== NULL
)
1465 SetLastError(ERROR_INVALID_PARAMETER
);
1469 SetWindowInfoRequest
->OutputHandle
= hConsoleOutput
;
1470 SetWindowInfoRequest
->Absolute
= bAbsolute
;
1471 SetWindowInfoRequest
->WindowRect
= *lpConsoleWindow
;
1473 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1475 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetWindowInfo
),
1476 sizeof(CONSOLE_SETWINDOWINFO
));
1477 if (!NT_SUCCESS(Status
))
1479 BaseSetLastNTError(Status
);
1487 /*--------------------------------------------------------------
1488 * SetConsoleTextAttribute
1494 SetConsoleTextAttribute(HANDLE hConsoleOutput
,
1498 CONSOLE_API_MESSAGE ApiMessage
;
1500 ApiMessage
.Data
.SetTextAttribRequest
.OutputHandle
= hConsoleOutput
;
1501 ApiMessage
.Data
.SetTextAttribRequest
.Attrib
= wAttributes
;
1503 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1505 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTextAttribute
),
1506 sizeof(CONSOLE_SETTEXTATTRIB
));
1507 if (!NT_SUCCESS(Status
))
1509 BaseSetLastNTError(Status
);
1519 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1521 PHANDLER_ROUTINE
* NewCtrlHandlers
= NULL
;
1523 if (HandlerRoutine
== NULL
)
1525 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= TRUE
;
1529 if (NrCtrlHandlers
== NrAllocatedHandlers
)
1531 NewCtrlHandlers
= RtlAllocateHeap(RtlGetProcessHeap(),
1533 (NrCtrlHandlers
+ 4) * sizeof(PHANDLER_ROUTINE
));
1534 if (NewCtrlHandlers
== NULL
)
1536 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1540 memmove(NewCtrlHandlers
, CtrlHandlers
, sizeof(PHANDLER_ROUTINE
) * NrCtrlHandlers
);
1542 if (NrAllocatedHandlers
> 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers
);
1544 CtrlHandlers
= NewCtrlHandlers
;
1545 NrAllocatedHandlers
+= 4;
1548 ASSERT(NrCtrlHandlers
< NrAllocatedHandlers
);
1550 CtrlHandlers
[NrCtrlHandlers
++] = HandlerRoutine
;
1557 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1561 if (HandlerRoutine
== NULL
)
1563 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= FALSE
;
1567 for (i
= 0; i
< NrCtrlHandlers
; i
++)
1569 if (CtrlHandlers
[i
] == HandlerRoutine
)
1571 if (i
< (NrCtrlHandlers
- 1))
1573 memmove(&CtrlHandlers
[i
],
1575 (NrCtrlHandlers
- i
+ 1) * sizeof(PHANDLER_ROUTINE
));
1583 SetLastError(ERROR_INVALID_PARAMETER
);
1593 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
,
1598 RtlEnterCriticalSection(&BaseDllDirectoryLock
);
1601 Ret
= AddConsoleCtrlHandler(HandlerRoutine
);
1605 Ret
= RemoveConsoleCtrlHandler(HandlerRoutine
);
1608 RtlLeaveCriticalSection(&BaseDllDirectoryLock
);
1613 /*--------------------------------------------------------------
1614 * GenerateConsoleCtrlEvent
1620 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent
,
1621 DWORD dwProcessGroupId
)
1624 CONSOLE_API_MESSAGE ApiMessage
;
1626 if (dwCtrlEvent
!= CTRL_C_EVENT
&& dwCtrlEvent
!= CTRL_BREAK_EVENT
)
1628 SetLastError(ERROR_INVALID_PARAMETER
);
1632 ApiMessage
.Data
.GenerateCtrlEventRequest
.Event
= dwCtrlEvent
;
1633 ApiMessage
.Data
.GenerateCtrlEventRequest
.ProcessGroup
= dwProcessGroupId
;
1635 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1637 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGenerateCtrlEvent
),
1638 sizeof(CONSOLE_GENERATECTRLEVENT
));
1639 if (!NT_SUCCESS(Status
))
1641 BaseSetLastNTError(Status
);
1650 IntGetConsoleTitle(LPVOID lpConsoleTitle
, DWORD nSize
, BOOL bUnicode
)
1653 CONSOLE_API_MESSAGE ApiMessage
;
1654 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
1655 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1657 if (nSize
== 0) return 0;
1659 TitleRequest
->Length
= nSize
* (bUnicode
? 1 : sizeof(WCHAR
));
1660 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
1661 if (CaptureBuffer
== NULL
)
1663 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1664 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1668 CsrAllocateMessagePointer(CaptureBuffer
,
1669 TitleRequest
->Length
,
1670 (PVOID
*)&TitleRequest
->Title
);
1672 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1674 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetTitle
),
1675 sizeof(CONSOLE_GETSETCONSOLETITLE
));
1676 if (!NT_SUCCESS(Status
))
1678 CsrFreeCaptureBuffer(CaptureBuffer
);
1679 BaseSetLastNTError(Status
);
1685 if (nSize
>= sizeof(WCHAR
))
1686 wcscpy((LPWSTR
)lpConsoleTitle
, TitleRequest
->Title
);
1690 if (nSize
< TitleRequest
->Length
/ sizeof(WCHAR
) ||
1691 !WideCharToMultiByte(CP_ACP
, // ANSI code page
1692 0, // performance and mapping flags
1693 TitleRequest
->Title
, // address of wide-character string
1694 -1, // number of characters in string
1695 (LPSTR
)lpConsoleTitle
, // address of buffer for new string
1696 nSize
, // size of buffer
1700 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1701 *(LPSTR
)lpConsoleTitle
= '\0';
1702 TitleRequest
->Length
= 0;
1705 CsrFreeCaptureBuffer(CaptureBuffer
);
1707 return TitleRequest
->Length
/ sizeof(WCHAR
);
1711 /*--------------------------------------------------------------
1718 GetConsoleTitleW(LPWSTR lpConsoleTitle
,
1721 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, TRUE
);
1725 /*--------------------------------------------------------------
1732 GetConsoleTitleA(LPSTR lpConsoleTitle
,
1735 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, FALSE
);
1739 /*--------------------------------------------------------------
1746 SetConsoleTitleW(LPCWSTR lpConsoleTitle
)
1749 CONSOLE_API_MESSAGE ApiMessage
;
1750 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
1751 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1753 TitleRequest
->Length
= wcslen(lpConsoleTitle
) * sizeof(WCHAR
);
1755 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
1756 if (CaptureBuffer
== NULL
)
1758 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1759 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1763 CsrCaptureMessageBuffer(CaptureBuffer
,
1764 (PVOID
)lpConsoleTitle
,
1765 TitleRequest
->Length
,
1766 (PVOID
*)&TitleRequest
->Title
);
1768 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1770 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTitle
),
1771 sizeof(CONSOLE_GETSETCONSOLETITLE
));
1773 CsrFreeCaptureBuffer(CaptureBuffer
);
1775 if (!NT_SUCCESS(Status
))
1777 BaseSetLastNTError(Status
);
1785 /*--------------------------------------------------------------
1792 SetConsoleTitleA(LPCSTR lpConsoleTitle
)
1795 ULONG Length
= strlen(lpConsoleTitle
) + 1;
1796 LPWSTR WideTitle
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
1800 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1804 MultiByteToWideChar(CP_ACP
, 0, lpConsoleTitle
, -1, WideTitle
, Length
);
1806 Ret
= SetConsoleTitleW(WideTitle
);
1808 HeapFree(GetProcessHeap(), 0, WideTitle
);
1813 /*--------------------------------------------------------------
1814 * CreateConsoleScreenBuffer
1820 CreateConsoleScreenBuffer(DWORD dwDesiredAccess
,
1822 CONST SECURITY_ATTRIBUTES
*lpSecurityAttributes
,
1824 LPVOID lpScreenBufferData
)
1827 CONSOLE_API_MESSAGE ApiMessage
;
1828 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest
= &ApiMessage
.Data
.CreateScreenBufferRequest
;
1829 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
1830 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo
= /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData
;
1832 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
1833 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) ||
1834 (dwFlags
!= CONSOLE_TEXTMODE_BUFFER
&& dwFlags
!= CONSOLE_GRAPHICS_BUFFER
) )
1836 SetLastError(ERROR_INVALID_PARAMETER
);
1837 return INVALID_HANDLE_VALUE
;
1840 CreateScreenBufferRequest
->ScreenBufferType
= dwFlags
;
1841 CreateScreenBufferRequest
->Access
= dwDesiredAccess
;
1842 CreateScreenBufferRequest
->ShareMode
= dwShareMode
;
1843 CreateScreenBufferRequest
->Inheritable
=
1844 (lpSecurityAttributes
? lpSecurityAttributes
->bInheritHandle
: FALSE
);
1846 if (dwFlags
== CONSOLE_GRAPHICS_BUFFER
)
1848 if (CreateScreenBufferRequest
->Inheritable
|| GraphicsBufferInfo
== NULL
)
1850 SetLastError(ERROR_INVALID_PARAMETER
);
1851 return INVALID_HANDLE_VALUE
;
1854 CreateScreenBufferRequest
->GraphicsBufferInfo
= *GraphicsBufferInfo
;
1856 CaptureBuffer
= CsrAllocateCaptureBuffer(1, GraphicsBufferInfo
->dwBitMapInfoLength
);
1857 if (CaptureBuffer
== NULL
)
1859 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1863 CsrCaptureMessageBuffer(CaptureBuffer
,
1864 (PVOID
)GraphicsBufferInfo
->lpBitMapInfo
,
1865 GraphicsBufferInfo
->dwBitMapInfoLength
,
1866 (PVOID
*)&CreateScreenBufferRequest
->GraphicsBufferInfo
.lpBitMapInfo
);
1869 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1871 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCreateScreenBuffer
),
1872 sizeof(CONSOLE_CREATESCREENBUFFER
));
1875 CsrFreeCaptureBuffer(CaptureBuffer
);
1877 if (!NT_SUCCESS(Status
))
1879 BaseSetLastNTError(Status
);
1880 return INVALID_HANDLE_VALUE
;
1883 if (dwFlags
== CONSOLE_GRAPHICS_BUFFER
&& GraphicsBufferInfo
)
1885 GraphicsBufferInfo
->hMutex
= CreateScreenBufferRequest
->GraphicsBufferInfo
.hMutex
;
1886 GraphicsBufferInfo
->lpBitMap
= CreateScreenBufferRequest
->GraphicsBufferInfo
.lpBitMap
;
1889 return CreateScreenBufferRequest
->OutputHandle
;
1893 /*--------------------------------------------------------------
1903 CONSOLE_API_MESSAGE ApiMessage
;
1905 /* Get the Input Code Page */
1906 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= TRUE
;
1908 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1910 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
1911 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1912 if (!NT_SUCCESS(Status
))
1914 BaseSetLastNTError(Status
);
1918 return ApiMessage
.Data
.ConsoleCPRequest
.CodePage
;
1922 /*--------------------------------------------------------------
1929 SetConsoleCP(UINT wCodePageID
)
1932 CONSOLE_API_MESSAGE ApiMessage
;
1934 /* Set the Input Code Page */
1935 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= TRUE
;
1936 ApiMessage
.Data
.ConsoleCPRequest
.CodePage
= wCodePageID
;
1938 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1940 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
1941 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1942 if (!NT_SUCCESS(Status
))
1944 BaseSetLastNTError(Status
);
1947 return NT_SUCCESS(Status
);
1951 /*--------------------------------------------------------------
1952 * GetConsoleOutputCP
1958 GetConsoleOutputCP(VOID
)
1961 CONSOLE_API_MESSAGE ApiMessage
;
1963 /* Get the Output Code Page */
1964 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= FALSE
;
1966 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1968 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
1969 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1970 if (!NT_SUCCESS(Status
))
1972 BaseSetLastNTError (Status
);
1976 return ApiMessage
.Data
.ConsoleCPRequest
.CodePage
;
1980 /*--------------------------------------------------------------
1981 * SetConsoleOutputCP
1987 SetConsoleOutputCP(UINT wCodePageID
)
1990 CONSOLE_API_MESSAGE ApiMessage
;
1992 /* Set the Output Code Page */
1993 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= FALSE
;
1994 ApiMessage
.Data
.ConsoleCPRequest
.CodePage
= wCodePageID
;
1996 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1998 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
1999 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
2000 if (!NT_SUCCESS(Status
))
2002 BaseSetLastNTError(Status
);
2005 return NT_SUCCESS(Status
);
2009 /*--------------------------------------------------------------
2010 * GetConsoleProcessList
2016 GetConsoleProcessList(LPDWORD lpdwProcessList
,
2017 DWORD dwProcessCount
)
2020 CONSOLE_API_MESSAGE ApiMessage
;
2021 PCONSOLE_GETPROCESSLIST GetProcessListRequest
= &ApiMessage
.Data
.GetProcessListRequest
;
2022 PCSR_CAPTURE_BUFFER CaptureBuffer
;
2025 if (lpdwProcessList
== NULL
|| dwProcessCount
== 0)
2027 SetLastError(ERROR_INVALID_PARAMETER
);
2031 CaptureBuffer
= CsrAllocateCaptureBuffer(1, dwProcessCount
* sizeof(DWORD
));
2032 if (CaptureBuffer
== NULL
)
2034 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2035 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2039 GetProcessListRequest
->nMaxIds
= dwProcessCount
;
2041 CsrAllocateMessagePointer(CaptureBuffer
,
2042 dwProcessCount
* sizeof(DWORD
),
2043 (PVOID
*)&GetProcessListRequest
->pProcessIds
);
2045 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2047 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetProcessList
),
2048 sizeof(CONSOLE_GETPROCESSLIST
));
2049 if (!NT_SUCCESS(Status
))
2051 BaseSetLastNTError (Status
);
2056 nProcesses
= GetProcessListRequest
->nProcessIdsTotal
;
2057 if (dwProcessCount
>= nProcesses
)
2059 memcpy(lpdwProcessList
, GetProcessListRequest
->pProcessIds
, nProcesses
* sizeof(DWORD
));
2063 CsrFreeCaptureBuffer(CaptureBuffer
);
2068 /*--------------------------------------------------------------
2069 * GetConsoleSelectionInfo
2075 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo
)
2078 CONSOLE_API_MESSAGE ApiMessage
;
2080 if (lpConsoleSelectionInfo
== NULL
)
2082 SetLastError(ERROR_INVALID_PARAMETER
);
2086 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2088 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetSelectionInfo
),
2089 sizeof(CONSOLE_GETSELECTIONINFO
));
2090 if (!NT_SUCCESS(Status
))
2092 BaseSetLastNTError(Status
);
2096 *lpConsoleSelectionInfo
= ApiMessage
.Data
.GetSelectionInfoRequest
.Info
;
2101 /*--------------------------------------------------------------
2106 * @note Strongly inspired by AllocConsole.
2110 AttachConsole(DWORD dwProcessId
)
2113 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
2114 CONSOLE_API_MESSAGE ApiMessage
;
2115 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest
= &ApiMessage
.Data
.AttachConsoleRequest
;
2117 if (Parameters
->ConsoleHandle
)
2119 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2120 SetLastError(ERROR_ACCESS_DENIED
);
2124 AttachConsoleRequest
->ProcessId
= dwProcessId
;
2125 AttachConsoleRequest
->CtrlDispatcher
= ConsoleControlDispatcher
;
2126 AttachConsoleRequest
->PropDispatcher
= PropDialogHandler
;
2128 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2130 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAttach
),
2131 sizeof(CONSOLE_ATTACHCONSOLE
));
2132 if (!NT_SUCCESS(Status
))
2134 BaseSetLastNTError(Status
);
2138 Parameters
->ConsoleHandle
= AttachConsoleRequest
->Console
;
2139 SetStdHandle(STD_INPUT_HANDLE
, AttachConsoleRequest
->InputHandle
);
2140 SetStdHandle(STD_OUTPUT_HANDLE
, AttachConsoleRequest
->OutputHandle
);
2141 SetStdHandle(STD_ERROR_HANDLE
, AttachConsoleRequest
->ErrorHandle
);
2143 /* Initialize Console Ctrl Handler */
2144 InitConsoleCtrlHandling();
2146 InputWaitHandle
= AttachConsoleRequest
->InputWaitHandle
;
2152 /*--------------------------------------------------------------
2159 GetConsoleWindow(VOID
)
2162 CONSOLE_API_MESSAGE ApiMessage
;
2164 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2166 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetConsoleWindow
),
2167 sizeof(CONSOLE_GETWINDOW
));
2168 if (!NT_SUCCESS(Status
))
2170 BaseSetLastNTError(Status
);
2174 return ApiMessage
.Data
.GetWindowRequest
.WindowHandle
;
2178 /*--------------------------------------------------------------
2185 SetConsoleIcon(HICON hicon
)
2188 CONSOLE_API_MESSAGE ApiMessage
;
2190 ApiMessage
.Data
.SetIconRequest
.WindowIcon
= hicon
;
2192 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2194 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetIcon
),
2195 sizeof(CONSOLE_SETICON
));
2196 if (!NT_SUCCESS(Status
))
2198 BaseSetLastNTError(Status
);
2202 return NT_SUCCESS(Status
);
2206 /******************************************************************************
2207 * \name SetConsoleInputExeNameW
2208 * \brief Sets the console input file name from a unicode string.
2209 * \param lpInputExeName Pointer to a unicode string with the name.
2210 * \return TRUE if successful, FALSE if unsuccsedful.
2211 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2212 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2216 SetConsoleInputExeNameW(LPCWSTR lpInputExeName
)
2220 if ( !lpInputExeName
||
2221 (lenName
= lstrlenW(lpInputExeName
)) == 0 ||
2222 lenName
> INPUTEXENAME_BUFLEN
- 1 )
2224 /* Fail if string is empty or too long */
2225 SetLastError(ERROR_INVALID_PARAMETER
);
2229 RtlEnterCriticalSection(&ConsoleLock
);
2232 RtlCopyMemory(InputExeName
, lpInputExeName
, lenName
* sizeof(WCHAR
));
2233 InputExeName
[lenName
] = L
'\0';
2237 RtlLeaveCriticalSection(&ConsoleLock
);
2245 /******************************************************************************
2246 * \name SetConsoleInputExeNameA
2247 * \brief Sets the console input file name from an ansi string.
2248 * \param lpInputExeName Pointer to an ansi string with the name.
2249 * \return TRUE if successful, FALSE if unsuccsedful.
2250 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2251 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2255 SetConsoleInputExeNameA(LPCSTR lpInputExeName
)
2257 WCHAR Buffer
[INPUTEXENAME_BUFLEN
];
2258 ANSI_STRING InputExeNameA
;
2259 UNICODE_STRING InputExeNameU
;
2262 RtlInitAnsiString(&InputExeNameA
, lpInputExeName
);
2264 if ( InputExeNameA
.Length
== 0 ||
2265 InputExeNameA
.Length
> INPUTEXENAME_BUFLEN
- 1 )
2267 /* Fail if string is empty or too long */
2268 SetLastError(ERROR_INVALID_PARAMETER
);
2272 InputExeNameU
.Buffer
= Buffer
;
2273 InputExeNameU
.MaximumLength
= sizeof(Buffer
);
2274 InputExeNameU
.Length
= 0;
2276 Status
= RtlAnsiStringToUnicodeString(&InputExeNameU
, &InputExeNameA
, FALSE
);
2277 if (!NT_SUCCESS(Status
))
2279 BaseSetLastNTError(Status
);
2283 return SetConsoleInputExeNameW(InputExeNameU
.Buffer
);
2287 /******************************************************************************
2288 * \name GetConsoleInputExeNameW
2289 * \brief Retrieves the console input file name as unicode string.
2290 * \param nBufferLength Length of the buffer in WCHARs.
2291 * Specify 0 to receive the needed buffer length.
2292 * \param lpBuffer Pointer to a buffer that receives the string.
2293 * \return Needed buffer size if \p nBufferLength is 0.
2294 * Otherwise 1 if successful, 2 if buffer is too small.
2295 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2296 * is not big enough.
2300 GetConsoleInputExeNameW(DWORD nBufferLength
, LPWSTR lpBuffer
)
2302 ULONG lenName
= lstrlenW(InputExeName
);
2304 if (nBufferLength
== 0)
2306 /* Buffer size is requested, return it */
2310 if (lenName
+ 1 > nBufferLength
)
2312 /* Buffer is not large enough! */
2313 SetLastError(ERROR_BUFFER_OVERFLOW
);
2317 RtlEnterCriticalSection(&ConsoleLock
);
2320 RtlCopyMemory(lpBuffer
, InputExeName
, lenName
* sizeof(WCHAR
));
2321 lpBuffer
[lenName
] = '\0';
2325 RtlLeaveCriticalSection(&ConsoleLock
);
2329 /* Success, return 1 */
2334 /******************************************************************************
2335 * \name GetConsoleInputExeNameA
2336 * \brief Retrieves the console input file name as ansi string.
2337 * \param nBufferLength Length of the buffer in CHARs.
2338 * \param lpBuffer Pointer to a buffer that receives the string.
2339 * \return 1 if successful, 2 if buffer is too small.
2340 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2341 * is not big enough. The buffer receives as much characters as fit.
2345 GetConsoleInputExeNameA(DWORD nBufferLength
, LPSTR lpBuffer
)
2347 WCHAR Buffer
[INPUTEXENAME_BUFLEN
];
2349 UNICODE_STRING BufferU
;
2350 ANSI_STRING BufferA
;
2352 /* Get the unicode name */
2353 Ret
= GetConsoleInputExeNameW(sizeof(Buffer
) / sizeof(Buffer
[0]), Buffer
);
2355 /* Initialize strings for conversion */
2356 RtlInitUnicodeString(&BufferU
, Buffer
);
2358 BufferA
.MaximumLength
= (USHORT
)nBufferLength
;
2359 BufferA
.Buffer
= lpBuffer
;
2361 /* Convert unicode name to ansi, copying as much chars as fit */
2362 RtlUnicodeStringToAnsiString(&BufferA
, &BufferU
, FALSE
);
2364 /* Error handling */
2365 if (nBufferLength
<= BufferU
.Length
/ sizeof(WCHAR
))
2367 SetLastError(ERROR_BUFFER_OVERFLOW
);
2376 GetConsoleCharType(HANDLE hConsole
, COORD Coord
, PDWORD Type
)
2384 GetConsoleCursorMode(HANDLE hConsole
, PBOOL pUnknown1
, PBOOL pUnknown2
)
2392 GetConsoleNlsMode(HANDLE hConsole
, LPDWORD lpMode
)
2400 SetConsoleCursorMode(HANDLE hConsole
, BOOL Unknown1
, BOOL Unknown2
)
2408 SetConsoleLocalEUDC(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
, DWORD Unknown4
)
2416 SetConsoleNlsMode(HANDLE hConsole
, DWORD dwMode
)
2424 RegisterConsoleIME(HWND hWnd
, LPDWORD ThreadId
)
2432 RegisterConsoleOS2(BOOL bUnknown
)
2440 SetConsoleOS2OemFormat(BOOL bUnknown
)
2448 UnregisterConsoleIME(VOID
)
2458 BOOL WINAPI
GetConsoleKeyboardLayoutNameA(LPSTR name
)
2467 BOOL WINAPI
GetConsoleKeyboardLayoutNameW(LPWSTR name
)
2478 SetLastConsoleEventActive(VOID
)