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 * PROGRAMMER: 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
);
149 if ((nCode
!= CTRL_C_EVENT
) || (NtCurrentPeb()->ProcessParameters
->ConsoleFlags
!= 1))
151 for (i
= NrCtrlHandlers
; i
> 0; i
--)
154 (CodeAndFlag
& MINLONG
) &&
155 ((nCode
== CTRL_LOGOFF_EVENT
) || (nCode
== CTRL_SHUTDOWN_EVENT
)))
157 DPRINT("Skipping system/service apps\n");
161 if (CtrlHandlers
[i
- 1](nCode
))
165 case CTRL_CLOSE_EVENT
:
166 case CTRL_LOGOFF_EVENT
:
167 case CTRL_SHUTDOWN_EVENT
:
169 nExitCode
= CodeAndFlag
;
177 RtlLeaveCriticalSection(&ConsoleLock
);
178 ExitThread(nExitCode
);
179 return STATUS_SUCCESS
;
184 InitConsoleCtrlHandling(VOID
)
186 /* Initialize Console Ctrl Handler */
187 NrAllocatedHandlers
= NrCtrlHandlers
= 1;
188 CtrlHandlers
= InitialHandler
;
189 CtrlHandlers
[0] = DefaultConsoleCtrlHandler
;
193 /* FUNCTIONS ******************************************************************/
196 IntCheckForConsoleFileName(IN LPCWSTR pszName
,
197 IN DWORD dwDesiredAccess
)
199 LPCWSTR ConsoleName
= pszName
;
200 ULONG DeviceNameInfo
;
203 * Check whether we deal with a DOS device, and if so,
204 * strip the path till the file name.
205 * Therefore, things like \\.\CON or C:\some_path\CONIN$
206 * are transformed into CON or CONIN$, for example.
208 DeviceNameInfo
= RtlIsDosDeviceName_U(pszName
);
209 if (DeviceNameInfo
!= 0)
211 ConsoleName
= (LPCWSTR
)((ULONG_PTR
)ConsoleName
+ ((DeviceNameInfo
>> 16) & 0xFFFF));
214 /* Return a standard console "file" name according to what we passed in parameters */
215 if (_wcsicmp(ConsoleName
, BaseConInputFileName
) == 0)
217 return BaseConInputFileName
;
219 else if (_wcsicmp(ConsoleName
, BaseConOutputFileName
) == 0)
221 return BaseConOutputFileName
;
223 else if (_wcsicmp(ConsoleName
, BaseConFileName
) == 0)
225 if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_READ
)
227 return BaseConInputFileName
;
229 else if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_WRITE
)
231 return BaseConOutputFileName
;
235 /* If we are there, that means that either the file name or the desired access are wrong */
241 * @unimplemented (Undocumented)
245 ConsoleMenuControl(HANDLE hConsole
,
249 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole
, Unknown1
, Unknown2
);
250 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
260 DuplicateConsoleHandle(HANDLE hConsole
,
261 DWORD dwDesiredAccess
,
266 CONSOLE_API_MESSAGE ApiMessage
;
267 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest
= &ApiMessage
.Data
.DuplicateHandleRequest
;
269 if ( (dwOptions
& ~(DUPLICATE_CLOSE_SOURCE
| DUPLICATE_SAME_ACCESS
)) ||
270 (!(dwOptions
& DUPLICATE_SAME_ACCESS
) &&
271 (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
))) )
273 SetLastError (ERROR_INVALID_PARAMETER
);
274 return INVALID_HANDLE_VALUE
;
277 DuplicateHandleRequest
->ConsoleHandle
= hConsole
;
278 DuplicateHandleRequest
->Access
= dwDesiredAccess
;
279 DuplicateHandleRequest
->Inheritable
= bInheritHandle
;
280 DuplicateHandleRequest
->Options
= dwOptions
;
282 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
284 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepDuplicateHandle
),
285 sizeof(CONSOLE_DUPLICATEHANDLE
));
286 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
288 BaseSetLastNTError(Status
);
289 return INVALID_HANDLE_VALUE
;
292 return DuplicateHandleRequest
->ConsoleHandle
;
301 GetConsoleDisplayMode(LPDWORD lpdwMode
)
303 * FUNCTION: Get the console display mode
305 * lpdwMode - Address of variable that receives the current value
307 * STATUS: Undocumented
310 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode
);
311 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
317 * @unimplemented (Undocumented)
321 GetConsoleFontInfo(DWORD Unknown0
,
326 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
327 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
337 GetConsoleFontSize(HANDLE hConsoleOutput
,
340 COORD Empty
= {0, 0};
341 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, nFont
);
342 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
348 * @implemented (Undocumented)
352 GetConsoleHardwareState(HANDLE hConsoleOutput
,
357 CONSOLE_API_MESSAGE ApiMessage
;
358 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
360 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
362 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
364 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetHardwareState
),
365 sizeof(CONSOLE_GETSETHWSTATE
));
366 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
368 BaseSetLastNTError(Status
);
372 *State
= HardwareStateRequest
->State
;
378 * @implemented (Undocumented)
382 GetConsoleInputWaitHandle(VOID
)
384 return InputWaitHandle
;
393 GetCurrentConsoleFont(HANDLE hConsoleOutput
,
395 PCONSOLE_FONT_INFO lpConsoleCurrentFont
)
397 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, bMaximumWindow
, lpConsoleCurrentFont
);
398 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
404 * @unimplemented (Undocumented)
408 GetNumberOfConsoleFonts(VOID
)
410 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
411 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
417 * @unimplemented (Undocumented)
421 InvalidateConsoleDIBits(DWORD Unknown0
,
424 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
425 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
431 * @unimplemented (Undocumented)
435 OpenConsoleW(LPCWSTR wsName
,
436 DWORD dwDesiredAccess
,
440 NTSTATUS Status
= STATUS_SUCCESS
;
441 CONSOLE_API_MESSAGE ApiMessage
;
442 PCONSOLE_OPENCONSOLE OpenConsoleRequest
= &ApiMessage
.Data
.OpenConsoleRequest
;
443 CONSOLE_HANDLE_TYPE HandleType
;
445 if (wsName
&& 0 == _wcsicmp(wsName
, BaseConInputFileName
))
447 HandleType
= HANDLE_INPUT
;
449 else if (wsName
&& 0 == _wcsicmp(wsName
, BaseConOutputFileName
))
451 HandleType
= HANDLE_OUTPUT
;
455 SetLastError(ERROR_INVALID_PARAMETER
);
456 return INVALID_HANDLE_VALUE
;
459 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
460 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) )
462 SetLastError(ERROR_INVALID_PARAMETER
);
463 return INVALID_HANDLE_VALUE
;
466 OpenConsoleRequest
->HandleType
= HandleType
;
467 OpenConsoleRequest
->Access
= dwDesiredAccess
;
468 OpenConsoleRequest
->Inheritable
= bInheritHandle
;
469 OpenConsoleRequest
->ShareMode
= dwShareMode
;
471 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
473 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepOpenConsole
),
474 sizeof(CONSOLE_OPENCONSOLE
));
475 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
477 BaseSetLastNTError(Status
);
478 return INVALID_HANDLE_VALUE
;
481 return OpenConsoleRequest
->ConsoleHandle
;
486 * @unimplemented (Undocumented)
490 SetConsoleCursor(DWORD Unknown0
,
493 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
494 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
504 SetConsoleDisplayMode(HANDLE hOut
,
508 * FUNCTION: Set the console display mode.
510 * hOut - Standard output handle.
511 * dwNewMode - New mode.
512 * lpdwOldMode - Address of a variable that receives the old mode.
515 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut
, dwNewMode
, lpdwOldMode
);
516 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
522 * @unimplemented (Undocumented)
526 SetConsoleFont(DWORD Unknown0
,
529 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
530 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
536 * @implemented (Undocumented)
540 SetConsoleHardwareState(HANDLE hConsoleOutput
,
545 CONSOLE_API_MESSAGE ApiMessage
;
546 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
548 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
549 HardwareStateRequest
->State
= State
;
551 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
553 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetHardwareState
),
554 sizeof(CONSOLE_GETSETHWSTATE
));
555 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
557 BaseSetLastNTError(Status
);
566 * @unimplemented (Undocumented)
570 SetConsoleKeyShortcuts(DWORD Unknown0
,
575 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
576 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
582 * @unimplemented (Undocumented)
586 SetConsoleMaximumWindowSize(DWORD Unknown0
,
589 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
590 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
596 * @unimplemented (Undocumented)
600 SetConsoleMenuClose(DWORD Unknown0
)
602 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0
);
603 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
609 * @unimplemented (Undocumented)
613 SetConsolePalette(DWORD Unknown0
,
617 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
);
618 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
623 * @unimplemented (Undocumented)
627 ShowConsoleCursor(DWORD Unknown0
,
630 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
);
631 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
637 * FUNCTION: Checks whether the given handle is a valid console handle.
640 * Handle - Handle to be checked
643 * TRUE: Handle is a valid console handle
644 * FALSE: Handle is not a valid console handle.
646 * STATUS: Officially undocumented
652 VerifyConsoleIoHandle(HANDLE Handle
)
655 CONSOLE_API_MESSAGE ApiMessage
;
657 ApiMessage
.Data
.VerifyHandleRequest
.ConsoleHandle
= Handle
;
659 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
661 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepVerifyIoHandle
),
662 sizeof(CONSOLE_VERIFYHANDLE
));
663 if (!NT_SUCCESS(Status
))
665 BaseSetLastNTError(Status
);
669 return (BOOL
)NT_SUCCESS(ApiMessage
.Status
);
678 WriteConsoleInputVDMA(DWORD Unknown0
,
683 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
684 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
694 WriteConsoleInputVDMW(DWORD Unknown0
,
699 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
700 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
706 * @implemented (Undocumented)
710 CloseConsoleHandle(HANDLE Handle
)
713 CONSOLE_API_MESSAGE ApiMessage
;
715 ApiMessage
.Data
.CloseHandleRequest
.ConsoleHandle
= Handle
;
717 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
719 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCloseHandle
),
720 sizeof(CONSOLE_CLOSEHANDLE
));
721 if (!NT_SUCCESS(Status
))
723 BaseSetLastNTError(Status
);
736 GetStdHandle(DWORD nStdHandle
)
738 * FUNCTION: Get a handle for the standard input, standard output
739 * and a standard error device.
742 * nStdHandle - Specifies the device for which to return the handle.
744 * RETURNS: If the function succeeds, the return value is the handle
745 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
748 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
752 case STD_INPUT_HANDLE
:
753 return Ppb
->StandardInput
;
755 case STD_OUTPUT_HANDLE
:
756 return Ppb
->StandardOutput
;
758 case STD_ERROR_HANDLE
:
759 return Ppb
->StandardError
;
762 SetLastError(ERROR_INVALID_HANDLE
);
763 return INVALID_HANDLE_VALUE
;
772 SetStdHandle(DWORD nStdHandle
,
775 * FUNCTION: Set the handle for the standard input, standard output or
776 * the standard error device.
779 * nStdHandle - Specifies the handle to be set.
780 * hHandle - The handle to set.
782 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
785 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
787 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
791 case STD_INPUT_HANDLE
:
792 Ppb
->StandardInput
= hHandle
;
795 case STD_OUTPUT_HANDLE
:
796 Ppb
->StandardOutput
= hHandle
;
799 case STD_ERROR_HANDLE
:
800 Ppb
->StandardError
= hHandle
;
804 /* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
805 SetLastError(ERROR_INVALID_HANDLE
);
810 /*--------------------------------------------------------------
820 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
821 CONSOLE_API_MESSAGE ApiMessage
;
822 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest
= &ApiMessage
.Data
.AllocConsoleRequest
;
823 PCSR_CAPTURE_BUFFER CaptureBuffer
;
826 if (Parameters
->ConsoleHandle
)
828 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
829 SetLastError(ERROR_ACCESS_DENIED
);
833 CaptureBuffer
= CsrAllocateCaptureBuffer(2, sizeof(CONSOLE_START_INFO
) +
834 (MAX_PATH
+ 1) * sizeof(WCHAR
));
835 if (CaptureBuffer
== NULL
)
837 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
838 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
842 CsrAllocateMessagePointer(CaptureBuffer
,
843 sizeof(CONSOLE_START_INFO
),
844 (PVOID
*)&AllocConsoleRequest
->ConsoleStartInfo
);
846 CsrAllocateMessagePointer(CaptureBuffer
,
847 (MAX_PATH
+ 1) * sizeof(WCHAR
),
848 (PVOID
*)&AllocConsoleRequest
->AppPath
);
850 /** Copied from BasepInitConsole **********************************************/
851 InitConsoleInfo(AllocConsoleRequest
->ConsoleStartInfo
);
853 Length
= min(MAX_PATH
, Parameters
->ImagePathName
.Length
/ sizeof(WCHAR
));
854 wcsncpy(AllocConsoleRequest
->AppPath
, Parameters
->ImagePathName
.Buffer
, Length
);
855 AllocConsoleRequest
->AppPath
[Length
] = L
'\0';
856 /******************************************************************************/
858 AllocConsoleRequest
->Console
= NULL
;
859 AllocConsoleRequest
->CtrlDispatcher
= ConsoleControlDispatcher
;
860 AllocConsoleRequest
->PropDispatcher
= PropDialogHandler
;
862 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
864 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAlloc
),
865 sizeof(CONSOLE_ALLOCCONSOLE
));
867 CsrFreeCaptureBuffer(CaptureBuffer
);
869 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
871 BaseSetLastNTError(Status
);
875 Parameters
->ConsoleHandle
= AllocConsoleRequest
->Console
;
876 SetStdHandle(STD_INPUT_HANDLE
, AllocConsoleRequest
->InputHandle
);
877 SetStdHandle(STD_OUTPUT_HANDLE
, AllocConsoleRequest
->OutputHandle
);
878 SetStdHandle(STD_ERROR_HANDLE
, AllocConsoleRequest
->ErrorHandle
);
880 /* Initialize Console Ctrl Handler */
881 InitConsoleCtrlHandling();
883 InputWaitHandle
= AllocConsoleRequest
->InputWaitHandle
;
889 /*--------------------------------------------------------------
898 // AG: I'm not sure if this is correct (what happens to std handles?)
899 // but I just tried to reverse what AllocConsole() does...
902 CONSOLE_API_MESSAGE ApiMessage
;
904 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
906 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFree
),
907 sizeof(CONSOLE_FREECONSOLE
));
908 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
910 BaseSetLastNTError(Status
);
914 NtCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
916 CloseHandle(InputWaitHandle
);
917 InputWaitHandle
= INVALID_HANDLE_VALUE
;
923 /*--------------------------------------------------------------
924 * GetConsoleScreenBufferInfo
930 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput
,
931 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
)
934 CONSOLE_API_MESSAGE ApiMessage
;
936 if (lpConsoleScreenBufferInfo
== NULL
)
938 SetLastError(ERROR_INVALID_PARAMETER
);
942 ApiMessage
.Data
.ScreenBufferInfoRequest
.OutputHandle
= hConsoleOutput
;
944 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
946 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetScreenBufferInfo
),
947 sizeof(CONSOLE_GETSCREENBUFFERINFO
));
948 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
950 BaseSetLastNTError(Status
);
954 *lpConsoleScreenBufferInfo
= ApiMessage
.Data
.ScreenBufferInfoRequest
.Info
;
960 /*--------------------------------------------------------------
961 * SetConsoleCursorPosition
967 SetConsoleCursorPosition(HANDLE hConsoleOutput
,
968 COORD dwCursorPosition
)
971 CONSOLE_API_MESSAGE ApiMessage
;
973 ApiMessage
.Data
.SetCursorPositionRequest
.OutputHandle
= hConsoleOutput
;
974 ApiMessage
.Data
.SetCursorPositionRequest
.Position
= dwCursorPosition
;
976 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
978 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorPosition
),
979 sizeof(CONSOLE_SETCURSORPOSITION
));
980 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
982 BaseSetLastNTError(Status
);
990 /*--------------------------------------------------------------
997 GetConsoleMode(HANDLE hConsoleHandle
,
1001 CONSOLE_API_MESSAGE ApiMessage
;
1002 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1004 ConsoleModeRequest
->ConsoleHandle
= hConsoleHandle
;
1006 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1008 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetMode
),
1009 sizeof(CONSOLE_GETSETCONSOLEMODE
));
1010 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1012 BaseSetLastNTError(Status
);
1016 *lpMode
= ConsoleModeRequest
->ConsoleMode
;
1022 /*--------------------------------------------------------------
1023 * GetNumberOfConsoleInputEvents
1029 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput
,
1030 LPDWORD lpNumberOfEvents
)
1033 CONSOLE_API_MESSAGE ApiMessage
;
1034 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest
= &ApiMessage
.Data
.GetNumInputEventsRequest
;
1036 GetNumInputEventsRequest
->InputHandle
= hConsoleInput
;
1037 GetNumInputEventsRequest
->NumInputEvents
= 0;
1039 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1041 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetNumberOfInputEvents
),
1042 sizeof(CONSOLE_GETNUMINPUTEVENTS
));
1043 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1045 BaseSetLastNTError(Status
);
1049 if (lpNumberOfEvents
== NULL
)
1051 SetLastError(ERROR_INVALID_ACCESS
);
1055 *lpNumberOfEvents
= GetNumInputEventsRequest
->NumInputEvents
;
1061 /*--------------------------------------------------------------
1062 * GetLargestConsoleWindowSize
1068 GetLargestConsoleWindowSize(HANDLE hConsoleOutput
)
1070 COORD Coord
= {80,25};
1071 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput
);
1072 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1077 /*--------------------------------------------------------------
1078 * GetConsoleCursorInfo
1084 GetConsoleCursorInfo(HANDLE hConsoleOutput
,
1085 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)
1088 CONSOLE_API_MESSAGE ApiMessage
;
1090 if (!lpConsoleCursorInfo
)
1092 if (!hConsoleOutput
)
1093 SetLastError(ERROR_INVALID_HANDLE
);
1095 SetLastError(ERROR_INVALID_ACCESS
);
1100 ApiMessage
.Data
.CursorInfoRequest
.OutputHandle
= hConsoleOutput
;
1102 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1104 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCursorInfo
),
1105 sizeof(CONSOLE_GETSETCURSORINFO
));
1106 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1108 BaseSetLastNTError(Status
);
1112 *lpConsoleCursorInfo
= ApiMessage
.Data
.CursorInfoRequest
.Info
;
1118 /*--------------------------------------------------------------
1119 * GetNumberOfConsoleMouseButtons
1125 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons
)
1127 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons
);
1128 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1133 /*--------------------------------------------------------------
1140 SetConsoleMode(HANDLE hConsoleHandle
,
1144 CONSOLE_API_MESSAGE ApiMessage
;
1145 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1147 ConsoleModeRequest
->ConsoleHandle
= hConsoleHandle
;
1148 ConsoleModeRequest
->ConsoleMode
= dwMode
;
1150 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1152 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetMode
),
1153 sizeof(CONSOLE_GETSETCONSOLEMODE
));
1154 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1156 BaseSetLastNTError(Status
);
1164 /*--------------------------------------------------------------
1165 * SetConsoleActiveScreenBuffer
1171 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput
)
1174 CONSOLE_API_MESSAGE ApiMessage
;
1176 ApiMessage
.Data
.SetScreenBufferRequest
.OutputHandle
= hConsoleOutput
;
1178 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1180 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetActiveScreenBuffer
),
1181 sizeof(CONSOLE_SETACTIVESCREENBUFFER
));
1182 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1184 BaseSetLastNTError(Status
);
1192 /*--------------------------------------------------------------
1193 * FlushConsoleInputBuffer
1199 FlushConsoleInputBuffer(HANDLE hConsoleInput
)
1202 CONSOLE_API_MESSAGE ApiMessage
;
1204 ApiMessage
.Data
.FlushInputBufferRequest
.InputHandle
= hConsoleInput
;
1206 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1208 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFlushInputBuffer
),
1209 sizeof(CONSOLE_FLUSHINPUTBUFFER
));
1210 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1212 BaseSetLastNTError(Status
);
1220 /*--------------------------------------------------------------
1221 * SetConsoleScreenBufferSize
1227 SetConsoleScreenBufferSize(HANDLE hConsoleOutput
,
1231 CONSOLE_API_MESSAGE ApiMessage
;
1233 ApiMessage
.Data
.SetScreenBufferSizeRequest
.OutputHandle
= hConsoleOutput
;
1234 ApiMessage
.Data
.SetScreenBufferSizeRequest
.Size
= dwSize
;
1236 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1238 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetScreenBufferSize
),
1239 sizeof(CONSOLE_SETSCREENBUFFERSIZE
));
1240 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1242 BaseSetLastNTError(Status
);
1250 /*--------------------------------------------------------------
1251 * SetConsoleCursorInfo
1257 SetConsoleCursorInfo(HANDLE hConsoleOutput
,
1258 CONST CONSOLE_CURSOR_INFO
*lpConsoleCursorInfo
)
1261 CONSOLE_API_MESSAGE ApiMessage
;
1263 ApiMessage
.Data
.CursorInfoRequest
.OutputHandle
= hConsoleOutput
;
1264 ApiMessage
.Data
.CursorInfoRequest
.Info
= *lpConsoleCursorInfo
;
1266 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1268 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorInfo
),
1269 sizeof(CONSOLE_GETSETCURSORINFO
));
1270 if(!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1272 BaseSetLastNTError(Status
);
1282 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput
,
1283 const SMALL_RECT
*lpScrollRectangle
,
1284 const SMALL_RECT
*lpClipRectangle
,
1285 COORD dwDestinationOrigin
,
1286 const CHAR_INFO
*lpFill
,
1290 CONSOLE_API_MESSAGE ApiMessage
;
1291 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest
= &ApiMessage
.Data
.ScrollScreenBufferRequest
;
1293 ScrollScreenBufferRequest
->OutputHandle
= hConsoleOutput
;
1294 ScrollScreenBufferRequest
->Unicode
= bUnicode
;
1295 ScrollScreenBufferRequest
->ScrollRectangle
= *lpScrollRectangle
;
1297 if (lpClipRectangle
!= NULL
)
1299 ScrollScreenBufferRequest
->UseClipRectangle
= TRUE
;
1300 ScrollScreenBufferRequest
->ClipRectangle
= *lpClipRectangle
;
1304 ScrollScreenBufferRequest
->UseClipRectangle
= FALSE
;
1307 ScrollScreenBufferRequest
->DestinationOrigin
= dwDestinationOrigin
;
1308 ScrollScreenBufferRequest
->Fill
= *lpFill
;
1310 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1312 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepScrollScreenBuffer
),
1313 sizeof(CONSOLE_SCROLLSCREENBUFFER
));
1315 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1317 BaseSetLastNTError(Status
);
1325 /*--------------------------------------------------------------
1326 * ScrollConsoleScreenBufferA
1332 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput
,
1333 CONST SMALL_RECT
*lpScrollRectangle
,
1334 CONST SMALL_RECT
*lpClipRectangle
,
1335 COORD dwDestinationOrigin
,
1336 CONST CHAR_INFO
*lpFill
)
1338 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1339 (PSMALL_RECT
)lpScrollRectangle
,
1340 (PSMALL_RECT
)lpClipRectangle
,
1341 dwDestinationOrigin
,
1347 /*--------------------------------------------------------------
1348 * ScrollConsoleScreenBufferW
1354 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput
,
1355 CONST SMALL_RECT
*lpScrollRectangle
,
1356 CONST SMALL_RECT
*lpClipRectangle
,
1357 COORD dwDestinationOrigin
,
1358 CONST CHAR_INFO
*lpFill
)
1360 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1363 dwDestinationOrigin
,
1369 /*--------------------------------------------------------------
1370 * SetConsoleWindowInfo
1376 SetConsoleWindowInfo(HANDLE hConsoleOutput
,
1378 CONST SMALL_RECT
*lpConsoleWindow
)
1380 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, bAbsolute
, lpConsoleWindow
);
1381 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1386 /*--------------------------------------------------------------
1387 * SetConsoleTextAttribute
1393 SetConsoleTextAttribute(HANDLE hConsoleOutput
,
1397 CONSOLE_API_MESSAGE ApiMessage
;
1399 ApiMessage
.Data
.SetTextAttribRequest
.OutputHandle
= hConsoleOutput
;
1400 ApiMessage
.Data
.SetTextAttribRequest
.Attrib
= wAttributes
;
1402 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1404 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTextAttribute
),
1405 sizeof(CONSOLE_SETTEXTATTRIB
));
1406 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1408 BaseSetLastNTError(Status
);
1418 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1420 PHANDLER_ROUTINE
* NewCtrlHandlers
= NULL
;
1422 if (HandlerRoutine
== NULL
)
1424 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= TRUE
;
1428 if (NrCtrlHandlers
== NrAllocatedHandlers
)
1430 NewCtrlHandlers
= RtlAllocateHeap(RtlGetProcessHeap(),
1432 (NrCtrlHandlers
+ 4) * sizeof(PHANDLER_ROUTINE
));
1433 if (NewCtrlHandlers
== NULL
)
1435 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1439 memmove(NewCtrlHandlers
, CtrlHandlers
, sizeof(PHANDLER_ROUTINE
) * NrCtrlHandlers
);
1441 if (NrAllocatedHandlers
> 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers
);
1443 CtrlHandlers
= NewCtrlHandlers
;
1444 NrAllocatedHandlers
+= 4;
1447 ASSERT(NrCtrlHandlers
< NrAllocatedHandlers
);
1449 CtrlHandlers
[NrCtrlHandlers
++] = HandlerRoutine
;
1456 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1460 if (HandlerRoutine
== NULL
)
1462 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= FALSE
;
1466 for (i
= 0; i
< NrCtrlHandlers
; i
++)
1468 if (CtrlHandlers
[i
] == HandlerRoutine
)
1470 if (i
< (NrCtrlHandlers
- 1))
1472 memmove(&CtrlHandlers
[i
],
1474 (NrCtrlHandlers
- i
+ 1) * sizeof(PHANDLER_ROUTINE
));
1482 SetLastError(ERROR_INVALID_PARAMETER
);
1492 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
,
1497 RtlEnterCriticalSection(&BaseDllDirectoryLock
);
1500 Ret
= AddConsoleCtrlHandler(HandlerRoutine
);
1504 Ret
= RemoveConsoleCtrlHandler(HandlerRoutine
);
1507 RtlLeaveCriticalSection(&BaseDllDirectoryLock
);
1512 /*--------------------------------------------------------------
1513 * GenerateConsoleCtrlEvent
1519 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent
,
1520 DWORD dwProcessGroupId
)
1523 CONSOLE_API_MESSAGE ApiMessage
;
1525 if (dwCtrlEvent
!= CTRL_C_EVENT
&& dwCtrlEvent
!= CTRL_BREAK_EVENT
)
1527 SetLastError(ERROR_INVALID_PARAMETER
);
1531 ApiMessage
.Data
.GenerateCtrlEventRequest
.Event
= dwCtrlEvent
;
1532 ApiMessage
.Data
.GenerateCtrlEventRequest
.ProcessGroup
= dwProcessGroupId
;
1534 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1536 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGenerateCtrlEvent
),
1537 sizeof(CONSOLE_GENERATECTRLEVENT
));
1538 if(!NT_SUCCESS(Status
) || !(NT_SUCCESS(Status
= ApiMessage
.Status
)))
1540 BaseSetLastNTError(Status
);
1549 IntGetConsoleTitle(LPVOID lpConsoleTitle
, DWORD nSize
, BOOL bUnicode
)
1552 CONSOLE_API_MESSAGE ApiMessage
;
1553 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
1554 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1556 if (nSize
== 0) return 0;
1558 TitleRequest
->Length
= nSize
* (bUnicode
? 1 : sizeof(WCHAR
));
1559 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
1560 if (CaptureBuffer
== NULL
)
1562 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1563 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1567 CsrAllocateMessagePointer(CaptureBuffer
,
1568 TitleRequest
->Length
,
1569 (PVOID
*)&TitleRequest
->Title
);
1571 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1573 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetTitle
),
1574 sizeof(CONSOLE_GETSETCONSOLETITLE
));
1575 if (!NT_SUCCESS(Status
) || !(NT_SUCCESS(Status
= ApiMessage
.Status
)))
1577 CsrFreeCaptureBuffer(CaptureBuffer
);
1578 BaseSetLastNTError(Status
);
1584 if (nSize
>= sizeof(WCHAR
))
1585 wcscpy((LPWSTR
)lpConsoleTitle
, TitleRequest
->Title
);
1589 if (nSize
< TitleRequest
->Length
/ sizeof(WCHAR
) ||
1590 !WideCharToMultiByte(CP_ACP
, // ANSI code page
1591 0, // performance and mapping flags
1592 TitleRequest
->Title
, // address of wide-character string
1593 -1, // number of characters in string
1594 (LPSTR
)lpConsoleTitle
, // address of buffer for new string
1595 nSize
, // size of buffer
1599 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1600 *(LPSTR
)lpConsoleTitle
= '\0';
1601 TitleRequest
->Length
= 0;
1604 CsrFreeCaptureBuffer(CaptureBuffer
);
1606 return TitleRequest
->Length
/ sizeof(WCHAR
);
1610 /*--------------------------------------------------------------
1617 GetConsoleTitleW(LPWSTR lpConsoleTitle
,
1620 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, TRUE
);
1624 /*--------------------------------------------------------------
1631 GetConsoleTitleA(LPSTR lpConsoleTitle
,
1634 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, FALSE
);
1638 /*--------------------------------------------------------------
1645 SetConsoleTitleW(LPCWSTR lpConsoleTitle
)
1648 CONSOLE_API_MESSAGE ApiMessage
;
1649 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
1650 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1652 TitleRequest
->Length
= wcslen(lpConsoleTitle
) * sizeof(WCHAR
);
1654 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
1655 if (CaptureBuffer
== NULL
)
1657 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1658 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1662 CsrCaptureMessageBuffer(CaptureBuffer
,
1663 (PVOID
)lpConsoleTitle
,
1664 TitleRequest
->Length
,
1665 (PVOID
*)&TitleRequest
->Title
);
1667 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1669 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTitle
),
1670 sizeof(CONSOLE_GETSETCONSOLETITLE
));
1672 CsrFreeCaptureBuffer(CaptureBuffer
);
1674 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1676 BaseSetLastNTError(Status
);
1684 /*--------------------------------------------------------------
1691 SetConsoleTitleA(LPCSTR lpConsoleTitle
)
1694 ULONG Length
= strlen(lpConsoleTitle
) + 1;
1695 LPWSTR WideTitle
= HeapAlloc(GetProcessHeap(), 0, Length
* sizeof(WCHAR
));
1699 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1703 MultiByteToWideChar(CP_ACP
, 0, lpConsoleTitle
, -1, WideTitle
, Length
);
1705 Ret
= SetConsoleTitleW(WideTitle
);
1707 HeapFree(GetProcessHeap(), 0, WideTitle
);
1712 /*--------------------------------------------------------------
1713 * CreateConsoleScreenBuffer
1719 CreateConsoleScreenBuffer(DWORD dwDesiredAccess
,
1721 CONST SECURITY_ATTRIBUTES
*lpSecurityAttributes
,
1723 LPVOID lpScreenBufferData
)
1726 CONSOLE_API_MESSAGE ApiMessage
;
1728 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
1729 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) ||
1730 (dwFlags
!= CONSOLE_TEXTMODE_BUFFER
) )
1732 SetLastError(ERROR_INVALID_PARAMETER
);
1733 return INVALID_HANDLE_VALUE
;
1736 ApiMessage
.Data
.CreateScreenBufferRequest
.Access
= dwDesiredAccess
;
1737 ApiMessage
.Data
.CreateScreenBufferRequest
.ShareMode
= dwShareMode
;
1738 ApiMessage
.Data
.CreateScreenBufferRequest
.Inheritable
=
1739 (lpSecurityAttributes
? lpSecurityAttributes
->bInheritHandle
: FALSE
);
1741 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1743 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCreateScreenBuffer
),
1744 sizeof(CONSOLE_CREATESCREENBUFFER
));
1745 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1747 BaseSetLastNTError(Status
);
1748 return INVALID_HANDLE_VALUE
;
1751 return ApiMessage
.Data
.CreateScreenBufferRequest
.OutputHandle
;
1755 /*--------------------------------------------------------------
1765 CONSOLE_API_MESSAGE ApiMessage
;
1767 /* Get the Input Code Page */
1768 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= TRUE
;
1770 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1772 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
1773 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1774 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1776 BaseSetLastNTError(Status
);
1780 return ApiMessage
.Data
.ConsoleCPRequest
.CodePage
;
1784 /*--------------------------------------------------------------
1791 SetConsoleCP(UINT wCodePageID
)
1794 CONSOLE_API_MESSAGE ApiMessage
;
1796 /* Set the Input Code Page */
1797 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= TRUE
;
1798 ApiMessage
.Data
.ConsoleCPRequest
.CodePage
= wCodePageID
;
1800 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1802 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
1803 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1804 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1806 BaseSetLastNTError(Status
);
1809 return NT_SUCCESS(Status
);
1813 /*--------------------------------------------------------------
1814 * GetConsoleOutputCP
1820 GetConsoleOutputCP(VOID
)
1823 CONSOLE_API_MESSAGE ApiMessage
;
1825 /* Get the Output Code Page */
1826 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= FALSE
;
1828 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1830 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
1831 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1832 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1834 BaseSetLastNTError (Status
);
1838 return ApiMessage
.Data
.ConsoleCPRequest
.CodePage
;
1842 /*--------------------------------------------------------------
1843 * SetConsoleOutputCP
1849 SetConsoleOutputCP(UINT wCodePageID
)
1852 CONSOLE_API_MESSAGE ApiMessage
;
1854 /* Set the Output Code Page */
1855 ApiMessage
.Data
.ConsoleCPRequest
.InputCP
= FALSE
;
1856 ApiMessage
.Data
.ConsoleCPRequest
.CodePage
= wCodePageID
;
1858 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1860 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
1861 sizeof(CONSOLE_GETSETINPUTOUTPUTCP
));
1862 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1864 BaseSetLastNTError(Status
);
1867 return NT_SUCCESS(Status
);
1871 /*--------------------------------------------------------------
1872 * GetConsoleProcessList
1878 GetConsoleProcessList(LPDWORD lpdwProcessList
,
1879 DWORD dwProcessCount
)
1882 CONSOLE_API_MESSAGE ApiMessage
;
1883 PCONSOLE_GETPROCESSLIST GetProcessListRequest
= &ApiMessage
.Data
.GetProcessListRequest
;
1884 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1887 if (lpdwProcessList
== NULL
|| dwProcessCount
== 0)
1889 SetLastError(ERROR_INVALID_PARAMETER
);
1893 CaptureBuffer
= CsrAllocateCaptureBuffer(1, dwProcessCount
* sizeof(DWORD
));
1894 if (CaptureBuffer
== NULL
)
1896 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1897 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1901 GetProcessListRequest
->nMaxIds
= dwProcessCount
;
1903 CsrAllocateMessagePointer(CaptureBuffer
,
1904 dwProcessCount
* sizeof(DWORD
),
1905 (PVOID
*)&GetProcessListRequest
->pProcessIds
);
1907 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1909 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetProcessList
),
1910 sizeof(CONSOLE_GETPROCESSLIST
));
1911 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1913 BaseSetLastNTError (Status
);
1918 nProcesses
= GetProcessListRequest
->nProcessIdsTotal
;
1919 if (dwProcessCount
>= nProcesses
)
1921 memcpy(lpdwProcessList
, GetProcessListRequest
->pProcessIds
, nProcesses
* sizeof(DWORD
));
1925 CsrFreeCaptureBuffer(CaptureBuffer
);
1930 /*--------------------------------------------------------------
1931 * GetConsoleSelectionInfo
1937 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo
)
1940 CONSOLE_API_MESSAGE ApiMessage
;
1942 if (lpConsoleSelectionInfo
== NULL
)
1944 SetLastError(ERROR_INVALID_PARAMETER
);
1948 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1950 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetSelectionInfo
),
1951 sizeof(CONSOLE_GETSELECTIONINFO
));
1952 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1954 BaseSetLastNTError(Status
);
1958 *lpConsoleSelectionInfo
= ApiMessage
.Data
.GetSelectionInfoRequest
.Info
;
1963 /*--------------------------------------------------------------
1968 * @note Strongly inspired by AllocConsole.
1972 AttachConsole(DWORD dwProcessId
)
1975 PRTL_USER_PROCESS_PARAMETERS Parameters
= NtCurrentPeb()->ProcessParameters
;
1976 CONSOLE_API_MESSAGE ApiMessage
;
1977 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest
= &ApiMessage
.Data
.AttachConsoleRequest
;
1979 if (Parameters
->ConsoleHandle
)
1981 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
1982 SetLastError(ERROR_ACCESS_DENIED
);
1986 AttachConsoleRequest
->ProcessId
= dwProcessId
;
1987 AttachConsoleRequest
->CtrlDispatcher
= ConsoleControlDispatcher
;
1988 AttachConsoleRequest
->PropDispatcher
= PropDialogHandler
;
1990 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1992 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAttach
),
1993 sizeof(CONSOLE_ATTACHCONSOLE
));
1994 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
1996 BaseSetLastNTError(Status
);
2000 Parameters
->ConsoleHandle
= AttachConsoleRequest
->Console
;
2001 SetStdHandle(STD_INPUT_HANDLE
, AttachConsoleRequest
->InputHandle
);
2002 SetStdHandle(STD_OUTPUT_HANDLE
, AttachConsoleRequest
->OutputHandle
);
2003 SetStdHandle(STD_ERROR_HANDLE
, AttachConsoleRequest
->ErrorHandle
);
2005 /* Initialize Console Ctrl Handler */
2006 InitConsoleCtrlHandling();
2008 InputWaitHandle
= AttachConsoleRequest
->InputWaitHandle
;
2014 /*--------------------------------------------------------------
2021 GetConsoleWindow(VOID
)
2024 CONSOLE_API_MESSAGE ApiMessage
;
2026 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2028 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetConsoleWindow
),
2029 sizeof(CONSOLE_GETWINDOW
));
2030 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
2032 BaseSetLastNTError(Status
);
2036 return ApiMessage
.Data
.GetWindowRequest
.WindowHandle
;
2040 /*--------------------------------------------------------------
2047 SetConsoleIcon(HICON hicon
)
2050 CONSOLE_API_MESSAGE ApiMessage
;
2052 ApiMessage
.Data
.SetIconRequest
.WindowIcon
= hicon
;
2054 Status
= CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2056 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetIcon
),
2057 sizeof(CONSOLE_SETICON
));
2058 if (!NT_SUCCESS(Status
) || !NT_SUCCESS(Status
= ApiMessage
.Status
))
2060 BaseSetLastNTError(Status
);
2064 return NT_SUCCESS(Status
);
2068 /******************************************************************************
2069 * \name SetConsoleInputExeNameW
2070 * \brief Sets the console input file name from a unicode string.
2071 * \param lpInputExeName Pointer to a unicode string with the name.
2072 * \return TRUE if successful, FALSE if unsuccsedful.
2073 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2074 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2078 SetConsoleInputExeNameW(LPCWSTR lpInputExeName
)
2082 if ( !lpInputExeName
||
2083 (lenName
= lstrlenW(lpInputExeName
)) == 0 ||
2084 lenName
> INPUTEXENAME_BUFLEN
- 1 )
2086 /* Fail if string is empty or too long */
2087 SetLastError(ERROR_INVALID_PARAMETER
);
2091 RtlEnterCriticalSection(&ConsoleLock
);
2094 RtlCopyMemory(InputExeName
, lpInputExeName
, lenName
* sizeof(WCHAR
));
2095 InputExeName
[lenName
] = L
'\0';
2099 RtlLeaveCriticalSection(&ConsoleLock
);
2107 /******************************************************************************
2108 * \name SetConsoleInputExeNameA
2109 * \brief Sets the console input file name from an ansi string.
2110 * \param lpInputExeName Pointer to an ansi string with the name.
2111 * \return TRUE if successful, FALSE if unsuccsedful.
2112 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2113 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2117 SetConsoleInputExeNameA(LPCSTR lpInputExeName
)
2119 WCHAR Buffer
[INPUTEXENAME_BUFLEN
];
2120 ANSI_STRING InputExeNameA
;
2121 UNICODE_STRING InputExeNameU
;
2124 RtlInitAnsiString(&InputExeNameA
, lpInputExeName
);
2126 if ( InputExeNameA
.Length
== 0 ||
2127 InputExeNameA
.Length
> INPUTEXENAME_BUFLEN
- 1 )
2129 /* Fail if string is empty or too long */
2130 SetLastError(ERROR_INVALID_PARAMETER
);
2134 InputExeNameU
.Buffer
= Buffer
;
2135 InputExeNameU
.MaximumLength
= sizeof(Buffer
);
2136 InputExeNameU
.Length
= 0;
2138 Status
= RtlAnsiStringToUnicodeString(&InputExeNameU
, &InputExeNameA
, FALSE
);
2139 if (!NT_SUCCESS(Status
))
2141 BaseSetLastNTError(Status
);
2145 return SetConsoleInputExeNameW(InputExeNameU
.Buffer
);
2149 /******************************************************************************
2150 * \name GetConsoleInputExeNameW
2151 * \brief Retrieves the console input file name as unicode string.
2152 * \param nBufferLength Length of the buffer in WCHARs.
2153 * Specify 0 to recieve the needed buffer length.
2154 * \param lpBuffer Pointer to a buffer that recieves the string.
2155 * \return Needed buffer size if \p nBufferLength is 0.
2156 * Otherwise 1 if successful, 2 if buffer is too small.
2157 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2158 * is not big enough.
2162 GetConsoleInputExeNameW(DWORD nBufferLength
, LPWSTR lpBuffer
)
2164 int lenName
= lstrlenW(InputExeName
);
2166 if (nBufferLength
== 0)
2168 /* Buffer size is requested, return it */
2172 if (lenName
+ 1 > nBufferLength
)
2174 /* Buffer is not large enough! */
2175 SetLastError(ERROR_BUFFER_OVERFLOW
);
2179 RtlEnterCriticalSection(&ConsoleLock
);
2182 RtlCopyMemory(lpBuffer
, InputExeName
, lenName
* sizeof(WCHAR
));
2183 lpBuffer
[lenName
] = '\0';
2187 RtlLeaveCriticalSection(&ConsoleLock
);
2191 /* Success, return 1 */
2196 /******************************************************************************
2197 * \name GetConsoleInputExeNameA
2198 * \brief Retrieves the console input file name as ansi string.
2199 * \param nBufferLength Length of the buffer in CHARs.
2200 * \param lpBuffer Pointer to a buffer that recieves the string.
2201 * \return 1 if successful, 2 if buffer is too small.
2202 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2203 * is not big enough. The buffer recieves as much characters as fit.
2207 GetConsoleInputExeNameA(DWORD nBufferLength
, LPSTR lpBuffer
)
2209 WCHAR Buffer
[INPUTEXENAME_BUFLEN
];
2211 UNICODE_STRING BufferU
;
2212 ANSI_STRING BufferA
;
2214 /* Get the unicode name */
2215 Ret
= GetConsoleInputExeNameW(sizeof(Buffer
) / sizeof(Buffer
[0]), Buffer
);
2217 /* Initialize strings for conversion */
2218 RtlInitUnicodeString(&BufferU
, Buffer
);
2220 BufferA
.MaximumLength
= nBufferLength
;
2221 BufferA
.Buffer
= lpBuffer
;
2223 /* Convert unicode name to ansi, copying as much chars as fit */
2224 RtlUnicodeStringToAnsiString(&BufferA
, &BufferU
, FALSE
);
2226 /* Error handling */
2227 if (nBufferLength
<= BufferU
.Length
/ sizeof(WCHAR
))
2229 SetLastError(ERROR_BUFFER_OVERFLOW
);
2238 GetConsoleCharType(HANDLE hConsole
, COORD Coord
, PDWORD Type
)
2246 GetConsoleCursorMode(HANDLE hConsole
, PBOOL pUnknown1
, PBOOL pUnknown2
)
2254 GetConsoleNlsMode(HANDLE hConsole
, LPDWORD lpMode
)
2262 SetConsoleCursorMode(HANDLE hConsole
, BOOL Unknown1
, BOOL Unknown2
)
2270 SetConsoleLocalEUDC(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
, DWORD Unknown4
)
2278 SetConsoleNlsMode(HANDLE hConsole
, DWORD dwMode
)
2286 RegisterConsoleIME(HWND hWnd
, LPDWORD ThreadId
)
2294 RegisterConsoleOS2(BOOL bUnknown
)
2302 SetConsoleOS2OemFormat(BOOL bUnknown
)
2310 UnregisterConsoleIME(VOID
)
2320 BOOL WINAPI
GetConsoleKeyboardLayoutNameA(LPSTR name
)
2329 BOOL WINAPI
GetConsoleKeyboardLayoutNameW(LPWSTR name
)
2340 SetLastConsoleEventActive(VOID
)