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 <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
18 /* GLOBALS ********************************************************************/
20 extern RTL_CRITICAL_SECTION ConsoleLock
;
21 extern BOOLEAN ConsoleInitialized
;
23 /* Console reserved "file" names */
24 static LPCWSTR BaseConFileName
= CONSOLE_FILE_NAME
;
25 static LPCWSTR BaseConInputFileName
= CONSOLE_INPUT_FILE_NAME
;
26 static LPCWSTR BaseConOutputFileName
= CONSOLE_OUTPUT_FILE_NAME
;
28 /* Console Control handling */
29 static PHANDLER_ROUTINE InitialHandler
[1];
30 static PHANDLER_ROUTINE
* CtrlHandlers
;
31 static ULONG NrCtrlHandlers
;
32 static ULONG NrAllocatedHandlers
;
33 static BOOLEAN LastCloseNotify
= FALSE
;
35 extern BOOL WINAPI
IsDebuggerPresent(VOID
);
37 /* Console Input facilities */
38 HANDLE InputWaitHandle
= INVALID_HANDLE_VALUE
;
40 #define EXENAME_LENGTH 255 + 1
41 static RTL_CRITICAL_SECTION ExeNameLock
;
42 static BOOLEAN ExeNameInitialized
;
43 static WCHAR ExeNameBuffer
[EXENAME_LENGTH
]; // NULL-terminated
44 static USHORT ExeNameLength
; // Count in number of characters without NULL
45 static WCHAR StartDirBuffer
[MAX_PATH
+ 1]; // NULL-terminated
46 static USHORT StartDirLength
; // Count in number of characters without NULL
49 /* Default Console Control Handler ********************************************/
53 DefaultConsoleCtrlHandler(DWORD Event
)
55 DPRINT("Default handler called: %lx\n", Event
);
59 DPRINT("Ctrl-C Event\n");
62 case CTRL_BREAK_EVENT
:
63 DPRINT("Ctrl-Break Event\n");
66 case CTRL_CLOSE_EVENT
:
67 DPRINT("Ctrl Close Event\n");
70 case CTRL_LAST_CLOSE_EVENT
:
71 DPRINT("Ctrl Last Close Event\n");
74 case CTRL_LOGOFF_EVENT
:
75 DPRINT("Ctrl Logoff Event\n");
78 case CTRL_SHUTDOWN_EVENT
:
79 DPRINT("Ctrl Shutdown Event\n");
83 ExitProcess(CONTROL_C_EXIT
);
89 ConsoleControlDispatcher(IN LPVOID lpThreadParameter
)
92 DWORD CodeAndFlag
= PtrToUlong(lpThreadParameter
);
93 DWORD nCode
= CodeAndFlag
& MAXLONG
;
95 EXCEPTION_RECORD erException
;
97 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag
, nCode
);
98 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST
);
103 case CTRL_BREAK_EVENT
:
105 if (IsDebuggerPresent())
107 erException
.ExceptionCode
= (nCode
== CTRL_C_EVENT
?
108 DBG_CONTROL_C
: DBG_CONTROL_BREAK
);
109 erException
.ExceptionFlags
= 0;
110 erException
.ExceptionRecord
= NULL
;
111 erException
.ExceptionAddress
= DefaultConsoleCtrlHandler
;
112 erException
.NumberParameters
= 0;
116 RtlRaiseException(&erException
);
118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
120 RtlEnterCriticalSection(&ConsoleLock
);
122 if ((nCode
!= CTRL_C_EVENT
) ||
123 (NtCurrentPeb()->ProcessParameters
->ConsoleFlags
!= 1))
125 for (i
= NrCtrlHandlers
; i
> 0; i
--)
127 if (CtrlHandlers
[i
- 1](nCode
)) break;
131 RtlLeaveCriticalSection(&ConsoleLock
);
140 case CTRL_CLOSE_EVENT
:
141 case CTRL_LOGOFF_EVENT
:
142 case CTRL_SHUTDOWN_EVENT
:
145 case CTRL_LAST_CLOSE_EVENT
:
147 * In case the console app hasn't register for last close notification,
148 * just kill this console handler thread. We don't want that such apps
149 * get killed for unexpected reasons. On the contrary apps that registered
150 * can be killed because they expect to be.
152 if (!LastCloseNotify
) ExitThread(0);
156 ExitProcess(CONTROL_C_EXIT
);
164 ASSERT(ConsoleInitialized
);
166 RtlEnterCriticalSection(&ConsoleLock
);
169 if ((nCode
!= CTRL_C_EVENT
) || (NtCurrentPeb()->ProcessParameters
->ConsoleFlags
!= 1))
171 for (i
= NrCtrlHandlers
; i
> 0; i
--)
174 (CodeAndFlag
& MINLONG
) &&
175 ((nCode
== CTRL_LOGOFF_EVENT
) || (nCode
== CTRL_SHUTDOWN_EVENT
)))
177 DPRINT("Skipping system/service apps\n");
181 if (CtrlHandlers
[i
- 1](nCode
))
185 case CTRL_CLOSE_EVENT
:
186 case CTRL_LAST_CLOSE_EVENT
:
187 case CTRL_LOGOFF_EVENT
:
188 case CTRL_SHUTDOWN_EVENT
:
189 nExitCode
= CodeAndFlag
;
197 RtlLeaveCriticalSection(&ConsoleLock
);
199 ExitThread(nExitCode
);
200 return STATUS_SUCCESS
;
204 InitializeCtrlHandling(VOID
)
206 /* Initialize Console Ctrl Handler */
207 NrAllocatedHandlers
= NrCtrlHandlers
= 1;
208 CtrlHandlers
= InitialHandler
;
209 CtrlHandlers
[0] = DefaultConsoleCtrlHandler
;
213 /* Input EXE Name Support *****************************************************/
219 PPEB Peb
= NtCurrentPeb();
220 PCURDIR CurrentDirectory
= &Peb
->ProcessParameters
->CurrentDirectory
;
221 PLDR_DATA_TABLE_ENTRY ImageEntry
;
223 if (ExeNameInitialized
) return;
225 /* Initialize the EXE name lock */
226 Status
= RtlInitializeCriticalSection(&ExeNameLock
);
227 if (!NT_SUCCESS(Status
)) return;
228 ExeNameInitialized
= TRUE
;
230 ImageEntry
= CONTAINING_RECORD(Peb
->Ldr
->InLoadOrderModuleList
.Flink
,
231 LDR_DATA_TABLE_ENTRY
,
234 /* Retrieve the EXE name, NULL-terminate it... */
235 ExeNameLength
= min(sizeof(ExeNameBuffer
)/sizeof(ExeNameBuffer
[0]),
236 ImageEntry
->BaseDllName
.Length
/ sizeof(WCHAR
));
237 RtlCopyMemory(ExeNameBuffer
,
238 ImageEntry
->BaseDllName
.Buffer
,
239 ImageEntry
->BaseDllName
.Length
);
240 ExeNameBuffer
[ExeNameLength
] = UNICODE_NULL
;
242 /* ... and retrieve the current directory path and NULL-terminate it. */
243 StartDirLength
= min(sizeof(StartDirBuffer
)/sizeof(StartDirBuffer
[0]),
244 CurrentDirectory
->DosPath
.Length
/ sizeof(WCHAR
));
245 RtlCopyMemory(StartDirBuffer
,
246 CurrentDirectory
->DosPath
.Buffer
,
247 CurrentDirectory
->DosPath
.Length
);
248 StartDirBuffer
[StartDirLength
] = UNICODE_NULL
;
253 * The "LPDWORD Length" parameters point on input to the maximum size of
254 * the buffers that can hold data (if != 0), and on output they hold the
255 * real size of the data. If "Length" are == 0 on input, then on output
256 * they receive the full size of the data.
257 * The "LPWSTR* String" parameters have a double meaning:
258 * - when "CaptureStrings" is TRUE, data is copied to the buffers pointed
259 * by the pointers (*String).
260 * - when "CaptureStrings" is FALSE, "*String" are set to the addresses of
264 SetUpAppName(IN BOOLEAN CaptureStrings
,
265 IN OUT LPDWORD CurDirLength
,
266 IN OUT LPWSTR
* CurDir
,
267 IN OUT LPDWORD AppNameLength
,
268 IN OUT LPWSTR
* AppName
)
272 /* Retrieve the needed buffer size */
273 Length
= (StartDirLength
+ 1) * sizeof(WCHAR
);
274 if (*CurDirLength
> 0) Length
= min(Length
, *CurDirLength
);
275 *CurDirLength
= Length
;
277 /* Capture the data if needed, or, return a pointer to it */
281 * Length is always >= sizeof(WCHAR). Copy everything but the
282 * possible trailing NULL character, and then NULL-terminate.
284 Length
-= sizeof(WCHAR
);
285 RtlCopyMemory(*CurDir
, StartDirBuffer
, Length
);
286 (*CurDir
)[Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
290 *CurDir
= StartDirBuffer
;
293 /* Retrieve the needed buffer size */
294 Length
= (ExeNameLength
+ 1) * sizeof(WCHAR
);
295 if (*AppNameLength
> 0) Length
= min(Length
, *AppNameLength
);
296 *AppNameLength
= Length
;
298 /* Capture the data if needed, or, return a pointer to it */
302 * Length is always >= sizeof(WCHAR). Copy everything but the
303 * possible trailing NULL character, and then NULL-terminate.
305 Length
-= sizeof(WCHAR
);
306 RtlCopyMemory(*AppName
, ExeNameBuffer
, Length
);
307 (*AppName
)[Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
311 *AppName
= ExeNameBuffer
;
316 GetCurrentExeName(OUT PWCHAR ExeName
,
317 IN USHORT BufferSize
)
321 if (ExeNameInitialized
)
323 RtlEnterCriticalSection(&ExeNameLock
);
325 if (BufferSize
> ExeNameLength
* sizeof(WCHAR
))
326 BufferSize
= ExeNameLength
* sizeof(WCHAR
);
328 RtlCopyMemory(ExeName
, ExeNameBuffer
, BufferSize
);
330 RtlLeaveCriticalSection(&ExeNameLock
);
331 ExeLength
= BufferSize
;
335 *ExeName
= UNICODE_NULL
;
342 /* FUNCTIONS ******************************************************************/
345 IntCheckForConsoleFileName(IN LPCWSTR pszName
,
346 IN DWORD dwDesiredAccess
)
348 LPCWSTR ConsoleName
= pszName
;
349 ULONG DeviceNameInfo
;
352 * Check whether we deal with a DOS device, and if so,
353 * strip the path till the file name.
354 * Therefore, things like \\.\CON or C:\some_path\CONIN$
355 * are transformed into CON or CONIN$, for example.
357 DeviceNameInfo
= RtlIsDosDeviceName_U(pszName
);
358 if (DeviceNameInfo
!= 0)
360 ConsoleName
= (LPCWSTR
)((ULONG_PTR
)ConsoleName
+ ((DeviceNameInfo
>> 16) & 0xFFFF));
363 /* Return a standard console "file" name according to what we passed in parameters */
364 if (_wcsicmp(ConsoleName
, BaseConInputFileName
) == 0)
366 return BaseConInputFileName
;
368 else if (_wcsicmp(ConsoleName
, BaseConOutputFileName
) == 0)
370 return BaseConOutputFileName
;
372 else if (_wcsicmp(ConsoleName
, BaseConFileName
) == 0)
374 if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_READ
)
376 return BaseConInputFileName
;
378 else if ((dwDesiredAccess
& (GENERIC_READ
| GENERIC_WRITE
)) == GENERIC_WRITE
)
380 return BaseConOutputFileName
;
384 /* If we are there, that means that either the file name or the desired access are wrong */
390 * @implemented (Undocumented)
391 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php
395 ConsoleMenuControl(HANDLE hConsoleOutput
,
399 CONSOLE_API_MESSAGE ApiMessage
;
400 PCONSOLE_MENUCONTROL MenuControlRequest
= &ApiMessage
.Data
.MenuControlRequest
;
402 MenuControlRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
403 MenuControlRequest
->OutputHandle
= hConsoleOutput
;
404 MenuControlRequest
->CmdIdLow
= dwCmdIdLow
;
405 MenuControlRequest
->CmdIdHigh
= dwCmdIdHigh
;
406 MenuControlRequest
->MenuHandle
= NULL
;
408 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
410 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepMenuControl
),
411 sizeof(*MenuControlRequest
));
413 return MenuControlRequest
->MenuHandle
;
422 DuplicateConsoleHandle(HANDLE hConsole
,
423 DWORD dwDesiredAccess
,
427 CONSOLE_API_MESSAGE ApiMessage
;
428 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest
= &ApiMessage
.Data
.DuplicateHandleRequest
;
430 if ( (dwOptions
& ~(DUPLICATE_CLOSE_SOURCE
| DUPLICATE_SAME_ACCESS
)) ||
431 (!(dwOptions
& DUPLICATE_SAME_ACCESS
) &&
432 (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
))) )
434 SetLastError(ERROR_INVALID_PARAMETER
);
435 return INVALID_HANDLE_VALUE
;
438 DuplicateHandleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
439 DuplicateHandleRequest
->SourceHandle
= hConsole
;
440 DuplicateHandleRequest
->DesiredAccess
= dwDesiredAccess
;
441 DuplicateHandleRequest
->InheritHandle
= bInheritHandle
;
442 DuplicateHandleRequest
->Options
= dwOptions
;
444 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
446 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepDuplicateHandle
),
447 sizeof(*DuplicateHandleRequest
));
448 if (!NT_SUCCESS(ApiMessage
.Status
))
450 BaseSetLastNTError(ApiMessage
.Status
);
451 return INVALID_HANDLE_VALUE
;
454 return DuplicateHandleRequest
->TargetHandle
;
463 GetConsoleHandleInformation(IN HANDLE hHandle
,
464 OUT LPDWORD lpdwFlags
)
466 CONSOLE_API_MESSAGE ApiMessage
;
467 PCONSOLE_GETHANDLEINFO GetHandleInfoRequest
= &ApiMessage
.Data
.GetHandleInfoRequest
;
469 GetHandleInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
470 GetHandleInfoRequest
->Handle
= hHandle
;
472 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
474 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetHandleInformation
),
475 sizeof(*GetHandleInfoRequest
));
476 if (!NT_SUCCESS(ApiMessage
.Status
))
478 BaseSetLastNTError(ApiMessage
.Status
);
482 *lpdwFlags
= GetHandleInfoRequest
->Flags
;
493 SetConsoleHandleInformation(IN HANDLE hHandle
,
497 CONSOLE_API_MESSAGE ApiMessage
;
498 PCONSOLE_SETHANDLEINFO SetHandleInfoRequest
= &ApiMessage
.Data
.SetHandleInfoRequest
;
500 SetHandleInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
501 SetHandleInfoRequest
->Handle
= hHandle
;
502 SetHandleInfoRequest
->Mask
= dwMask
;
503 SetHandleInfoRequest
->Flags
= dwFlags
;
505 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
507 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetHandleInformation
),
508 sizeof(*SetHandleInfoRequest
));
509 if (!NT_SUCCESS(ApiMessage
.Status
))
511 BaseSetLastNTError(ApiMessage
.Status
);
524 GetConsoleDisplayMode(LPDWORD lpModeFlags
)
526 CONSOLE_API_MESSAGE ApiMessage
;
527 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest
= &ApiMessage
.Data
.GetDisplayModeRequest
;
529 if (lpModeFlags
== NULL
)
531 SetLastError(ERROR_INVALID_PARAMETER
);
535 GetDisplayModeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
537 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
539 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetDisplayMode
),
540 sizeof(*GetDisplayModeRequest
));
541 if (!NT_SUCCESS(ApiMessage
.Status
))
543 BaseSetLastNTError(ApiMessage
.Status
);
547 *lpModeFlags
= GetDisplayModeRequest
->DisplayMode
; // ModeFlags
554 * @unimplemented (Undocumented)
558 GetConsoleFontInfo(HANDLE hConsoleOutput
,
561 PCONSOLE_FONT_INFO lpConsoleFontInfo
)
563 DPRINT1("GetConsoleFontInfo(0x%p, %d, %lu, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput
, bMaximumWindow
, nFontCount
, lpConsoleFontInfo
);
564 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
574 GetConsoleFontSize(HANDLE hConsoleOutput
,
577 COORD Empty
= {0, 0};
578 DPRINT1("GetConsoleFontSize(0x%p, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput
, nFont
);
579 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
585 * @implemented (Undocumented)
589 GetConsoleHardwareState(HANDLE hConsoleOutput
,
593 CONSOLE_API_MESSAGE ApiMessage
;
594 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
596 DPRINT1("GetConsoleHardwareState(%lu, 0x%p) UNIMPLEMENTED!\n", Flags
, State
);
598 if (Flags
== NULL
|| State
== NULL
)
600 SetLastError(ERROR_INVALID_PARAMETER
);
604 HardwareStateRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
605 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
607 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
609 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetHardwareState
),
610 sizeof(*HardwareStateRequest
));
611 if (!NT_SUCCESS(ApiMessage
.Status
))
613 BaseSetLastNTError(ApiMessage
.Status
);
617 *Flags
= HardwareStateRequest
->Flags
;
618 *State
= HardwareStateRequest
->State
;
625 * @implemented (Undocumented)
629 GetConsoleInputWaitHandle(VOID
)
631 return InputWaitHandle
;
640 GetCurrentConsoleFont(HANDLE hConsoleOutput
,
642 PCONSOLE_FONT_INFO lpConsoleCurrentFont
)
644 DPRINT1("GetCurrentConsoleFont(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput
, bMaximumWindow
, lpConsoleCurrentFont
);
645 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
651 * @unimplemented (Undocumented)
655 GetNumberOfConsoleFonts(VOID
)
657 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
658 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
664 * @implemented (Undocumented)
665 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
669 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput
,
670 IN PSMALL_RECT lpRect
)
672 CONSOLE_API_MESSAGE ApiMessage
;
673 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest
= &ApiMessage
.Data
.InvalidateDIBitsRequest
;
677 SetLastError(ERROR_INVALID_PARAMETER
);
681 InvalidateDIBitsRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
682 InvalidateDIBitsRequest
->OutputHandle
= hConsoleOutput
;
683 InvalidateDIBitsRequest
->Region
= *lpRect
;
685 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
687 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepInvalidateBitMapRect
),
688 sizeof(*InvalidateDIBitsRequest
));
689 if (!NT_SUCCESS(ApiMessage
.Status
))
691 BaseSetLastNTError(ApiMessage
.Status
);
700 * @implemented (Undocumented)
704 OpenConsoleW(LPCWSTR wsName
,
705 DWORD dwDesiredAccess
,
709 CONSOLE_API_MESSAGE ApiMessage
;
710 PCONSOLE_OPENCONSOLE OpenConsoleRequest
= &ApiMessage
.Data
.OpenConsoleRequest
;
711 CONSOLE_HANDLE_TYPE HandleType
;
713 if (wsName
&& (_wcsicmp(wsName
, BaseConInputFileName
) == 0))
715 HandleType
= HANDLE_INPUT
;
717 else if (wsName
&& (_wcsicmp(wsName
, BaseConOutputFileName
) == 0))
719 HandleType
= HANDLE_OUTPUT
;
723 SetLastError(ERROR_INVALID_PARAMETER
);
724 return INVALID_HANDLE_VALUE
;
727 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
728 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) )
730 SetLastError(ERROR_INVALID_PARAMETER
);
731 return INVALID_HANDLE_VALUE
;
734 OpenConsoleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
735 OpenConsoleRequest
->HandleType
= HandleType
;
736 OpenConsoleRequest
->DesiredAccess
= dwDesiredAccess
;
737 OpenConsoleRequest
->InheritHandle
= bInheritHandle
;
738 OpenConsoleRequest
->ShareMode
= dwShareMode
;
740 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
742 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepOpenConsole
),
743 sizeof(*OpenConsoleRequest
));
744 if (!NT_SUCCESS(ApiMessage
.Status
))
746 BaseSetLastNTError(ApiMessage
.Status
);
747 return INVALID_HANDLE_VALUE
;
750 return OpenConsoleRequest
->Handle
;
755 * @implemented (Undocumented)
756 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleCursor.php
760 SetConsoleCursor(HANDLE hConsoleOutput
,
763 CONSOLE_API_MESSAGE ApiMessage
;
764 PCONSOLE_SETCURSOR SetCursorRequest
= &ApiMessage
.Data
.SetCursorRequest
;
766 SetCursorRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
767 SetCursorRequest
->OutputHandle
= hConsoleOutput
;
768 SetCursorRequest
->CursorHandle
= hCursor
;
770 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
772 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursor
),
773 sizeof(*SetCursorRequest
));
774 if (!NT_SUCCESS(ApiMessage
.Status
))
776 BaseSetLastNTError(ApiMessage
.Status
);
789 SetConsoleDisplayMode(HANDLE hConsoleOutput
,
790 DWORD dwFlags
, // dwModeFlags
791 PCOORD lpNewScreenBufferDimensions
)
793 CONSOLE_API_MESSAGE ApiMessage
;
794 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest
= &ApiMessage
.Data
.SetDisplayModeRequest
;
796 SetDisplayModeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
797 SetDisplayModeRequest
->OutputHandle
= hConsoleOutput
;
798 SetDisplayModeRequest
->DisplayMode
= dwFlags
; // ModeFlags ; dwModeFlags
799 SetDisplayModeRequest
->NewSBDim
.X
= 0;
800 SetDisplayModeRequest
->NewSBDim
.Y
= 0;
801 /* SetDisplayModeRequest->EventHandle; */
803 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
805 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetDisplayMode
),
806 sizeof(*SetDisplayModeRequest
));
807 if (!NT_SUCCESS(ApiMessage
.Status
))
809 BaseSetLastNTError(ApiMessage
.Status
);
813 if (lpNewScreenBufferDimensions
)
814 *lpNewScreenBufferDimensions
= SetDisplayModeRequest
->NewSBDim
;
821 * @unimplemented (Undocumented)
825 SetConsoleFont(HANDLE hConsoleOutput
,
828 DPRINT1("SetConsoleFont(0x%p, %lu) UNIMPLEMENTED!\n", hConsoleOutput
, nFont
);
829 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
835 * @implemented (Undocumented)
839 SetConsoleHardwareState(HANDLE hConsoleOutput
,
843 CONSOLE_API_MESSAGE ApiMessage
;
844 PCONSOLE_GETSETHWSTATE HardwareStateRequest
= &ApiMessage
.Data
.HardwareStateRequest
;
846 DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags
, State
);
848 HardwareStateRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
849 HardwareStateRequest
->OutputHandle
= hConsoleOutput
;
850 HardwareStateRequest
->Flags
= Flags
;
851 HardwareStateRequest
->State
= State
;
853 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
855 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetHardwareState
),
856 sizeof(*HardwareStateRequest
));
857 if (!NT_SUCCESS(ApiMessage
.Status
))
859 BaseSetLastNTError(ApiMessage
.Status
);
868 * @unimplemented (Undocumented)
872 SetConsoleKeyShortcuts(DWORD Unknown0
,
877 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0
, Unknown1
, Unknown2
, Unknown3
);
878 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
884 * @implemented (Undocumented)
885 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php
886 * Does nothing, returns TRUE only. Checked on Windows Server 2003.
890 SetConsoleMaximumWindowSize(HANDLE hConsoleOutput
,
893 DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n",
894 hConsoleOutput
, dwMaximumSize
.X
, dwMaximumSize
.Y
);
900 * @implemented (Undocumented)
904 SetConsoleMenuClose(BOOL bEnable
)
906 CONSOLE_API_MESSAGE ApiMessage
;
907 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest
= &ApiMessage
.Data
.SetMenuCloseRequest
;
909 SetMenuCloseRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
910 SetMenuCloseRequest
->Enable
= bEnable
;
912 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
914 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetMenuClose
),
915 sizeof(*SetMenuCloseRequest
));
916 if (!NT_SUCCESS(ApiMessage
.Status
))
918 BaseSetLastNTError(ApiMessage
.Status
);
927 * @implemented (Undocumented)
928 * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844
929 * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52
933 SetConsolePalette(HANDLE hConsoleOutput
,
937 CONSOLE_API_MESSAGE ApiMessage
;
938 PCONSOLE_SETPALETTE SetPaletteRequest
= &ApiMessage
.Data
.SetPaletteRequest
;
940 SetPaletteRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
941 SetPaletteRequest
->OutputHandle
= hConsoleOutput
;
942 SetPaletteRequest
->PaletteHandle
= hPalette
;
943 SetPaletteRequest
->Usage
= dwUsage
;
945 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
947 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetPalette
),
948 sizeof(*SetPaletteRequest
));
949 if (!NT_SUCCESS(ApiMessage
.Status
))
951 BaseSetLastNTError(ApiMessage
.Status
);
959 * @implemented (Undocumented)
960 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php
964 ShowConsoleCursor(HANDLE hConsoleOutput
,
967 CONSOLE_API_MESSAGE ApiMessage
;
968 PCONSOLE_SHOWCURSOR ShowCursorRequest
= &ApiMessage
.Data
.ShowCursorRequest
;
970 ShowCursorRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
971 ShowCursorRequest
->OutputHandle
= hConsoleOutput
;
972 ShowCursorRequest
->Show
= bShow
;
973 ShowCursorRequest
->RefCount
= 0;
975 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
977 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepShowCursor
),
978 sizeof(*ShowCursorRequest
));
980 return ShowCursorRequest
->RefCount
;
985 * FUNCTION: Checks whether the given handle is a valid console handle.
988 * hIoHandle - Handle to be checked.
991 * TRUE : Handle is a valid console handle.
992 * FALSE: Handle is not a valid console handle.
994 * STATUS: Officially undocumented
1000 VerifyConsoleIoHandle(HANDLE hIoHandle
)
1002 CONSOLE_API_MESSAGE ApiMessage
;
1003 PCONSOLE_VERIFYHANDLE VerifyHandleRequest
= &ApiMessage
.Data
.VerifyHandleRequest
;
1005 VerifyHandleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1006 VerifyHandleRequest
->Handle
= hIoHandle
;
1007 VerifyHandleRequest
->IsValid
= FALSE
;
1009 /* If the process is not attached to a console, return invalid handle */
1010 if (VerifyHandleRequest
->ConsoleHandle
== NULL
) return FALSE
;
1012 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1014 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepVerifyIoHandle
),
1015 sizeof(*VerifyHandleRequest
));
1016 if (!NT_SUCCESS(ApiMessage
.Status
))
1018 BaseSetLastNTError(ApiMessage
.Status
);
1022 return VerifyHandleRequest
->IsValid
;
1027 * @implemented (Undocumented)
1031 CloseConsoleHandle(HANDLE hHandle
)
1033 CONSOLE_API_MESSAGE ApiMessage
;
1034 PCONSOLE_CLOSEHANDLE CloseHandleRequest
= &ApiMessage
.Data
.CloseHandleRequest
;
1036 CloseHandleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1037 CloseHandleRequest
->Handle
= hHandle
;
1039 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1041 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCloseHandle
),
1042 sizeof(*CloseHandleRequest
));
1043 if (!NT_SUCCESS(ApiMessage
.Status
))
1045 BaseSetLastNTError(ApiMessage
.Status
);
1058 GetStdHandle(DWORD nStdHandle
)
1060 * FUNCTION: Get a handle for the standard input, standard output
1061 * and a standard error device.
1064 * nStdHandle - Specifies the device for which to return the handle.
1066 * RETURNS: If the function succeeds, the return value is the handle
1067 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1070 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
1071 HANDLE Handle
= INVALID_HANDLE_VALUE
;
1075 case STD_INPUT_HANDLE
:
1076 Handle
= Ppb
->StandardInput
;
1079 case STD_OUTPUT_HANDLE
:
1080 Handle
= Ppb
->StandardOutput
;
1083 case STD_ERROR_HANDLE
:
1084 Handle
= Ppb
->StandardError
;
1088 /* If the returned handle is invalid, set last error */
1089 if (Handle
== INVALID_HANDLE_VALUE
) SetLastError(ERROR_INVALID_HANDLE
);
1100 SetStdHandle(DWORD nStdHandle
,
1103 * FUNCTION: Set the handle for the standard input, standard output or
1104 * the standard error device.
1107 * nStdHandle - Specifies the handle to be set.
1108 * hHandle - The handle to set.
1110 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1113 PRTL_USER_PROCESS_PARAMETERS Ppb
= NtCurrentPeb()->ProcessParameters
;
1115 /* No need to check if hHandle == INVALID_HANDLE_VALUE */
1119 case STD_INPUT_HANDLE
:
1120 Ppb
->StandardInput
= hHandle
;
1123 case STD_OUTPUT_HANDLE
:
1124 Ppb
->StandardOutput
= hHandle
;
1127 case STD_ERROR_HANDLE
:
1128 Ppb
->StandardError
= hHandle
;
1132 /* nStdHandle was invalid, bail out */
1133 SetLastError(ERROR_INVALID_HANDLE
);
1142 IntAllocConsole(LPWSTR Title
,
1145 DWORD DesktopLength
,
1149 DWORD AppNameLength
,
1150 LPTHREAD_START_ROUTINE CtrlRoutine
,
1151 LPTHREAD_START_ROUTINE PropRoutine
,
1152 PCONSOLE_START_INFO ConsoleStartInfo
)
1154 BOOL Success
= TRUE
;
1155 #ifdef USE_CONSOLE_INIT_HANDLES
1159 CONSOLE_API_MESSAGE ApiMessage
;
1160 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest
= &ApiMessage
.Data
.AllocConsoleRequest
;
1161 PCSR_CAPTURE_BUFFER CaptureBuffer
;
1163 AllocConsoleRequest
->CtrlRoutine
= CtrlRoutine
;
1164 AllocConsoleRequest
->PropRoutine
= PropRoutine
;
1166 CaptureBuffer
= CsrAllocateCaptureBuffer(5, TitleLength
+
1170 sizeof(CONSOLE_START_INFO
));
1171 if (CaptureBuffer
== NULL
)
1173 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1178 CsrCaptureMessageBuffer(CaptureBuffer
,
1180 sizeof(CONSOLE_START_INFO
),
1181 (PVOID
*)&AllocConsoleRequest
->ConsoleStartInfo
);
1183 AllocConsoleRequest
->TitleLength
= TitleLength
;
1184 CsrCaptureMessageBuffer(CaptureBuffer
,
1187 (PVOID
*)&AllocConsoleRequest
->ConsoleTitle
);
1189 AllocConsoleRequest
->DesktopLength
= DesktopLength
;
1190 CsrCaptureMessageBuffer(CaptureBuffer
,
1193 (PVOID
*)&AllocConsoleRequest
->Desktop
);
1195 AllocConsoleRequest
->CurDirLength
= CurDirLength
;
1196 CsrCaptureMessageBuffer(CaptureBuffer
,
1199 (PVOID
*)&AllocConsoleRequest
->CurDir
);
1201 AllocConsoleRequest
->AppNameLength
= AppNameLength
;
1202 CsrCaptureMessageBuffer(CaptureBuffer
,
1205 (PVOID
*)&AllocConsoleRequest
->AppName
);
1207 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1209 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAlloc
),
1210 sizeof(*AllocConsoleRequest
));
1211 if (!NT_SUCCESS(ApiMessage
.Status
))
1213 BaseSetLastNTError(ApiMessage
.Status
);
1218 #ifdef USE_CONSOLE_INIT_HANDLES
1219 // Is AllocConsoleRequest->ConsoleStartInfo->Events aligned on handle boundary ????
1220 Status
= NtWaitForMultipleObjects(2, AllocConsoleRequest
->ConsoleStartInfo
->Events
,
1221 WaitAny
, FALSE
, NULL
);
1222 if (!NT_SUCCESS(Status
))
1224 BaseSetLastNTError(Status
);
1229 NtClose(AllocConsoleRequest
->ConsoleStartInfo
->Events
[0]);
1230 NtClose(AllocConsoleRequest
->ConsoleStartInfo
->Events
[1]);
1231 if (Status
!= STATUS_SUCCESS
)
1233 NtCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
1239 RtlCopyMemory(ConsoleStartInfo
,
1240 AllocConsoleRequest
->ConsoleStartInfo
,
1241 sizeof(CONSOLE_START_INFO
));
1246 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
1255 CONSOLE_START_INFO ConsoleStartInfo
;
1257 PWCHAR ConsoleTitle
;
1262 ULONG TitleLength
= (MAX_PATH
+ 1) * sizeof(WCHAR
);
1263 ULONG DesktopLength
= (MAX_PATH
+ 1) * sizeof(WCHAR
);
1264 ULONG AppNameLength
= 128 * sizeof(WCHAR
);
1265 ULONG CurDirLength
= (MAX_PATH
+ 1) * sizeof(WCHAR
);
1269 RtlEnterCriticalSection(&ConsoleLock
);
1271 if (NtCurrentPeb()->ProcessParameters
->ConsoleHandle
)
1273 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
1274 SetLastError(ERROR_ACCESS_DENIED
);
1279 /* Set up the console properties */
1280 SetUpConsoleInfo(FALSE
,
1286 DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n",
1287 ConsoleTitle
, Desktop
);
1289 /* Initialize the Input EXE name */
1296 DPRINT("CurDir = '%S' - AppName = '%S'\n",
1299 Success
= IntAllocConsole(ConsoleTitle
,
1307 ConsoleControlDispatcher
,
1312 /* Set up the handles */
1313 SetUpHandles(&ConsoleStartInfo
);
1314 InputWaitHandle
= ConsoleStartInfo
.InputWaitHandle
;
1316 /* Initialize Console Ctrl Handling */
1317 InitializeCtrlHandling();
1319 /* Sets the current console locale for this thread */
1324 RtlLeaveCriticalSection(&ConsoleLock
);
1336 CONSOLE_API_MESSAGE ApiMessage
;
1337 PCONSOLE_FREECONSOLE FreeConsoleRequest
= &ApiMessage
.Data
.FreeConsoleRequest
;
1338 HANDLE ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1340 /* We must have a non-trivial handle to close */
1341 if (ConsoleHandle
== NULL
) // IsConsoleHandle(ConsoleHandle)
1343 SetLastError(ERROR_INVALID_PARAMETER
);
1347 /* Set up the data to send to the Console Server */
1348 FreeConsoleRequest
->ConsoleHandle
= ConsoleHandle
;
1350 /* Call the server */
1351 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1353 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFree
),
1354 sizeof(*FreeConsoleRequest
));
1356 /* Check for success */
1357 if (!NT_SUCCESS(ApiMessage
.Status
))
1359 BaseSetLastNTError(ApiMessage
.Status
);
1363 /* Reset the console handle */
1364 NtCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
1366 /* Close the associated input handle */
1367 CloseHandle(InputWaitHandle
);
1368 InputWaitHandle
= INVALID_HANDLE_VALUE
;
1379 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput
,
1380 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
)
1382 CONSOLE_API_MESSAGE ApiMessage
;
1383 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest
= &ApiMessage
.Data
.ScreenBufferInfoRequest
;
1385 if (lpConsoleScreenBufferInfo
== NULL
)
1387 SetLastError(ERROR_INVALID_PARAMETER
);
1391 ScreenBufferInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1392 ScreenBufferInfoRequest
->OutputHandle
= hConsoleOutput
;
1394 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1396 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetScreenBufferInfo
),
1397 sizeof(*ScreenBufferInfoRequest
));
1398 if (!NT_SUCCESS(ApiMessage
.Status
))
1400 BaseSetLastNTError(ApiMessage
.Status
);
1404 lpConsoleScreenBufferInfo
->dwSize
= ScreenBufferInfoRequest
->ScreenBufferSize
;
1405 lpConsoleScreenBufferInfo
->dwCursorPosition
= ScreenBufferInfoRequest
->CursorPosition
;
1406 lpConsoleScreenBufferInfo
->wAttributes
= ScreenBufferInfoRequest
->Attributes
;
1407 lpConsoleScreenBufferInfo
->srWindow
.Left
= ScreenBufferInfoRequest
->ViewOrigin
.X
;
1408 lpConsoleScreenBufferInfo
->srWindow
.Top
= ScreenBufferInfoRequest
->ViewOrigin
.Y
;
1409 lpConsoleScreenBufferInfo
->srWindow
.Right
= ScreenBufferInfoRequest
->ViewOrigin
.X
+ ScreenBufferInfoRequest
->ViewSize
.X
- 1;
1410 lpConsoleScreenBufferInfo
->srWindow
.Bottom
= ScreenBufferInfoRequest
->ViewOrigin
.Y
+ ScreenBufferInfoRequest
->ViewSize
.Y
- 1;
1411 lpConsoleScreenBufferInfo
->dwMaximumWindowSize
= ScreenBufferInfoRequest
->MaximumViewSize
;
1422 SetConsoleCursorPosition(HANDLE hConsoleOutput
,
1423 COORD dwCursorPosition
)
1425 CONSOLE_API_MESSAGE ApiMessage
;
1426 PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest
= &ApiMessage
.Data
.SetCursorPositionRequest
;
1428 SetCursorPositionRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1429 SetCursorPositionRequest
->OutputHandle
= hConsoleOutput
;
1430 SetCursorPositionRequest
->Position
= dwCursorPosition
;
1432 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1434 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorPosition
),
1435 sizeof(*SetCursorPositionRequest
));
1436 if (!NT_SUCCESS(ApiMessage
.Status
))
1438 BaseSetLastNTError(ApiMessage
.Status
);
1451 GetConsoleMode(HANDLE hConsoleHandle
,
1454 CONSOLE_API_MESSAGE ApiMessage
;
1455 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1459 SetLastError(ERROR_INVALID_PARAMETER
);
1463 ConsoleModeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1464 ConsoleModeRequest
->Handle
= hConsoleHandle
;
1466 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1468 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetMode
),
1469 sizeof(*ConsoleModeRequest
));
1470 if (!NT_SUCCESS(ApiMessage
.Status
))
1472 BaseSetLastNTError(ApiMessage
.Status
);
1476 *lpMode
= ConsoleModeRequest
->Mode
;
1487 SetConsoleMode(HANDLE hConsoleHandle
,
1490 CONSOLE_API_MESSAGE ApiMessage
;
1491 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest
= &ApiMessage
.Data
.ConsoleModeRequest
;
1493 ConsoleModeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1494 ConsoleModeRequest
->Handle
= hConsoleHandle
;
1495 ConsoleModeRequest
->Mode
= dwMode
;
1497 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1499 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetMode
),
1500 sizeof(*ConsoleModeRequest
));
1501 if (!NT_SUCCESS(ApiMessage
.Status
))
1503 BaseSetLastNTError(ApiMessage
.Status
);
1516 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput
,
1517 LPDWORD lpNumberOfEvents
)
1519 CONSOLE_API_MESSAGE ApiMessage
;
1520 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest
= &ApiMessage
.Data
.GetNumInputEventsRequest
;
1522 GetNumInputEventsRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1523 GetNumInputEventsRequest
->InputHandle
= hConsoleInput
;
1524 GetNumInputEventsRequest
->NumberOfEvents
= 0;
1526 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1528 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetNumberOfInputEvents
),
1529 sizeof(*GetNumInputEventsRequest
));
1530 if (!NT_SUCCESS(ApiMessage
.Status
))
1532 BaseSetLastNTError(ApiMessage
.Status
);
1536 if (lpNumberOfEvents
== NULL
)
1538 SetLastError(ERROR_INVALID_ACCESS
);
1542 *lpNumberOfEvents
= GetNumInputEventsRequest
->NumberOfEvents
;
1553 GetLargestConsoleWindowSize(HANDLE hConsoleOutput
)
1555 CONSOLE_API_MESSAGE ApiMessage
;
1556 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest
= &ApiMessage
.Data
.GetLargestWindowSizeRequest
;
1558 GetLargestWindowSizeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1559 GetLargestWindowSizeRequest
->OutputHandle
= hConsoleOutput
;
1560 GetLargestWindowSizeRequest
->Size
.X
= 0;
1561 GetLargestWindowSizeRequest
->Size
.Y
= 0;
1563 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1565 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetLargestWindowSize
),
1566 sizeof(*GetLargestWindowSizeRequest
));
1567 if (!NT_SUCCESS(ApiMessage
.Status
))
1569 BaseSetLastNTError(ApiMessage
.Status
);
1572 DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest
->Size
.X
, GetLargestWindowSizeRequest
->Size
.Y
);
1573 return GetLargestWindowSizeRequest
->Size
;
1582 GetConsoleCursorInfo(HANDLE hConsoleOutput
,
1583 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
)
1585 CONSOLE_API_MESSAGE ApiMessage
;
1586 PCONSOLE_GETSETCURSORINFO CursorInfoRequest
= &ApiMessage
.Data
.CursorInfoRequest
;
1588 if (!lpConsoleCursorInfo
)
1590 if (!hConsoleOutput
)
1591 SetLastError(ERROR_INVALID_HANDLE
);
1593 SetLastError(ERROR_INVALID_ACCESS
);
1598 CursorInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1599 CursorInfoRequest
->OutputHandle
= hConsoleOutput
;
1601 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1603 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCursorInfo
),
1604 sizeof(*CursorInfoRequest
));
1605 if (!NT_SUCCESS(ApiMessage
.Status
))
1607 BaseSetLastNTError(ApiMessage
.Status
);
1611 *lpConsoleCursorInfo
= CursorInfoRequest
->Info
;
1622 SetConsoleCursorInfo(HANDLE hConsoleOutput
,
1623 CONST CONSOLE_CURSOR_INFO
*lpConsoleCursorInfo
)
1625 CONSOLE_API_MESSAGE ApiMessage
;
1626 PCONSOLE_GETSETCURSORINFO CursorInfoRequest
= &ApiMessage
.Data
.CursorInfoRequest
;
1628 CursorInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1629 CursorInfoRequest
->OutputHandle
= hConsoleOutput
;
1630 CursorInfoRequest
->Info
= *lpConsoleCursorInfo
;
1632 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1634 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCursorInfo
),
1635 sizeof(*CursorInfoRequest
));
1636 if (!NT_SUCCESS(ApiMessage
.Status
))
1638 BaseSetLastNTError(ApiMessage
.Status
);
1651 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons
)
1653 CONSOLE_API_MESSAGE ApiMessage
;
1654 PCONSOLE_GETMOUSEINFO GetMouseInfoRequest
= &ApiMessage
.Data
.GetMouseInfoRequest
;
1656 GetMouseInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1658 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1660 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetMouseInfo
),
1661 sizeof(*GetMouseInfoRequest
));
1662 if (!NT_SUCCESS(ApiMessage
.Status
))
1664 BaseSetLastNTError(ApiMessage
.Status
);
1668 *lpNumberOfMouseButtons
= GetMouseInfoRequest
->NumButtons
;
1678 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput
)
1680 CONSOLE_API_MESSAGE ApiMessage
;
1681 PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest
= &ApiMessage
.Data
.SetScreenBufferRequest
;
1683 SetScreenBufferRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1684 SetScreenBufferRequest
->OutputHandle
= hConsoleOutput
;
1686 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1688 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetActiveScreenBuffer
),
1689 sizeof(*SetScreenBufferRequest
));
1690 if (!NT_SUCCESS(ApiMessage
.Status
))
1692 BaseSetLastNTError(ApiMessage
.Status
);
1705 FlushConsoleInputBuffer(HANDLE hConsoleInput
)
1707 CONSOLE_API_MESSAGE ApiMessage
;
1708 PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest
= &ApiMessage
.Data
.FlushInputBufferRequest
;
1710 FlushInputBufferRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1711 FlushInputBufferRequest
->InputHandle
= hConsoleInput
;
1713 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1715 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFlushInputBuffer
),
1716 sizeof(*FlushInputBufferRequest
));
1717 if (!NT_SUCCESS(ApiMessage
.Status
))
1719 BaseSetLastNTError(ApiMessage
.Status
);
1732 SetConsoleScreenBufferSize(HANDLE hConsoleOutput
,
1735 CONSOLE_API_MESSAGE ApiMessage
;
1736 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest
= &ApiMessage
.Data
.SetScreenBufferSizeRequest
;
1738 SetScreenBufferSizeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1739 SetScreenBufferSizeRequest
->OutputHandle
= hConsoleOutput
;
1740 SetScreenBufferSizeRequest
->Size
= dwSize
;
1742 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1744 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetScreenBufferSize
),
1745 sizeof(*SetScreenBufferSizeRequest
));
1746 if (!NT_SUCCESS(ApiMessage
.Status
))
1748 BaseSetLastNTError(ApiMessage
.Status
);
1758 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput
,
1759 CONST SMALL_RECT
* lpScrollRectangle
,
1760 CONST SMALL_RECT
* lpClipRectangle
,
1761 COORD dwDestinationOrigin
,
1762 CONST CHAR_INFO
* lpFill
,
1765 CONSOLE_API_MESSAGE ApiMessage
;
1766 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest
= &ApiMessage
.Data
.ScrollScreenBufferRequest
;
1768 ScrollScreenBufferRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1769 ScrollScreenBufferRequest
->OutputHandle
= hConsoleOutput
;
1770 ScrollScreenBufferRequest
->ScrollRectangle
= *lpScrollRectangle
;
1772 if (lpClipRectangle
!= NULL
)
1774 ScrollScreenBufferRequest
->UseClipRectangle
= TRUE
;
1775 ScrollScreenBufferRequest
->ClipRectangle
= *lpClipRectangle
;
1779 ScrollScreenBufferRequest
->UseClipRectangle
= FALSE
;
1782 ScrollScreenBufferRequest
->DestinationOrigin
= dwDestinationOrigin
;
1783 ScrollScreenBufferRequest
->Fill
= *lpFill
;
1784 ScrollScreenBufferRequest
->Unicode
= bUnicode
;
1786 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1788 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepScrollScreenBuffer
),
1789 sizeof(*ScrollScreenBufferRequest
));
1790 if (!NT_SUCCESS(ApiMessage
.Status
))
1792 BaseSetLastNTError(ApiMessage
.Status
);
1805 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput
,
1806 CONST SMALL_RECT
* lpScrollRectangle
,
1807 CONST SMALL_RECT
* lpClipRectangle
,
1808 COORD dwDestinationOrigin
,
1809 CONST CHAR_INFO
* lpFill
)
1811 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1814 dwDestinationOrigin
,
1825 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput
,
1826 CONST SMALL_RECT
*lpScrollRectangle
,
1827 CONST SMALL_RECT
*lpClipRectangle
,
1828 COORD dwDestinationOrigin
,
1829 CONST CHAR_INFO
*lpFill
)
1831 return IntScrollConsoleScreenBuffer(hConsoleOutput
,
1834 dwDestinationOrigin
,
1845 SetConsoleWindowInfo(HANDLE hConsoleOutput
,
1847 CONST SMALL_RECT
*lpConsoleWindow
)
1849 CONSOLE_API_MESSAGE ApiMessage
;
1850 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest
= &ApiMessage
.Data
.SetWindowInfoRequest
;
1852 if (lpConsoleWindow
== NULL
)
1854 SetLastError(ERROR_INVALID_PARAMETER
);
1858 SetWindowInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1859 SetWindowInfoRequest
->OutputHandle
= hConsoleOutput
;
1860 SetWindowInfoRequest
->Absolute
= bAbsolute
;
1861 SetWindowInfoRequest
->WindowRect
= *lpConsoleWindow
;
1863 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1865 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetWindowInfo
),
1866 sizeof(*SetWindowInfoRequest
));
1867 if (!NT_SUCCESS(ApiMessage
.Status
))
1869 BaseSetLastNTError(ApiMessage
.Status
);
1882 SetConsoleTextAttribute(HANDLE hConsoleOutput
,
1885 CONSOLE_API_MESSAGE ApiMessage
;
1886 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest
= &ApiMessage
.Data
.SetTextAttribRequest
;
1888 SetTextAttribRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
1889 SetTextAttribRequest
->OutputHandle
= hConsoleOutput
;
1890 SetTextAttribRequest
->Attributes
= wAttributes
;
1892 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
1894 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTextAttribute
),
1895 sizeof(*SetTextAttribRequest
));
1896 if (!NT_SUCCESS(ApiMessage
.Status
))
1898 BaseSetLastNTError(ApiMessage
.Status
);
1908 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1910 PHANDLER_ROUTINE
* NewCtrlHandlers
= NULL
;
1912 if (HandlerRoutine
== NULL
)
1914 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= TRUE
;
1918 if (NrCtrlHandlers
== NrAllocatedHandlers
)
1920 NewCtrlHandlers
= RtlAllocateHeap(RtlGetProcessHeap(),
1922 (NrCtrlHandlers
+ 4) * sizeof(PHANDLER_ROUTINE
));
1923 if (NewCtrlHandlers
== NULL
)
1925 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1929 memmove(NewCtrlHandlers
, CtrlHandlers
, sizeof(PHANDLER_ROUTINE
) * NrCtrlHandlers
);
1931 if (NrAllocatedHandlers
> 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers
);
1933 CtrlHandlers
= NewCtrlHandlers
;
1934 NrAllocatedHandlers
+= 4;
1937 ASSERT(NrCtrlHandlers
< NrAllocatedHandlers
);
1939 CtrlHandlers
[NrCtrlHandlers
++] = HandlerRoutine
;
1946 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
)
1950 if (HandlerRoutine
== NULL
)
1952 NtCurrentPeb()->ProcessParameters
->ConsoleFlags
= FALSE
;
1956 for (i
= 0; i
< NrCtrlHandlers
; i
++)
1958 if (CtrlHandlers
[i
] == HandlerRoutine
)
1960 if (i
< (NrCtrlHandlers
- 1))
1962 memmove(&CtrlHandlers
[i
],
1964 (NrCtrlHandlers
- i
+ 1) * sizeof(PHANDLER_ROUTINE
));
1972 SetLastError(ERROR_INVALID_PARAMETER
);
1982 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine
,
1987 RtlEnterCriticalSection(&BaseDllDirectoryLock
);
1990 Ret
= AddConsoleCtrlHandler(HandlerRoutine
);
1994 Ret
= RemoveConsoleCtrlHandler(HandlerRoutine
);
1997 RtlLeaveCriticalSection(&BaseDllDirectoryLock
);
2007 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent
,
2008 DWORD dwProcessGroupId
)
2010 CONSOLE_API_MESSAGE ApiMessage
;
2011 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest
= &ApiMessage
.Data
.GenerateCtrlEventRequest
;
2013 if (dwCtrlEvent
!= CTRL_C_EVENT
&& dwCtrlEvent
!= CTRL_BREAK_EVENT
)
2015 SetLastError(ERROR_INVALID_PARAMETER
);
2019 GenerateCtrlEventRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2020 GenerateCtrlEventRequest
->CtrlEvent
= dwCtrlEvent
;
2021 GenerateCtrlEventRequest
->ProcessGroupId
= dwProcessGroupId
;
2023 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2025 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGenerateCtrlEvent
),
2026 sizeof(*GenerateCtrlEventRequest
));
2027 if (!NT_SUCCESS(ApiMessage
.Status
))
2029 BaseSetLastNTError(ApiMessage
.Status
);
2038 IntGetConsoleTitle(LPVOID lpConsoleTitle
, DWORD dwNumChars
, BOOLEAN bUnicode
)
2040 CONSOLE_API_MESSAGE ApiMessage
;
2041 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
2042 PCSR_CAPTURE_BUFFER CaptureBuffer
;
2044 if (dwNumChars
== 0) return 0;
2046 TitleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2047 TitleRequest
->Length
= dwNumChars
* (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
2048 TitleRequest
->Unicode
= bUnicode
;
2050 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
2051 if (CaptureBuffer
== NULL
)
2053 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2054 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2058 CsrAllocateMessagePointer(CaptureBuffer
,
2059 TitleRequest
->Length
,
2060 (PVOID
*)&TitleRequest
->Title
);
2062 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2064 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetTitle
),
2065 sizeof(*TitleRequest
));
2066 if (!NT_SUCCESS(ApiMessage
.Status
))
2068 CsrFreeCaptureBuffer(CaptureBuffer
);
2069 BaseSetLastNTError(ApiMessage
.Status
);
2073 dwNumChars
= TitleRequest
->Length
/ (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
2077 memcpy(lpConsoleTitle
, TitleRequest
->Title
, TitleRequest
->Length
);
2080 ((LPWSTR
)lpConsoleTitle
)[dwNumChars
] = UNICODE_NULL
;
2082 ((LPSTR
)lpConsoleTitle
)[dwNumChars
] = ANSI_NULL
;
2085 CsrFreeCaptureBuffer(CaptureBuffer
);
2096 GetConsoleTitleW(LPWSTR lpConsoleTitle
,
2099 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, TRUE
);
2108 GetConsoleTitleA(LPSTR lpConsoleTitle
,
2111 return IntGetConsoleTitle(lpConsoleTitle
, nSize
, FALSE
);
2116 IntSetConsoleTitle(CONST VOID
*lpConsoleTitle
, BOOLEAN bUnicode
)
2118 CONSOLE_API_MESSAGE ApiMessage
;
2119 PCONSOLE_GETSETCONSOLETITLE TitleRequest
= &ApiMessage
.Data
.TitleRequest
;
2120 PCSR_CAPTURE_BUFFER CaptureBuffer
;
2122 ULONG NumChars
= (ULONG
)(lpConsoleTitle
? (bUnicode
? wcslen(lpConsoleTitle
) : strlen(lpConsoleTitle
)) : 0);
2124 TitleRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2125 TitleRequest
->Length
= NumChars
* (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
2126 TitleRequest
->Unicode
= bUnicode
;
2128 CaptureBuffer
= CsrAllocateCaptureBuffer(1, TitleRequest
->Length
);
2129 if (CaptureBuffer
== NULL
)
2131 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2132 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2136 CsrCaptureMessageBuffer(CaptureBuffer
,
2137 (PVOID
)lpConsoleTitle
,
2138 TitleRequest
->Length
,
2139 (PVOID
*)&TitleRequest
->Title
);
2141 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2143 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetTitle
),
2144 sizeof(*TitleRequest
));
2146 CsrFreeCaptureBuffer(CaptureBuffer
);
2148 if (!NT_SUCCESS(ApiMessage
.Status
))
2150 BaseSetLastNTError(ApiMessage
.Status
);
2162 SetConsoleTitleW(LPCWSTR lpConsoleTitle
)
2164 return IntSetConsoleTitle(lpConsoleTitle
, TRUE
);
2173 SetConsoleTitleA(LPCSTR lpConsoleTitle
)
2175 return IntSetConsoleTitle(lpConsoleTitle
, FALSE
);
2184 CreateConsoleScreenBuffer(DWORD dwDesiredAccess
,
2186 CONST SECURITY_ATTRIBUTES
*lpSecurityAttributes
,
2188 LPVOID lpScreenBufferData
)
2190 CONSOLE_API_MESSAGE ApiMessage
;
2191 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest
= &ApiMessage
.Data
.CreateScreenBufferRequest
;
2192 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
2193 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo
= lpScreenBufferData
;
2195 if ( (dwDesiredAccess
& ~(GENERIC_READ
| GENERIC_WRITE
)) ||
2196 (dwShareMode
& ~(FILE_SHARE_READ
| FILE_SHARE_WRITE
)) ||
2197 (dwFlags
!= CONSOLE_TEXTMODE_BUFFER
&& dwFlags
!= CONSOLE_GRAPHICS_BUFFER
) )
2199 SetLastError(ERROR_INVALID_PARAMETER
);
2200 return INVALID_HANDLE_VALUE
;
2203 CreateScreenBufferRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2204 CreateScreenBufferRequest
->DesiredAccess
= dwDesiredAccess
;
2205 CreateScreenBufferRequest
->InheritHandle
=
2206 (lpSecurityAttributes
? lpSecurityAttributes
->bInheritHandle
: FALSE
);
2207 CreateScreenBufferRequest
->ShareMode
= dwShareMode
;
2208 CreateScreenBufferRequest
->ScreenBufferType
= dwFlags
;
2210 if (dwFlags
== CONSOLE_GRAPHICS_BUFFER
)
2212 if (CreateScreenBufferRequest
->InheritHandle
|| GraphicsBufferInfo
== NULL
)
2214 SetLastError(ERROR_INVALID_PARAMETER
);
2215 return INVALID_HANDLE_VALUE
;
2218 CreateScreenBufferRequest
->GraphicsBufferInfo
= *GraphicsBufferInfo
;
2220 CaptureBuffer
= CsrAllocateCaptureBuffer(1, GraphicsBufferInfo
->dwBitMapInfoLength
);
2221 if (CaptureBuffer
== NULL
)
2223 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2224 return INVALID_HANDLE_VALUE
;
2227 CsrCaptureMessageBuffer(CaptureBuffer
,
2228 (PVOID
)GraphicsBufferInfo
->lpBitMapInfo
,
2229 GraphicsBufferInfo
->dwBitMapInfoLength
,
2230 (PVOID
*)&CreateScreenBufferRequest
->GraphicsBufferInfo
.lpBitMapInfo
);
2233 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2235 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepCreateScreenBuffer
),
2236 sizeof(*CreateScreenBufferRequest
));
2238 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
2240 if (!NT_SUCCESS(ApiMessage
.Status
))
2242 BaseSetLastNTError(ApiMessage
.Status
);
2243 return INVALID_HANDLE_VALUE
;
2246 if (dwFlags
== CONSOLE_GRAPHICS_BUFFER
&& GraphicsBufferInfo
)
2248 GraphicsBufferInfo
->hMutex
= CreateScreenBufferRequest
->hMutex
; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
2249 GraphicsBufferInfo
->lpBitMap
= CreateScreenBufferRequest
->lpBitMap
; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
2252 return CreateScreenBufferRequest
->OutputHandle
;
2263 CONSOLE_API_MESSAGE ApiMessage
;
2264 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest
= &ApiMessage
.Data
.GetConsoleCPRequest
;
2266 /* Get the Input Code Page */
2267 GetConsoleCPRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2268 GetConsoleCPRequest
->OutputCP
= FALSE
;
2270 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2272 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
2273 sizeof(*GetConsoleCPRequest
));
2274 if (!NT_SUCCESS(ApiMessage
.Status
))
2276 BaseSetLastNTError(ApiMessage
.Status
);
2280 return GetConsoleCPRequest
->CodePage
;
2289 SetConsoleCP(UINT wCodePageID
)
2291 CONSOLE_API_MESSAGE ApiMessage
;
2292 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest
= &ApiMessage
.Data
.SetConsoleCPRequest
;
2294 /* Set the Input Code Page */
2295 SetConsoleCPRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2296 SetConsoleCPRequest
->CodePage
= wCodePageID
;
2297 SetConsoleCPRequest
->OutputCP
= FALSE
;
2298 /* SetConsoleCPRequest->EventHandle; */
2300 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2302 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
2303 sizeof(*SetConsoleCPRequest
));
2304 if (!NT_SUCCESS(ApiMessage
.Status
))
2306 BaseSetLastNTError(ApiMessage
.Status
);
2319 GetConsoleOutputCP(VOID
)
2321 CONSOLE_API_MESSAGE ApiMessage
;
2322 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest
= &ApiMessage
.Data
.GetConsoleCPRequest
;
2324 /* Get the Output Code Page */
2325 GetConsoleCPRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2326 GetConsoleCPRequest
->OutputCP
= TRUE
;
2328 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2330 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetCP
),
2331 sizeof(*GetConsoleCPRequest
));
2332 if (!NT_SUCCESS(ApiMessage
.Status
))
2334 BaseSetLastNTError(ApiMessage
.Status
);
2338 return GetConsoleCPRequest
->CodePage
;
2347 SetConsoleOutputCP(UINT wCodePageID
)
2349 CONSOLE_API_MESSAGE ApiMessage
;
2350 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest
= &ApiMessage
.Data
.SetConsoleCPRequest
;
2352 /* Set the Output Code Page */
2353 SetConsoleCPRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2354 SetConsoleCPRequest
->CodePage
= wCodePageID
;
2355 SetConsoleCPRequest
->OutputCP
= TRUE
;
2356 /* SetConsoleCPRequest->EventHandle; */
2358 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2360 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetCP
),
2361 sizeof(*SetConsoleCPRequest
));
2362 if (!NT_SUCCESS(ApiMessage
.Status
))
2364 BaseSetLastNTError(ApiMessage
.Status
);
2377 GetConsoleProcessList(LPDWORD lpdwProcessList
,
2378 DWORD dwProcessCount
)
2380 CONSOLE_API_MESSAGE ApiMessage
;
2381 PCONSOLE_GETPROCESSLIST GetProcessListRequest
= &ApiMessage
.Data
.GetProcessListRequest
;
2382 PCSR_CAPTURE_BUFFER CaptureBuffer
;
2383 ULONG nProcesses
= 0;
2385 if (lpdwProcessList
== NULL
|| dwProcessCount
== 0)
2387 SetLastError(ERROR_INVALID_PARAMETER
);
2391 CaptureBuffer
= CsrAllocateCaptureBuffer(1, dwProcessCount
* sizeof(DWORD
));
2392 if (CaptureBuffer
== NULL
)
2394 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2395 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2399 GetProcessListRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2400 GetProcessListRequest
->ProcessCount
= dwProcessCount
;
2402 CsrAllocateMessagePointer(CaptureBuffer
,
2403 dwProcessCount
* sizeof(DWORD
),
2404 (PVOID
*)&GetProcessListRequest
->ProcessIdsList
);
2406 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2408 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetProcessList
),
2409 sizeof(*GetProcessListRequest
));
2410 if (!NT_SUCCESS(ApiMessage
.Status
))
2412 BaseSetLastNTError(ApiMessage
.Status
);
2416 nProcesses
= GetProcessListRequest
->ProcessCount
;
2417 if (dwProcessCount
>= nProcesses
)
2419 memcpy(lpdwProcessList
, GetProcessListRequest
->ProcessIdsList
, nProcesses
* sizeof(DWORD
));
2423 CsrFreeCaptureBuffer(CaptureBuffer
);
2433 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo
)
2435 CONSOLE_API_MESSAGE ApiMessage
;
2436 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest
= &ApiMessage
.Data
.GetSelectionInfoRequest
;
2438 if (lpConsoleSelectionInfo
== NULL
)
2440 SetLastError(ERROR_INVALID_PARAMETER
);
2444 GetSelectionInfoRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2446 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2448 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetSelectionInfo
),
2449 sizeof(*GetSelectionInfoRequest
));
2450 if (!NT_SUCCESS(ApiMessage
.Status
))
2452 BaseSetLastNTError(ApiMessage
.Status
);
2456 *lpConsoleSelectionInfo
= GetSelectionInfoRequest
->Info
;
2464 * @note Strongly inspired by AllocConsole.
2467 IntAttachConsole(DWORD ProcessId
,
2468 LPTHREAD_START_ROUTINE CtrlRoutine
,
2469 LPTHREAD_START_ROUTINE PropRoutine
,
2470 PCONSOLE_START_INFO ConsoleStartInfo
)
2472 BOOL Success
= TRUE
;
2473 #ifdef USE_CONSOLE_INIT_HANDLES
2477 CONSOLE_API_MESSAGE ApiMessage
;
2478 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest
= &ApiMessage
.Data
.AttachConsoleRequest
;
2479 PCSR_CAPTURE_BUFFER CaptureBuffer
;
2481 AttachConsoleRequest
->ProcessId
= ProcessId
;
2482 AttachConsoleRequest
->CtrlRoutine
= CtrlRoutine
;
2483 AttachConsoleRequest
->PropRoutine
= PropRoutine
;
2485 CaptureBuffer
= CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO
));
2486 if (CaptureBuffer
== NULL
)
2488 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
2493 CsrCaptureMessageBuffer(CaptureBuffer
,
2495 sizeof(CONSOLE_START_INFO
),
2496 (PVOID
*)&AttachConsoleRequest
->ConsoleStartInfo
);
2498 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2500 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepAttach
),
2501 sizeof(*AttachConsoleRequest
));
2502 if (!NT_SUCCESS(ApiMessage
.Status
))
2504 BaseSetLastNTError(ApiMessage
.Status
);
2509 #ifdef USE_CONSOLE_INIT_HANDLES
2510 // Is AttachConsoleRequest->ConsoleStartInfo->Events aligned on handle boundary ????
2511 Status
= NtWaitForMultipleObjects(2, AttachConsoleRequest
->ConsoleStartInfo
->Events
,
2512 WaitAny
, FALSE
, NULL
);
2513 if (!NT_SUCCESS(Status
))
2515 BaseSetLastNTError(Status
);
2520 NtClose(AttachConsoleRequest
->ConsoleStartInfo
->Events
[0]);
2521 NtClose(AttachConsoleRequest
->ConsoleStartInfo
->Events
[1]);
2522 if (Status
!= STATUS_SUCCESS
)
2524 NtCurrentPeb()->ProcessParameters
->ConsoleHandle
= NULL
;
2530 RtlCopyMemory(ConsoleStartInfo
,
2531 AttachConsoleRequest
->ConsoleStartInfo
,
2532 sizeof(CONSOLE_START_INFO
));
2537 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
2543 AttachConsole(DWORD dwProcessId
)
2546 CONSOLE_START_INFO ConsoleStartInfo
;
2551 RtlEnterCriticalSection(&ConsoleLock
);
2553 if (NtCurrentPeb()->ProcessParameters
->ConsoleHandle
)
2555 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2556 SetLastError(ERROR_ACCESS_DENIED
);
2561 /* Set up the console properties */
2562 SetUpConsoleInfo(FALSE
,
2569 Success
= IntAttachConsole(dwProcessId
,
2570 ConsoleControlDispatcher
,
2575 /* Set up the handles */
2576 SetUpHandles(&ConsoleStartInfo
);
2577 InputWaitHandle
= ConsoleStartInfo
.InputWaitHandle
;
2579 /* Initialize Console Ctrl Handling */
2580 InitializeCtrlHandling();
2582 /* Sets the current console locale for this thread */
2587 RtlLeaveCriticalSection(&ConsoleLock
);
2597 GetConsoleWindow(VOID
)
2599 CONSOLE_API_MESSAGE ApiMessage
;
2600 PCONSOLE_GETWINDOW GetWindowRequest
= &ApiMessage
.Data
.GetWindowRequest
;
2602 GetWindowRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2604 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2606 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetConsoleWindow
),
2607 sizeof(*GetWindowRequest
));
2608 if (!NT_SUCCESS(ApiMessage
.Status
))
2610 BaseSetLastNTError(ApiMessage
.Status
);
2614 return GetWindowRequest
->WindowHandle
;
2623 SetConsoleIcon(HICON hIcon
)
2625 CONSOLE_API_MESSAGE ApiMessage
;
2626 PCONSOLE_SETICON SetIconRequest
= &ApiMessage
.Data
.SetIconRequest
;
2628 SetIconRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2629 SetIconRequest
->IconHandle
= hIcon
;
2631 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2633 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepSetIcon
),
2634 sizeof(*SetIconRequest
));
2635 if (!NT_SUCCESS(ApiMessage
.Status
))
2637 BaseSetLastNTError(ApiMessage
.Status
);
2645 /******************************************************************************
2646 * \name SetConsoleInputExeNameW
2647 * \brief Sets the console input file name from a unicode string.
2648 * \param lpExeName Pointer to a unicode string with the name.
2649 * \return TRUE if successful, FALSE if unsuccsedful.
2650 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255,
2651 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2655 SetConsoleInputExeNameW(IN LPWSTR lpExeName
)
2659 ExeLength
= lstrlenW(lpExeName
);
2660 if ((ExeLength
== 0) || (ExeLength
>= EXENAME_LENGTH
))
2662 /* Fail if string is empty or too long */
2663 SetLastError(ERROR_INVALID_PARAMETER
);
2667 RtlEnterCriticalSection(&ExeNameLock
);
2670 /* Set the input EXE name, not NULL terminated */
2671 RtlCopyMemory(ExeNameBuffer
, lpExeName
, ExeLength
* sizeof(WCHAR
));
2672 ExeNameLength
= (USHORT
)ExeLength
;
2676 RtlLeaveCriticalSection(&ExeNameLock
);
2684 /******************************************************************************
2685 * \name SetConsoleInputExeNameA
2686 * \brief Sets the console input file name from an ansi string.
2687 * \param lpExeName Pointer to an ansi string with the name.
2688 * \return TRUE if successful, FALSE if unsuccsedful.
2689 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255,
2690 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2694 SetConsoleInputExeNameA(IN LPSTR lpExeName
)
2697 #ifdef USE_TEB_STATIC_USTR
2698 PUNICODE_STRING ExeNameU
;
2700 UNICODE_STRING ExeNameU
;
2702 ANSI_STRING ExeNameA
;
2703 #ifndef USE_TEB_STATIC_USTR
2704 WCHAR Buffer
[EXENAME_LENGTH
];
2707 #ifdef USE_TEB_STATIC_USTR
2709 * Use the TEB static UNICODE string for storage. It is already
2710 * initialized at process creation time by the Memory Manager.
2712 ExeNameU
= &NtCurrentTeb()->StaticUnicodeString
;
2715 /* Initialize string for conversion */
2716 RtlInitAnsiString(&ExeNameA
, lpExeName
);
2719 if ((ExeNameA
.Length
== 0) || (ExeNameA
.Length
>= EXENAME_LENGTH
))
2721 /* Fail if string is empty or too long */
2722 SetLastError(ERROR_INVALID_PARAMETER
);
2726 #ifndef USE_TEB_STATIC_USTR
2727 ExeNameU
.Length
= 0;
2728 ExeNameU
.MaximumLength
= (USHORT
)sizeof(Buffer
);
2729 ExeNameU
.Buffer
= Buffer
;
2732 #ifdef USE_TEB_STATIC_USTR
2733 Status
= RtlAnsiStringToUnicodeString(ExeNameU
, &ExeNameA
, FALSE
);
2735 Status
= RtlAnsiStringToUnicodeString(&ExeNameU
, &ExeNameA
, FALSE
);
2737 if (!NT_SUCCESS(Status
))
2739 /* Fail if string is empty or too long */
2740 if (Status
== STATUS_BUFFER_OVERFLOW
)
2741 SetLastError(ERROR_FILENAME_EXCED_RANGE
);
2743 SetLastError(ERROR_INVALID_PARAMETER
);
2748 #ifdef USE_TEB_STATIC_USTR
2749 return SetConsoleInputExeNameW(ExeNameU
->Buffer
);
2751 return SetConsoleInputExeNameW(ExeNameU
.Buffer
);
2756 /******************************************************************************
2757 * \name GetConsoleInputExeNameW
2758 * \brief Retrieves the console input file name as unicode string.
2759 * \param nBufferLength Length of the buffer in WCHARs.
2760 * Specify 0 to receive the needed buffer length.
2761 * \param lpBuffer Pointer to a buffer that receives the string.
2762 * \return Needed buffer size if \p nBufferLength is 0.
2763 * Otherwise 1 if successful, 2 if buffer is too small.
2764 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2765 * is not big enough.
2769 GetConsoleInputExeNameW(IN DWORD nBufferLength
,
2770 OUT LPWSTR lpExeName
)
2772 if (nBufferLength
<= ExeNameLength
)
2774 /* Buffer is not large enough! Return the correct size. */
2775 SetLastError(ERROR_BUFFER_OVERFLOW
);
2776 return ExeNameLength
+ 1;
2779 RtlEnterCriticalSection(&ExeNameLock
);
2782 /* Copy the input EXE name and NULL-terminate it */
2783 RtlCopyMemory(lpExeName
, ExeNameBuffer
, ExeNameLength
* sizeof(WCHAR
));
2784 lpExeName
[ExeNameLength
] = UNICODE_NULL
;
2788 RtlLeaveCriticalSection(&ExeNameLock
);
2796 /******************************************************************************
2797 * \name GetConsoleInputExeNameA
2798 * \brief Retrieves the console input file name as ansi string.
2799 * \param nBufferLength Length of the buffer in CHARs.
2800 * \param lpBuffer Pointer to a buffer that receives the string.
2801 * \return 1 if successful, 2 if buffer is too small.
2802 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2803 * is not big enough. The buffer receives as much characters as fit.
2807 GetConsoleInputExeNameA(IN DWORD nBufferLength
,
2808 OUT LPSTR lpExeName
)
2812 UNICODE_STRING BufferU
;
2813 ANSI_STRING BufferA
;
2814 WCHAR Buffer
[EXENAME_LENGTH
];
2816 /* Get the UNICODE name */
2817 ExeLength
= GetConsoleInputExeNameW(EXENAME_LENGTH
, Buffer
);
2819 if ((ExeLength
== 0) || (ExeLength
>= EXENAME_LENGTH
))
2822 /* Initialize the strings for conversion */
2823 RtlInitUnicodeString(&BufferU
, Buffer
);
2825 BufferA
.MaximumLength
= (USHORT
)nBufferLength
;
2826 BufferA
.Buffer
= lpExeName
;
2828 /* Convert UNICODE name to ANSI, copying as much chars as it can fit */
2829 Status
= RtlUnicodeStringToAnsiString(&BufferA
, &BufferU
, FALSE
);
2830 if (!NT_SUCCESS(Status
))
2832 if (Status
== STATUS_BUFFER_OVERFLOW
)
2834 SetLastError(ERROR_BUFFER_OVERFLOW
);
2835 return ExeLength
+ 1;
2837 SetLastError(ERROR_INVALID_PARAMETER
);
2845 GetConsoleCharType(HANDLE hConsole
, COORD Coord
, PDWORD Type
)
2853 GetConsoleCursorMode(HANDLE hConsole
, PBOOL pUnknown1
, PBOOL pUnknown2
)
2861 SetConsoleCursorMode(HANDLE hConsole
, BOOL Unknown1
, BOOL Unknown2
)
2869 GetConsoleNlsMode(HANDLE hConsole
, LPDWORD lpMode
)
2877 SetConsoleNlsMode(HANDLE hConsole
, DWORD dwMode
)
2885 SetConsoleLocalEUDC(DWORD Unknown1
, DWORD Unknown2
, DWORD Unknown3
, DWORD Unknown4
)
2893 RegisterConsoleIME(HWND hWnd
, LPDWORD ThreadId
)
2901 RegisterConsoleOS2(BOOL bUnknown
)
2909 SetConsoleOS2OemFormat(BOOL bUnknown
)
2917 UnregisterConsoleIME(VOID
)
2925 IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName
,
2928 CONSOLE_API_MESSAGE ApiMessage
;
2929 PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest
= &ApiMessage
.Data
.GetKbdLayoutNameRequest
;
2931 /* Set up the data to send to the Console Server */
2932 GetKbdLayoutNameRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
2933 GetKbdLayoutNameRequest
->Ansi
= bAnsi
;
2935 /* Call the server */
2936 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
2938 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetKeyboardLayoutName
),
2939 sizeof(*GetKbdLayoutNameRequest
));
2941 /* Check for success */
2942 if (!NT_SUCCESS(ApiMessage
.Status
))
2944 BaseSetLastNTError(ApiMessage
.Status
);
2948 /* Retrieve the results */
2951 /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */
2953 strncpy(pszLayoutName
, (PCHAR
)GetKbdLayoutNameRequest
->LayoutBuffer
, KL_NAMELENGTH
);
2955 wcsncpy(pszLayoutName
, (PWCHAR
)GetKbdLayoutNameRequest
->LayoutBuffer
, KL_NAMELENGTH
);
2957 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
2959 SetLastError(ERROR_INVALID_ACCESS
);
2960 _SEH2_YIELD(return FALSE
);
2968 * @implemented (undocumented)
2972 GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName
)
2974 return IntGetConsoleKeyboardLayoutName(pszLayoutName
, TRUE
);
2978 * @implemented (undocumented)
2982 GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName
)
2984 return IntGetConsoleKeyboardLayoutName(pszLayoutName
, FALSE
);
2992 SetLastConsoleEventActive(VOID
)
2994 CONSOLE_API_MESSAGE ApiMessage
;
2995 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest
= &ApiMessage
.Data
.NotifyLastCloseRequest
;
2997 /* Set the flag used by the console control dispatcher */
2998 LastCloseNotify
= TRUE
;
3000 /* Set up the input arguments */
3001 NotifyLastCloseRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
3003 /* Call CSRSS; just return the NTSTATUS cast to DWORD */
3004 return CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
3006 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepNotifyLastClose
),
3007 sizeof(*NotifyLastCloseRequest
));