[kernel32]
[reactos.git] / reactos / dll / win32 / kernel32 / client / console / console.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/console/console.c
5 * PURPOSE: Win32 server console functions
6 * PROGRAMMERS: James Tabor
7 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <k32.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17
18 /* GLOBALS ********************************************************************/
19
20 extern RTL_CRITICAL_SECTION ConsoleLock;
21 extern BOOL ConsoleInitialized;
22 extern BOOL WINAPI IsDebuggerPresent(VOID);
23
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;
28
29 PHANDLER_ROUTINE InitialHandler[1];
30 PHANDLER_ROUTINE* CtrlHandlers;
31 ULONG NrCtrlHandlers;
32 ULONG NrAllocatedHandlers;
33
34 HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
35
36 #define INPUTEXENAME_BUFLEN 256
37 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
38
39
40 /* Default Console Control Handler ********************************************/
41
42 BOOL
43 WINAPI
44 DefaultConsoleCtrlHandler(DWORD Event)
45 {
46 DPRINT("Default handler called: %lx\n", Event);
47 switch(Event)
48 {
49 case CTRL_C_EVENT:
50 DPRINT("Ctrl-C Event\n");
51 break;
52
53 case CTRL_BREAK_EVENT:
54 DPRINT("Ctrl-Break Event\n");
55 break;
56
57 case CTRL_CLOSE_EVENT:
58 DPRINT("Ctrl Close Event\n");
59 break;
60
61 case CTRL_LOGOFF_EVENT:
62 DPRINT("Ctrl Logoff Event\n");
63 break;
64
65 case CTRL_SHUTDOWN_EVENT:
66 DPRINT("Ctrl Shutdown Event\n");
67 break;
68 }
69
70 ExitProcess(CONTROL_C_EXIT);
71 return TRUE;
72 }
73
74 DWORD
75 WINAPI
76 ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
77 {
78 DWORD nExitCode = 0;
79 DWORD CodeAndFlag = PtrToUlong(lpThreadParameter);
80 DWORD nCode = CodeAndFlag & MAXLONG;
81 UINT i;
82 EXCEPTION_RECORD erException;
83
84 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
85 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
86
87 switch(nCode)
88 {
89 case CTRL_C_EVENT:
90 case CTRL_BREAK_EVENT:
91 {
92 if (IsDebuggerPresent())
93 {
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;
100
101 _SEH2_TRY
102 {
103 RtlRaiseException(&erException);
104 }
105 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
106 {
107 RtlEnterCriticalSection(&ConsoleLock);
108
109 if ((nCode != CTRL_C_EVENT) ||
110 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
111 {
112 for (i = NrCtrlHandlers; i > 0; i--)
113 {
114 if (CtrlHandlers[i - 1](nCode)) break;
115 }
116 }
117
118 RtlLeaveCriticalSection(&ConsoleLock);
119 }
120 _SEH2_END;
121
122 ExitThread(0);
123 }
124 break;
125 }
126
127 case CTRL_CLOSE_EVENT:
128 case CTRL_LOGOFF_EVENT:
129 case CTRL_SHUTDOWN_EVENT:
130 break;
131
132 case 3:
133 ExitThread(0);
134 break;
135
136 case 4:
137 ExitProcess(CONTROL_C_EXIT);
138 break;
139
140 default:
141 ASSERT(FALSE);
142 break;
143 }
144
145 ASSERT(ConsoleInitialized);
146
147 RtlEnterCriticalSection(&ConsoleLock);
148
149 nExitCode = 0;
150 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
151 {
152 for (i = NrCtrlHandlers; i > 0; i--)
153 {
154 if ((i == 1) &&
155 (CodeAndFlag & MINLONG) &&
156 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
157 {
158 DPRINT("Skipping system/service apps\n");
159 break;
160 }
161
162 if (CtrlHandlers[i - 1](nCode))
163 {
164 switch(nCode)
165 {
166 case CTRL_CLOSE_EVENT:
167 case CTRL_LOGOFF_EVENT:
168 case CTRL_SHUTDOWN_EVENT:
169 case 3:
170 nExitCode = CodeAndFlag;
171 break;
172 }
173 break;
174 }
175 }
176 }
177
178 RtlLeaveCriticalSection(&ConsoleLock);
179
180 ExitThread(nExitCode);
181 return STATUS_SUCCESS;
182 }
183
184 VOID
185 WINAPI
186 InitConsoleCtrlHandling(VOID)
187 {
188 /* Initialize Console Ctrl Handler */
189 NrAllocatedHandlers = NrCtrlHandlers = 1;
190 CtrlHandlers = InitialHandler;
191 CtrlHandlers[0] = DefaultConsoleCtrlHandler;
192 }
193
194
195 /* FUNCTIONS ******************************************************************/
196
197 LPCWSTR
198 IntCheckForConsoleFileName(IN LPCWSTR pszName,
199 IN DWORD dwDesiredAccess)
200 {
201 LPCWSTR ConsoleName = pszName;
202 ULONG DeviceNameInfo;
203
204 /*
205 * Check whether we deal with a DOS device, and if so,
206 * strip the path till the file name.
207 * Therefore, things like \\.\CON or C:\some_path\CONIN$
208 * are transformed into CON or CONIN$, for example.
209 */
210 DeviceNameInfo = RtlIsDosDeviceName_U(pszName);
211 if (DeviceNameInfo != 0)
212 {
213 ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF));
214 }
215
216 /* Return a standard console "file" name according to what we passed in parameters */
217 if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0)
218 {
219 return BaseConInputFileName;
220 }
221 else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0)
222 {
223 return BaseConOutputFileName;
224 }
225 else if (_wcsicmp(ConsoleName, BaseConFileName) == 0)
226 {
227 if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ)
228 {
229 return BaseConInputFileName;
230 }
231 else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE)
232 {
233 return BaseConOutputFileName;
234 }
235 }
236
237 /* If we are there, that means that either the file name or the desired access are wrong */
238 return NULL;
239 }
240
241
242 /*
243 * @implemented (Undocumented)
244 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php
245 */
246 HMENU
247 WINAPI
248 ConsoleMenuControl(HANDLE hConsoleOutput,
249 DWORD dwCmdIdLow,
250 DWORD dwCmdIdHigh)
251 {
252 CONSOLE_API_MESSAGE ApiMessage;
253 PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest;
254
255 MenuControlRequest->OutputHandle = hConsoleOutput;
256 MenuControlRequest->dwCmdIdLow = dwCmdIdLow;
257 MenuControlRequest->dwCmdIdHigh = dwCmdIdHigh;
258 MenuControlRequest->hMenu = NULL;
259
260 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
261 NULL,
262 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepMenuControl),
263 sizeof(CONSOLE_MENUCONTROL));
264
265 return MenuControlRequest->hMenu;
266 }
267
268
269 /*
270 * @implemented
271 */
272 HANDLE
273 WINAPI
274 DuplicateConsoleHandle(HANDLE hConsole,
275 DWORD dwDesiredAccess,
276 BOOL bInheritHandle,
277 DWORD dwOptions)
278 {
279 NTSTATUS Status;
280 CONSOLE_API_MESSAGE ApiMessage;
281 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest;
282
283 if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) ||
284 (!(dwOptions & DUPLICATE_SAME_ACCESS) &&
285 (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) )
286 {
287 SetLastError (ERROR_INVALID_PARAMETER);
288 return INVALID_HANDLE_VALUE;
289 }
290
291 DuplicateHandleRequest->ConsoleHandle = hConsole;
292 DuplicateHandleRequest->Access = dwDesiredAccess;
293 DuplicateHandleRequest->Inheritable = bInheritHandle;
294 DuplicateHandleRequest->Options = dwOptions;
295
296 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
297 NULL,
298 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle),
299 sizeof(CONSOLE_DUPLICATEHANDLE));
300 if (!NT_SUCCESS(Status))
301 {
302 BaseSetLastNTError(Status);
303 return INVALID_HANDLE_VALUE;
304 }
305
306 return DuplicateHandleRequest->ConsoleHandle;
307 }
308
309
310 /*
311 * @implemented
312 */
313 BOOL
314 WINAPI
315 GetConsoleDisplayMode(LPDWORD lpModeFlags)
316 {
317 NTSTATUS Status;
318 CONSOLE_API_MESSAGE ApiMessage;
319 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest;
320
321 if (lpModeFlags == NULL)
322 {
323 SetLastError(ERROR_INVALID_PARAMETER);
324 return FALSE;
325 }
326
327 // GetDisplayModeRequest->OutputHandle = hConsoleOutput;
328
329 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
330 NULL,
331 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode),
332 sizeof(CONSOLE_GETDISPLAYMODE));
333 if (!NT_SUCCESS(Status))
334 {
335 BaseSetLastNTError(Status);
336 return FALSE;
337 }
338
339 *lpModeFlags = GetDisplayModeRequest->DisplayMode;
340 return TRUE;
341 }
342
343
344 /*
345 * @unimplemented (Undocumented)
346 */
347 DWORD
348 WINAPI
349 GetConsoleFontInfo(HANDLE hConsoleOutput,
350 BOOL bMaximumWindow,
351 DWORD nFontCount,
352 PCONSOLE_FONT_INFO lpConsoleFontInfo)
353 {
354 DPRINT1("GetConsoleFontInfo(0x%p, %d, %lu, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, nFontCount, lpConsoleFontInfo);
355 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
356 return 0;
357 }
358
359
360 /*
361 * @unimplemented
362 */
363 COORD
364 WINAPI
365 GetConsoleFontSize(HANDLE hConsoleOutput,
366 DWORD nFont)
367 {
368 COORD Empty = {0, 0};
369 DPRINT1("GetConsoleFontSize(0x%p, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
370 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
371 return Empty;
372 }
373
374
375 /*
376 * @implemented (Undocumented)
377 */
378 BOOL
379 WINAPI
380 GetConsoleHardwareState(HANDLE hConsoleOutput,
381 DWORD Flags,
382 PDWORD State)
383 {
384 NTSTATUS Status;
385 CONSOLE_API_MESSAGE ApiMessage;
386 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
387
388 DPRINT1("GetConsoleHardwareState(%lu, 0x%p) UNIMPLEMENTED!\n", Flags, State);
389
390 if (State == NULL)
391 {
392 SetLastError(ERROR_INVALID_PARAMETER);
393 return FALSE;
394 }
395
396 HardwareStateRequest->OutputHandle = hConsoleOutput;
397
398 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
399 NULL,
400 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState),
401 sizeof(CONSOLE_GETSETHWSTATE));
402 if (!NT_SUCCESS(Status))
403 {
404 BaseSetLastNTError(Status);
405 return FALSE;
406 }
407
408 *State = HardwareStateRequest->State;
409 return TRUE;
410 }
411
412
413 /*
414 * @implemented (Undocumented)
415 */
416 HANDLE
417 WINAPI
418 GetConsoleInputWaitHandle(VOID)
419 {
420 return InputWaitHandle;
421 }
422
423
424 /*
425 * @unimplemented
426 */
427 BOOL
428 WINAPI
429 GetCurrentConsoleFont(HANDLE hConsoleOutput,
430 BOOL bMaximumWindow,
431 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
432 {
433 DPRINT1("GetCurrentConsoleFont(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
434 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
435 return 0;
436 }
437
438
439 /*
440 * @unimplemented (Undocumented)
441 */
442 ULONG
443 WINAPI
444 GetNumberOfConsoleFonts(VOID)
445 {
446 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
447 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
448 return 1;
449 }
450
451
452 /*
453 * @implemented (Undocumented)
454 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
455 */
456 BOOL
457 WINAPI
458 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
459 IN PSMALL_RECT lpRect)
460 {
461 NTSTATUS Status;
462 CONSOLE_API_MESSAGE ApiMessage;
463 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest;
464
465 if (lpRect == NULL)
466 {
467 SetLastError(ERROR_INVALID_PARAMETER);
468 return FALSE;
469 }
470
471 InvalidateDIBitsRequest->OutputHandle = hConsoleOutput;
472 InvalidateDIBitsRequest->Region = *lpRect;
473
474 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
475 NULL,
476 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect),
477 sizeof(CONSOLE_INVALIDATEDIBITS));
478 if (!NT_SUCCESS(Status))
479 {
480 BaseSetLastNTError(Status);
481 return FALSE;
482 }
483
484 return TRUE;
485 }
486
487
488 /*
489 * @unimplemented (Undocumented)
490 */
491 HANDLE
492 WINAPI
493 OpenConsoleW(LPCWSTR wsName,
494 DWORD dwDesiredAccess,
495 BOOL bInheritHandle,
496 DWORD dwShareMode)
497 {
498 NTSTATUS Status = STATUS_SUCCESS;
499 CONSOLE_API_MESSAGE ApiMessage;
500 PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest;
501 CONSOLE_HANDLE_TYPE HandleType;
502
503 if (wsName && 0 == _wcsicmp(wsName, BaseConInputFileName))
504 {
505 HandleType = HANDLE_INPUT;
506 }
507 else if (wsName && 0 == _wcsicmp(wsName, BaseConOutputFileName))
508 {
509 HandleType = HANDLE_OUTPUT;
510 }
511 else
512 {
513 SetLastError(ERROR_INVALID_PARAMETER);
514 return INVALID_HANDLE_VALUE;
515 }
516
517 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
518 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) )
519 {
520 SetLastError(ERROR_INVALID_PARAMETER);
521 return INVALID_HANDLE_VALUE;
522 }
523
524 OpenConsoleRequest->HandleType = HandleType;
525 OpenConsoleRequest->Access = dwDesiredAccess;
526 OpenConsoleRequest->Inheritable = bInheritHandle;
527 OpenConsoleRequest->ShareMode = dwShareMode;
528
529 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
530 NULL,
531 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole),
532 sizeof(CONSOLE_OPENCONSOLE));
533 if (!NT_SUCCESS(Status))
534 {
535 BaseSetLastNTError(Status);
536 return INVALID_HANDLE_VALUE;
537 }
538
539 return OpenConsoleRequest->ConsoleHandle;
540 }
541
542
543 /*
544 * @implemented (Undocumented)
545 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleCursor.php
546 */
547 BOOL
548 WINAPI
549 SetConsoleCursor(HANDLE hConsoleOutput,
550 HCURSOR hCursor)
551 {
552 NTSTATUS Status;
553 CONSOLE_API_MESSAGE ApiMessage;
554 PCONSOLE_SETCURSOR SetCursorRequest = &ApiMessage.Data.SetCursorRequest;
555
556 SetCursorRequest->OutputHandle = hConsoleOutput;
557 SetCursorRequest->hCursor = hCursor;
558
559 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
560 NULL,
561 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursor),
562 sizeof(CONSOLE_SETCURSOR));
563 if (!NT_SUCCESS(Status))
564 {
565 BaseSetLastNTError(Status);
566 return FALSE;
567 }
568
569 return TRUE;
570 }
571
572
573 /*
574 * @implemented
575 */
576 BOOL
577 WINAPI
578 SetConsoleDisplayMode(HANDLE hConsoleOutput,
579 DWORD dwFlags,
580 PCOORD lpNewScreenBufferDimensions)
581 {
582 NTSTATUS Status;
583 CONSOLE_API_MESSAGE ApiMessage;
584 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest;
585
586 SetDisplayModeRequest->OutputHandle = hConsoleOutput;
587 SetDisplayModeRequest->DisplayMode = dwFlags;
588 SetDisplayModeRequest->NewSBDim.X = 0;
589 SetDisplayModeRequest->NewSBDim.Y = 0;
590
591 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
592 NULL,
593 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode),
594 sizeof(CONSOLE_SETDISPLAYMODE));
595 if (!NT_SUCCESS(Status))
596 {
597 BaseSetLastNTError(Status);
598 return FALSE;
599 }
600
601 if (lpNewScreenBufferDimensions)
602 *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim;
603
604 return TRUE;
605 }
606
607
608 /*
609 * @unimplemented (Undocumented)
610 */
611 BOOL
612 WINAPI
613 SetConsoleFont(HANDLE hConsoleOutput,
614 DWORD nFont)
615 {
616 DPRINT1("SetConsoleFont(0x%p, %lu) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
617 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
618 return FALSE;
619 }
620
621
622 /*
623 * @implemented (Undocumented)
624 */
625 BOOL
626 WINAPI
627 SetConsoleHardwareState(HANDLE hConsoleOutput,
628 DWORD Flags,
629 DWORD State)
630 {
631 NTSTATUS Status;
632 CONSOLE_API_MESSAGE ApiMessage;
633 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
634
635 DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags, State);
636
637 HardwareStateRequest->OutputHandle = hConsoleOutput;
638 HardwareStateRequest->State = State;
639
640 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
641 NULL,
642 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState),
643 sizeof(CONSOLE_GETSETHWSTATE));
644 if (!NT_SUCCESS(Status))
645 {
646 BaseSetLastNTError(Status);
647 return FALSE;
648 }
649
650 return TRUE;
651 }
652
653
654 /*
655 * @unimplemented (Undocumented)
656 */
657 BOOL
658 WINAPI
659 SetConsoleKeyShortcuts(DWORD Unknown0,
660 DWORD Unknown1,
661 DWORD Unknown2,
662 DWORD Unknown3)
663 {
664 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
665 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
666 return FALSE;
667 }
668
669
670 /*
671 * @implemented (Undocumented)
672 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php
673 * Does nothing, returns TRUE only. Checked on Windows Server 2003.
674 */
675 BOOL
676 WINAPI
677 SetConsoleMaximumWindowSize(HANDLE hConsoleOutput,
678 COORD dwMaximumSize)
679 {
680 DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n",
681 hConsoleOutput, dwMaximumSize.X, dwMaximumSize.Y);
682 return TRUE;
683 }
684
685
686 /*
687 * @implemented (Undocumented)
688 */
689 BOOL
690 WINAPI
691 SetConsoleMenuClose(BOOL bEnable)
692 {
693 NTSTATUS Status;
694 CONSOLE_API_MESSAGE ApiMessage;
695 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest;
696
697 SetMenuCloseRequest->Enable = bEnable;
698
699 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
700 NULL,
701 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose),
702 sizeof(CONSOLE_SETMENUCLOSE));
703 if (!NT_SUCCESS(Status))
704 {
705 BaseSetLastNTError(Status);
706 return FALSE;
707 }
708
709 return TRUE;
710 }
711
712
713 /*
714 * @implemented (Undocumented)
715 * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844
716 * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52
717 */
718 BOOL
719 WINAPI
720 SetConsolePalette(HANDLE hConsoleOutput,
721 HPALETTE hPalette,
722 UINT dwUsage)
723 {
724 NTSTATUS Status;
725 CONSOLE_API_MESSAGE ApiMessage;
726 PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest;
727
728 SetPaletteRequest->OutputHandle = hConsoleOutput;
729 SetPaletteRequest->PaletteHandle = hPalette;
730 SetPaletteRequest->Usage = dwUsage;
731
732 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
733 NULL,
734 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetPalette),
735 sizeof(CONSOLE_SETPALETTE));
736 if (!NT_SUCCESS(Status))
737 {
738 BaseSetLastNTError(Status);
739 return FALSE;
740 }
741
742 return TRUE;
743 }
744
745 /*
746 * @implemented (Undocumented)
747 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php
748 */
749 INT
750 WINAPI
751 ShowConsoleCursor(HANDLE hConsoleOutput,
752 BOOL bShow)
753 {
754 CONSOLE_API_MESSAGE ApiMessage;
755 PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest;
756
757 ShowCursorRequest->OutputHandle = hConsoleOutput;
758 ShowCursorRequest->Show = bShow;
759 ShowCursorRequest->RefCount = 0;
760
761 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
762 NULL,
763 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepShowCursor),
764 sizeof(CONSOLE_SHOWCURSOR));
765
766 return ShowCursorRequest->RefCount;
767 }
768
769
770 /*
771 * FUNCTION: Checks whether the given handle is a valid console handle.
772 *
773 * ARGUMENTS:
774 * Handle - Handle to be checked
775 *
776 * RETURNS:
777 * TRUE: Handle is a valid console handle
778 * FALSE: Handle is not a valid console handle.
779 *
780 * STATUS: Officially undocumented
781 *
782 * @implemented
783 */
784 BOOL
785 WINAPI
786 VerifyConsoleIoHandle(HANDLE Handle)
787 {
788 NTSTATUS Status;
789 CONSOLE_API_MESSAGE ApiMessage;
790
791 ApiMessage.Data.VerifyHandleRequest.ConsoleHandle = Handle;
792
793 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
794 NULL,
795 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle),
796 sizeof(CONSOLE_VERIFYHANDLE));
797 if (!NT_SUCCESS(Status))
798 {
799 return FALSE;
800 }
801
802 return TRUE;
803 }
804
805
806 /*
807 * @implemented (Undocumented)
808 */
809 BOOL
810 WINAPI
811 CloseConsoleHandle(HANDLE Handle)
812 {
813 NTSTATUS Status;
814 CONSOLE_API_MESSAGE ApiMessage;
815
816 ApiMessage.Data.CloseHandleRequest.ConsoleHandle = Handle;
817
818 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
819 NULL,
820 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle),
821 sizeof(CONSOLE_CLOSEHANDLE));
822 if (!NT_SUCCESS(Status))
823 {
824 BaseSetLastNTError(Status);
825 return FALSE;
826 }
827
828 return TRUE;
829 }
830
831
832 /*
833 * @implemented
834 */
835 HANDLE
836 WINAPI
837 GetStdHandle(DWORD nStdHandle)
838 /*
839 * FUNCTION: Get a handle for the standard input, standard output
840 * and a standard error device.
841 *
842 * ARGUMENTS:
843 * nStdHandle - Specifies the device for which to return the handle.
844 *
845 * RETURNS: If the function succeeds, the return value is the handle
846 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
847 */
848 {
849 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
850
851 switch (nStdHandle)
852 {
853 case STD_INPUT_HANDLE:
854 return Ppb->StandardInput;
855
856 case STD_OUTPUT_HANDLE:
857 return Ppb->StandardOutput;
858
859 case STD_ERROR_HANDLE:
860 return Ppb->StandardError;
861 }
862
863 SetLastError(ERROR_INVALID_HANDLE);
864 return INVALID_HANDLE_VALUE;
865 }
866
867
868 /*
869 * @implemented
870 */
871 BOOL
872 WINAPI
873 SetStdHandle(DWORD nStdHandle,
874 HANDLE hHandle)
875 /*
876 * FUNCTION: Set the handle for the standard input, standard output or
877 * the standard error device.
878 *
879 * ARGUMENTS:
880 * nStdHandle - Specifies the handle to be set.
881 * hHandle - The handle to set.
882 *
883 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
884 */
885 {
886 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
887
888 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
889
890 switch (nStdHandle)
891 {
892 case STD_INPUT_HANDLE:
893 Ppb->StandardInput = hHandle;
894 return TRUE;
895
896 case STD_OUTPUT_HANDLE:
897 Ppb->StandardOutput = hHandle;
898 return TRUE;
899
900 case STD_ERROR_HANDLE:
901 Ppb->StandardError = hHandle;
902 return TRUE;
903 }
904
905 /* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
906 SetLastError(ERROR_INVALID_HANDLE);
907 return FALSE;
908 }
909
910
911 /*--------------------------------------------------------------
912 * AllocConsole
913 *
914 * @implemented
915 */
916 BOOL
917 WINAPI
918 AllocConsole(VOID)
919 {
920 NTSTATUS Status;
921 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
922 CONSOLE_API_MESSAGE ApiMessage;
923 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
924 PCSR_CAPTURE_BUFFER CaptureBuffer;
925
926 if (Parameters->ConsoleHandle)
927 {
928 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
929 SetLastError(ERROR_ACCESS_DENIED);
930 return FALSE;
931 }
932
933 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
934 if (CaptureBuffer == NULL)
935 {
936 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
937 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
938 return FALSE;
939 }
940
941 CsrAllocateMessagePointer(CaptureBuffer,
942 sizeof(CONSOLE_START_INFO),
943 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
944
945 InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo,
946 &Parameters->ImagePathName);
947
948 AllocConsoleRequest->ConsoleHandle = NULL;
949 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
950 AllocConsoleRequest->PropDispatcher = PropDialogHandler;
951
952 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
953 CaptureBuffer,
954 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
955 sizeof(CONSOLE_ALLOCCONSOLE));
956
957 CsrFreeCaptureBuffer(CaptureBuffer);
958
959 if (!NT_SUCCESS(Status))
960 {
961 BaseSetLastNTError(Status);
962 return FALSE;
963 }
964
965 Parameters->ConsoleHandle = AllocConsoleRequest->ConsoleHandle;
966 SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
967 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
968 SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
969
970 /* Initialize Console Ctrl Handler */
971 InitConsoleCtrlHandling();
972
973 InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
974
975 return TRUE;
976 }
977
978
979 /*--------------------------------------------------------------
980 * FreeConsole
981 *
982 * @implemented
983 */
984 BOOL
985 WINAPI
986 FreeConsole(VOID)
987 {
988 // AG: I'm not sure if this is correct (what happens to std handles?)
989 // but I just tried to reverse what AllocConsole() does...
990
991 NTSTATUS Status;
992 CONSOLE_API_MESSAGE ApiMessage;
993
994 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
995 NULL,
996 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
997 sizeof(CONSOLE_FREECONSOLE));
998 if (!NT_SUCCESS(Status))
999 {
1000 BaseSetLastNTError(Status);
1001 return FALSE;
1002 }
1003
1004 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1005
1006 CloseHandle(InputWaitHandle);
1007 InputWaitHandle = INVALID_HANDLE_VALUE;
1008
1009 return TRUE;
1010 }
1011
1012
1013 /*--------------------------------------------------------------
1014 * GetConsoleScreenBufferInfo
1015 *
1016 * @implemented
1017 */
1018 BOOL
1019 WINAPI
1020 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1021 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1022 {
1023 NTSTATUS Status;
1024 CONSOLE_API_MESSAGE ApiMessage;
1025
1026 if (lpConsoleScreenBufferInfo == NULL)
1027 {
1028 SetLastError(ERROR_INVALID_PARAMETER);
1029 return FALSE;
1030 }
1031
1032 ApiMessage.Data.ScreenBufferInfoRequest.OutputHandle = hConsoleOutput;
1033
1034 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1035 NULL,
1036 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1037 sizeof(CONSOLE_GETSCREENBUFFERINFO));
1038 if (!NT_SUCCESS(Status))
1039 {
1040 BaseSetLastNTError(Status);
1041 return FALSE;
1042 }
1043
1044 *lpConsoleScreenBufferInfo = ApiMessage.Data.ScreenBufferInfoRequest.Info;
1045
1046 return TRUE;
1047 }
1048
1049
1050 /*--------------------------------------------------------------
1051 * SetConsoleCursorPosition
1052 *
1053 * @implemented
1054 */
1055 BOOL
1056 WINAPI
1057 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1058 COORD dwCursorPosition)
1059 {
1060 NTSTATUS Status;
1061 CONSOLE_API_MESSAGE ApiMessage;
1062
1063 ApiMessage.Data.SetCursorPositionRequest.OutputHandle = hConsoleOutput;
1064 ApiMessage.Data.SetCursorPositionRequest.Position = dwCursorPosition;
1065
1066 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1067 NULL,
1068 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1069 sizeof(CONSOLE_SETCURSORPOSITION));
1070 if (!NT_SUCCESS(Status))
1071 {
1072 BaseSetLastNTError(Status);
1073 return FALSE;
1074 }
1075
1076 return TRUE;
1077 }
1078
1079
1080 /*--------------------------------------------------------------
1081 * GetConsoleMode
1082 *
1083 * @implemented
1084 */
1085 BOOL
1086 WINAPI
1087 GetConsoleMode(HANDLE hConsoleHandle,
1088 LPDWORD lpMode)
1089 {
1090 NTSTATUS Status;
1091 CONSOLE_API_MESSAGE ApiMessage;
1092 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1093
1094 if (lpMode == NULL)
1095 {
1096 SetLastError(ERROR_INVALID_PARAMETER);
1097 return FALSE;
1098 }
1099
1100 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1101
1102 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1103 NULL,
1104 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1105 sizeof(CONSOLE_GETSETCONSOLEMODE));
1106 if (!NT_SUCCESS(Status))
1107 {
1108 BaseSetLastNTError(Status);
1109 return FALSE;
1110 }
1111
1112 *lpMode = ConsoleModeRequest->ConsoleMode;
1113
1114 return TRUE;
1115 }
1116
1117
1118 /*--------------------------------------------------------------
1119 * GetNumberOfConsoleInputEvents
1120 *
1121 * @implemented
1122 */
1123 BOOL
1124 WINAPI
1125 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1126 LPDWORD lpNumberOfEvents)
1127 {
1128 NTSTATUS Status;
1129 CONSOLE_API_MESSAGE ApiMessage;
1130 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1131
1132 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1133 GetNumInputEventsRequest->NumInputEvents = 0;
1134
1135 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1136 NULL,
1137 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1138 sizeof(CONSOLE_GETNUMINPUTEVENTS));
1139 if (!NT_SUCCESS(Status))
1140 {
1141 BaseSetLastNTError(Status);
1142 return FALSE;
1143 }
1144
1145 if (lpNumberOfEvents == NULL)
1146 {
1147 SetLastError(ERROR_INVALID_ACCESS);
1148 return FALSE;
1149 }
1150
1151 *lpNumberOfEvents = GetNumInputEventsRequest->NumInputEvents;
1152
1153 return TRUE;
1154 }
1155
1156
1157 /*--------------------------------------------------------------
1158 * GetLargestConsoleWindowSize
1159 *
1160 * @implemented
1161 */
1162 COORD
1163 WINAPI
1164 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1165 {
1166 NTSTATUS Status;
1167 CONSOLE_API_MESSAGE ApiMessage;
1168 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1169
1170 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1171 GetLargestWindowSizeRequest->Size.X = 0;
1172 GetLargestWindowSizeRequest->Size.Y = 0;
1173
1174 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1175 NULL,
1176 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1177 sizeof(CONSOLE_GETLARGESTWINDOWSIZE));
1178 if (!NT_SUCCESS(Status))
1179 {
1180 BaseSetLastNTError(Status);
1181 }
1182
1183 DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1184 return GetLargestWindowSizeRequest->Size;
1185 }
1186
1187
1188 /*--------------------------------------------------------------
1189 * GetConsoleCursorInfo
1190 *
1191 * @implemented
1192 */
1193 BOOL
1194 WINAPI
1195 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1196 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1197 {
1198 NTSTATUS Status;
1199 CONSOLE_API_MESSAGE ApiMessage;
1200
1201 if (!lpConsoleCursorInfo)
1202 {
1203 if (!hConsoleOutput)
1204 SetLastError(ERROR_INVALID_HANDLE);
1205 else
1206 SetLastError(ERROR_INVALID_ACCESS);
1207
1208 return FALSE;
1209 }
1210
1211 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1212
1213 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1214 NULL,
1215 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1216 sizeof(CONSOLE_GETSETCURSORINFO));
1217 if (!NT_SUCCESS(Status))
1218 {
1219 BaseSetLastNTError(Status);
1220 return FALSE;
1221 }
1222
1223 *lpConsoleCursorInfo = ApiMessage.Data.CursorInfoRequest.Info;
1224
1225 return TRUE;
1226 }
1227
1228
1229 /*--------------------------------------------------------------
1230 * GetNumberOfConsoleMouseButtons
1231 *
1232 * @unimplemented
1233 */
1234 BOOL
1235 WINAPI
1236 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1237 {
1238 DPRINT1("GetNumberOfConsoleMouseButtons(0x%p) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
1239 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1240 return FALSE;
1241 }
1242
1243
1244 /*--------------------------------------------------------------
1245 * SetConsoleMode
1246 *
1247 * @implemented
1248 */
1249 BOOL
1250 WINAPI
1251 SetConsoleMode(HANDLE hConsoleHandle,
1252 DWORD dwMode)
1253 {
1254 NTSTATUS Status;
1255 CONSOLE_API_MESSAGE ApiMessage;
1256 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1257
1258 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1259 ConsoleModeRequest->ConsoleMode = dwMode;
1260
1261 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1262 NULL,
1263 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1264 sizeof(CONSOLE_GETSETCONSOLEMODE));
1265 if (!NT_SUCCESS(Status))
1266 {
1267 BaseSetLastNTError(Status);
1268 return FALSE;
1269 }
1270
1271 return TRUE;
1272 }
1273
1274
1275 /*--------------------------------------------------------------
1276 * SetConsoleActiveScreenBuffer
1277 *
1278 * @implemented
1279 */
1280 BOOL
1281 WINAPI
1282 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1283 {
1284 NTSTATUS Status;
1285 CONSOLE_API_MESSAGE ApiMessage;
1286
1287 ApiMessage.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
1288
1289 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1290 NULL,
1291 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1292 sizeof(CONSOLE_SETACTIVESCREENBUFFER));
1293 if (!NT_SUCCESS(Status))
1294 {
1295 BaseSetLastNTError(Status);
1296 return FALSE;
1297 }
1298
1299 return TRUE;
1300 }
1301
1302
1303 /*--------------------------------------------------------------
1304 * FlushConsoleInputBuffer
1305 *
1306 * @implemented
1307 */
1308 BOOL
1309 WINAPI
1310 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1311 {
1312 NTSTATUS Status;
1313 CONSOLE_API_MESSAGE ApiMessage;
1314
1315 ApiMessage.Data.FlushInputBufferRequest.InputHandle = hConsoleInput;
1316
1317 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1318 NULL,
1319 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1320 sizeof(CONSOLE_FLUSHINPUTBUFFER));
1321 if (!NT_SUCCESS(Status))
1322 {
1323 BaseSetLastNTError(Status);
1324 return FALSE;
1325 }
1326
1327 return TRUE;
1328 }
1329
1330
1331 /*--------------------------------------------------------------
1332 * SetConsoleScreenBufferSize
1333 *
1334 * @implemented
1335 */
1336 BOOL
1337 WINAPI
1338 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1339 COORD dwSize)
1340 {
1341 NTSTATUS Status;
1342 CONSOLE_API_MESSAGE ApiMessage;
1343
1344 ApiMessage.Data.SetScreenBufferSizeRequest.OutputHandle = hConsoleOutput;
1345 ApiMessage.Data.SetScreenBufferSizeRequest.Size = dwSize;
1346
1347 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1348 NULL,
1349 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1350 sizeof(CONSOLE_SETSCREENBUFFERSIZE));
1351 if (!NT_SUCCESS(Status))
1352 {
1353 BaseSetLastNTError(Status);
1354 return FALSE;
1355 }
1356
1357 return TRUE;
1358 }
1359
1360
1361 /*--------------------------------------------------------------
1362 * SetConsoleCursorInfo
1363 *
1364 * @implemented
1365 */
1366 BOOL
1367 WINAPI
1368 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1369 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1370 {
1371 NTSTATUS Status;
1372 CONSOLE_API_MESSAGE ApiMessage;
1373
1374 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1375 ApiMessage.Data.CursorInfoRequest.Info = *lpConsoleCursorInfo;
1376
1377 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1378 NULL,
1379 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1380 sizeof(CONSOLE_GETSETCURSORINFO));
1381 if (!NT_SUCCESS(Status))
1382 {
1383 BaseSetLastNTError(Status);
1384 return FALSE;
1385 }
1386
1387 return TRUE;
1388 }
1389
1390
1391 static
1392 BOOL
1393 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1394 const SMALL_RECT *lpScrollRectangle,
1395 const SMALL_RECT *lpClipRectangle,
1396 COORD dwDestinationOrigin,
1397 const CHAR_INFO *lpFill,
1398 BOOL bUnicode)
1399 {
1400 NTSTATUS Status;
1401 CONSOLE_API_MESSAGE ApiMessage;
1402 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1403
1404 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1405 ScrollScreenBufferRequest->Unicode = bUnicode;
1406 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1407
1408 if (lpClipRectangle != NULL)
1409 {
1410 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1411 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1412 }
1413 else
1414 {
1415 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1416 }
1417
1418 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1419 ScrollScreenBufferRequest->Fill = *lpFill;
1420
1421 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1422 NULL,
1423 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1424 sizeof(CONSOLE_SCROLLSCREENBUFFER));
1425
1426 if (!NT_SUCCESS(Status))
1427 {
1428 BaseSetLastNTError(Status);
1429 return FALSE;
1430 }
1431
1432 return TRUE;
1433 }
1434
1435
1436 /*--------------------------------------------------------------
1437 * ScrollConsoleScreenBufferA
1438 *
1439 * @implemented
1440 */
1441 BOOL
1442 WINAPI
1443 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1444 CONST SMALL_RECT *lpScrollRectangle,
1445 CONST SMALL_RECT *lpClipRectangle,
1446 COORD dwDestinationOrigin,
1447 CONST CHAR_INFO *lpFill)
1448 {
1449 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1450 (PSMALL_RECT)lpScrollRectangle,
1451 (PSMALL_RECT)lpClipRectangle,
1452 dwDestinationOrigin,
1453 (PCHAR_INFO)lpFill,
1454 FALSE);
1455 }
1456
1457
1458 /*--------------------------------------------------------------
1459 * ScrollConsoleScreenBufferW
1460 *
1461 * @implemented
1462 */
1463 BOOL
1464 WINAPI
1465 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1466 CONST SMALL_RECT *lpScrollRectangle,
1467 CONST SMALL_RECT *lpClipRectangle,
1468 COORD dwDestinationOrigin,
1469 CONST CHAR_INFO *lpFill)
1470 {
1471 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1472 lpScrollRectangle,
1473 lpClipRectangle,
1474 dwDestinationOrigin,
1475 lpFill,
1476 TRUE);
1477 }
1478
1479
1480 /*--------------------------------------------------------------
1481 * SetConsoleWindowInfo
1482 *
1483 * @implemented
1484 */
1485 BOOL
1486 WINAPI
1487 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1488 BOOL bAbsolute,
1489 CONST SMALL_RECT *lpConsoleWindow)
1490 {
1491 NTSTATUS Status;
1492 CONSOLE_API_MESSAGE ApiMessage;
1493 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1494
1495 if (lpConsoleWindow == NULL)
1496 {
1497 SetLastError(ERROR_INVALID_PARAMETER);
1498 return FALSE;
1499 }
1500
1501 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1502 SetWindowInfoRequest->Absolute = bAbsolute;
1503 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1504
1505 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1506 NULL,
1507 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1508 sizeof(CONSOLE_SETWINDOWINFO));
1509 if (!NT_SUCCESS(Status))
1510 {
1511 BaseSetLastNTError(Status);
1512 return FALSE;
1513 }
1514
1515 return TRUE;
1516 }
1517
1518
1519 /*--------------------------------------------------------------
1520 * SetConsoleTextAttribute
1521 *
1522 * @implemented
1523 */
1524 BOOL
1525 WINAPI
1526 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1527 WORD wAttributes)
1528 {
1529 NTSTATUS Status;
1530 CONSOLE_API_MESSAGE ApiMessage;
1531
1532 ApiMessage.Data.SetTextAttribRequest.OutputHandle = hConsoleOutput;
1533 ApiMessage.Data.SetTextAttribRequest.Attrib = wAttributes;
1534
1535 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1536 NULL,
1537 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1538 sizeof(CONSOLE_SETTEXTATTRIB));
1539 if (!NT_SUCCESS(Status))
1540 {
1541 BaseSetLastNTError(Status);
1542 return FALSE;
1543 }
1544
1545 return TRUE;
1546 }
1547
1548
1549 static
1550 BOOL
1551 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1552 {
1553 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1554
1555 if (HandlerRoutine == NULL)
1556 {
1557 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1558 return TRUE;
1559 }
1560
1561 if (NrCtrlHandlers == NrAllocatedHandlers)
1562 {
1563 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1564 0,
1565 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1566 if (NewCtrlHandlers == NULL)
1567 {
1568 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1569 return FALSE;
1570 }
1571
1572 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1573
1574 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1575
1576 CtrlHandlers = NewCtrlHandlers;
1577 NrAllocatedHandlers += 4;
1578 }
1579
1580 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1581
1582 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1583 return TRUE;
1584 }
1585
1586
1587 static
1588 BOOL
1589 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1590 {
1591 ULONG i;
1592
1593 if (HandlerRoutine == NULL)
1594 {
1595 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1596 return TRUE;
1597 }
1598
1599 for (i = 0; i < NrCtrlHandlers; i++)
1600 {
1601 if (CtrlHandlers[i] == HandlerRoutine)
1602 {
1603 if (i < (NrCtrlHandlers - 1))
1604 {
1605 memmove(&CtrlHandlers[i],
1606 &CtrlHandlers[i+1],
1607 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1608 }
1609
1610 NrCtrlHandlers--;
1611 return TRUE;
1612 }
1613 }
1614
1615 SetLastError(ERROR_INVALID_PARAMETER);
1616 return FALSE;
1617 }
1618
1619
1620 /*
1621 * @implemented
1622 */
1623 BOOL
1624 WINAPI
1625 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1626 BOOL Add)
1627 {
1628 BOOL Ret;
1629
1630 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1631 if (Add)
1632 {
1633 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1634 }
1635 else
1636 {
1637 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1638 }
1639
1640 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1641 return(Ret);
1642 }
1643
1644
1645 /*--------------------------------------------------------------
1646 * GenerateConsoleCtrlEvent
1647 *
1648 * @implemented
1649 */
1650 BOOL
1651 WINAPI
1652 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1653 DWORD dwProcessGroupId)
1654 {
1655 NTSTATUS Status;
1656 CONSOLE_API_MESSAGE ApiMessage;
1657
1658 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1659 {
1660 SetLastError(ERROR_INVALID_PARAMETER);
1661 return FALSE;
1662 }
1663
1664 ApiMessage.Data.GenerateCtrlEventRequest.Event = dwCtrlEvent;
1665 ApiMessage.Data.GenerateCtrlEventRequest.ProcessGroup = dwProcessGroupId;
1666
1667 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1668 NULL,
1669 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1670 sizeof(CONSOLE_GENERATECTRLEVENT));
1671 if (!NT_SUCCESS(Status))
1672 {
1673 BaseSetLastNTError(Status);
1674 return FALSE;
1675 }
1676
1677 return TRUE;
1678 }
1679
1680
1681 static DWORD
1682 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
1683 {
1684 NTSTATUS Status;
1685 CONSOLE_API_MESSAGE ApiMessage;
1686 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1687 PCSR_CAPTURE_BUFFER CaptureBuffer;
1688
1689 if (nSize == 0) return 0;
1690
1691 TitleRequest->Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
1692 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1693 if (CaptureBuffer == NULL)
1694 {
1695 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1696 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1697 return 0;
1698 }
1699
1700 CsrAllocateMessagePointer(CaptureBuffer,
1701 TitleRequest->Length,
1702 (PVOID*)&TitleRequest->Title);
1703
1704 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1705 CaptureBuffer,
1706 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1707 sizeof(CONSOLE_GETSETCONSOLETITLE));
1708 if (!NT_SUCCESS(Status))
1709 {
1710 CsrFreeCaptureBuffer(CaptureBuffer);
1711 BaseSetLastNTError(Status);
1712 return 0;
1713 }
1714
1715 if (bUnicode)
1716 {
1717 if (nSize >= sizeof(WCHAR))
1718 wcscpy((LPWSTR)lpConsoleTitle, TitleRequest->Title);
1719 }
1720 else
1721 {
1722 if (nSize < TitleRequest->Length / sizeof(WCHAR) ||
1723 !WideCharToMultiByte(CP_ACP, // ANSI code page
1724 0, // performance and mapping flags
1725 TitleRequest->Title, // address of wide-character string
1726 -1, // number of characters in string
1727 (LPSTR)lpConsoleTitle, // address of buffer for new string
1728 nSize, // size of buffer
1729 NULL, // FAST
1730 NULL))
1731 {
1732 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1733 *(LPSTR)lpConsoleTitle = '\0';
1734 TitleRequest->Length = 0;
1735 }
1736 }
1737 CsrFreeCaptureBuffer(CaptureBuffer);
1738
1739 return TitleRequest->Length / sizeof(WCHAR);
1740 }
1741
1742
1743 /*--------------------------------------------------------------
1744 * GetConsoleTitleW
1745 *
1746 * @implemented
1747 */
1748 DWORD
1749 WINAPI
1750 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1751 DWORD nSize)
1752 {
1753 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1754 }
1755
1756
1757 /*--------------------------------------------------------------
1758 * GetConsoleTitleA
1759 *
1760 * @implemented
1761 */
1762 DWORD
1763 WINAPI
1764 GetConsoleTitleA(LPSTR lpConsoleTitle,
1765 DWORD nSize)
1766 {
1767 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1768 }
1769
1770
1771 /*--------------------------------------------------------------
1772 * SetConsoleTitleW
1773 *
1774 * @implemented
1775 */
1776 BOOL
1777 WINAPI
1778 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1779 {
1780 NTSTATUS Status;
1781 CONSOLE_API_MESSAGE ApiMessage;
1782 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1783 PCSR_CAPTURE_BUFFER CaptureBuffer;
1784
1785 TitleRequest->Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
1786
1787 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1788 if (CaptureBuffer == NULL)
1789 {
1790 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1791 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1792 return FALSE;
1793 }
1794
1795 CsrCaptureMessageBuffer(CaptureBuffer,
1796 (PVOID)lpConsoleTitle,
1797 TitleRequest->Length,
1798 (PVOID*)&TitleRequest->Title);
1799
1800 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1801 CaptureBuffer,
1802 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1803 sizeof(CONSOLE_GETSETCONSOLETITLE));
1804
1805 CsrFreeCaptureBuffer(CaptureBuffer);
1806
1807 if (!NT_SUCCESS(Status))
1808 {
1809 BaseSetLastNTError(Status);
1810 return FALSE;
1811 }
1812
1813 return TRUE;
1814 }
1815
1816
1817 /*--------------------------------------------------------------
1818 * SetConsoleTitleA
1819 *
1820 * @implemented
1821 */
1822 BOOL
1823 WINAPI
1824 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1825 {
1826 BOOL Ret;
1827 ULONG Length = strlen(lpConsoleTitle) + 1;
1828 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1829
1830 if (!WideTitle)
1831 {
1832 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1833 return FALSE;
1834 }
1835
1836 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
1837
1838 Ret = SetConsoleTitleW(WideTitle);
1839
1840 HeapFree(GetProcessHeap(), 0, WideTitle);
1841 return Ret;
1842 }
1843
1844
1845 /*--------------------------------------------------------------
1846 * CreateConsoleScreenBuffer
1847 *
1848 * @implemented
1849 */
1850 HANDLE
1851 WINAPI
1852 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1853 DWORD dwShareMode,
1854 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1855 DWORD dwFlags,
1856 LPVOID lpScreenBufferData)
1857 {
1858 NTSTATUS Status;
1859 CONSOLE_API_MESSAGE ApiMessage;
1860 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1861 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1862 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData;
1863
1864 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1865 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1866 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1867 {
1868 SetLastError(ERROR_INVALID_PARAMETER);
1869 return INVALID_HANDLE_VALUE;
1870 }
1871
1872 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1873 CreateScreenBufferRequest->Access = dwDesiredAccess;
1874 CreateScreenBufferRequest->ShareMode = dwShareMode;
1875 CreateScreenBufferRequest->Inheritable =
1876 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1877
1878 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1879 {
1880 if (CreateScreenBufferRequest->Inheritable || GraphicsBufferInfo == NULL)
1881 {
1882 SetLastError(ERROR_INVALID_PARAMETER);
1883 return INVALID_HANDLE_VALUE;
1884 }
1885
1886 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
1887
1888 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
1889 if (CaptureBuffer == NULL)
1890 {
1891 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1892 return FALSE;
1893 }
1894
1895 CsrCaptureMessageBuffer(CaptureBuffer,
1896 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
1897 GraphicsBufferInfo->dwBitMapInfoLength,
1898 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
1899 }
1900
1901 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1902 CaptureBuffer,
1903 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1904 sizeof(CONSOLE_CREATESCREENBUFFER));
1905
1906 if (CaptureBuffer)
1907 CsrFreeCaptureBuffer(CaptureBuffer);
1908
1909 if (!NT_SUCCESS(Status))
1910 {
1911 BaseSetLastNTError(Status);
1912 return INVALID_HANDLE_VALUE;
1913 }
1914
1915 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
1916 {
1917 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
1918 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
1919 }
1920
1921 return CreateScreenBufferRequest->OutputHandle;
1922 }
1923
1924
1925 /*--------------------------------------------------------------
1926 * GetConsoleCP
1927 *
1928 * @implemented
1929 */
1930 UINT
1931 WINAPI
1932 GetConsoleCP(VOID)
1933 {
1934 NTSTATUS Status;
1935 CONSOLE_API_MESSAGE ApiMessage;
1936
1937 /* Get the Input Code Page */
1938 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1939 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
1940
1941 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1942 NULL,
1943 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1944 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1945
1946 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1947
1948 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1949 }
1950
1951
1952 /*--------------------------------------------------------------
1953 * SetConsoleCP
1954 *
1955 * @implemented
1956 */
1957 BOOL
1958 WINAPI
1959 SetConsoleCP(UINT wCodePageID)
1960 {
1961 NTSTATUS Status;
1962 CONSOLE_API_MESSAGE ApiMessage;
1963
1964 /* Set the Input Code Page */
1965 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1966 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1967
1968 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1969 NULL,
1970 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1971 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1972
1973 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1974
1975 return NT_SUCCESS(Status);
1976 }
1977
1978
1979 /*--------------------------------------------------------------
1980 * GetConsoleOutputCP
1981 *
1982 * @implemented
1983 */
1984 UINT
1985 WINAPI
1986 GetConsoleOutputCP(VOID)
1987 {
1988 NTSTATUS Status;
1989 CONSOLE_API_MESSAGE ApiMessage;
1990
1991 /* Get the Output Code Page */
1992 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1993 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
1994
1995 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1996 NULL,
1997 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1998 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1999
2000 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2001
2002 return ApiMessage.Data.ConsoleCPRequest.CodePage;
2003 }
2004
2005
2006 /*--------------------------------------------------------------
2007 * SetConsoleOutputCP
2008 *
2009 * @implemented
2010 */
2011 BOOL
2012 WINAPI
2013 SetConsoleOutputCP(UINT wCodePageID)
2014 {
2015 NTSTATUS Status;
2016 CONSOLE_API_MESSAGE ApiMessage;
2017
2018 /* Set the Output Code Page */
2019 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
2020 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
2021
2022 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2023 NULL,
2024 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2025 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2026
2027 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2028
2029 return NT_SUCCESS(Status);
2030 }
2031
2032
2033 /*--------------------------------------------------------------
2034 * GetConsoleProcessList
2035 *
2036 * @implemented
2037 */
2038 DWORD
2039 WINAPI
2040 GetConsoleProcessList(LPDWORD lpdwProcessList,
2041 DWORD dwProcessCount)
2042 {
2043 NTSTATUS Status;
2044 CONSOLE_API_MESSAGE ApiMessage;
2045 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2046 PCSR_CAPTURE_BUFFER CaptureBuffer;
2047 ULONG nProcesses;
2048
2049 if (lpdwProcessList == NULL || dwProcessCount == 0)
2050 {
2051 SetLastError(ERROR_INVALID_PARAMETER);
2052 return 0;
2053 }
2054
2055 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2056 if (CaptureBuffer == NULL)
2057 {
2058 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2059 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2060 return FALSE;
2061 }
2062
2063 GetProcessListRequest->nMaxIds = dwProcessCount;
2064
2065 CsrAllocateMessagePointer(CaptureBuffer,
2066 dwProcessCount * sizeof(DWORD),
2067 (PVOID*)&GetProcessListRequest->pProcessIds);
2068
2069 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2070 CaptureBuffer,
2071 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2072 sizeof(CONSOLE_GETPROCESSLIST));
2073 if (!NT_SUCCESS(Status))
2074 {
2075 BaseSetLastNTError (Status);
2076 nProcesses = 0;
2077 }
2078 else
2079 {
2080 nProcesses = GetProcessListRequest->nProcessIdsTotal;
2081 if (dwProcessCount >= nProcesses)
2082 {
2083 memcpy(lpdwProcessList, GetProcessListRequest->pProcessIds, nProcesses * sizeof(DWORD));
2084 }
2085 }
2086
2087 CsrFreeCaptureBuffer(CaptureBuffer);
2088 return nProcesses;
2089 }
2090
2091
2092 /*--------------------------------------------------------------
2093 * GetConsoleSelectionInfo
2094 *
2095 * @implemented
2096 */
2097 BOOL
2098 WINAPI
2099 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2100 {
2101 NTSTATUS Status;
2102 CONSOLE_API_MESSAGE ApiMessage;
2103
2104 if (lpConsoleSelectionInfo == NULL)
2105 {
2106 SetLastError(ERROR_INVALID_PARAMETER);
2107 return FALSE;
2108 }
2109
2110 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2111 NULL,
2112 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2113 sizeof(CONSOLE_GETSELECTIONINFO));
2114 if (!NT_SUCCESS(Status))
2115 {
2116 BaseSetLastNTError(Status);
2117 return FALSE;
2118 }
2119
2120 *lpConsoleSelectionInfo = ApiMessage.Data.GetSelectionInfoRequest.Info;
2121 return TRUE;
2122 }
2123
2124
2125 /*--------------------------------------------------------------
2126 * AttachConsole
2127 *
2128 * @implemented
2129 *
2130 * @note Strongly inspired by AllocConsole.
2131 */
2132 BOOL
2133 WINAPI
2134 AttachConsole(DWORD dwProcessId)
2135 {
2136 NTSTATUS Status;
2137 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2138 CONSOLE_API_MESSAGE ApiMessage;
2139 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2140
2141 if (Parameters->ConsoleHandle)
2142 {
2143 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2144 SetLastError(ERROR_ACCESS_DENIED);
2145 return FALSE;
2146 }
2147
2148 AttachConsoleRequest->ProcessId = dwProcessId;
2149 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2150 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2151
2152 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2153 NULL,
2154 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2155 sizeof(CONSOLE_ATTACHCONSOLE));
2156 if (!NT_SUCCESS(Status))
2157 {
2158 BaseSetLastNTError(Status);
2159 return FALSE;
2160 }
2161
2162 Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle;
2163 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2164 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2165 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2166
2167 /* Initialize Console Ctrl Handler */
2168 InitConsoleCtrlHandling();
2169
2170 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2171
2172 return TRUE;
2173 }
2174
2175
2176 /*--------------------------------------------------------------
2177 * GetConsoleWindow
2178 *
2179 * @implemented
2180 */
2181 HWND
2182 WINAPI
2183 GetConsoleWindow(VOID)
2184 {
2185 NTSTATUS Status;
2186 CONSOLE_API_MESSAGE ApiMessage;
2187
2188 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2189 NULL,
2190 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2191 sizeof(CONSOLE_GETWINDOW));
2192 if (!NT_SUCCESS(Status))
2193 {
2194 BaseSetLastNTError(Status);
2195 return (HWND)NULL;
2196 }
2197
2198 return ApiMessage.Data.GetWindowRequest.WindowHandle;
2199 }
2200
2201
2202 /*--------------------------------------------------------------
2203 * SetConsoleIcon
2204 *
2205 * @implemented
2206 */
2207 BOOL
2208 WINAPI
2209 SetConsoleIcon(HICON hicon)
2210 {
2211 NTSTATUS Status;
2212 CONSOLE_API_MESSAGE ApiMessage;
2213
2214 ApiMessage.Data.SetIconRequest.WindowIcon = hicon;
2215
2216 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2217 NULL,
2218 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2219 sizeof(CONSOLE_SETICON));
2220 if (!NT_SUCCESS(Status))
2221 {
2222 BaseSetLastNTError(Status);
2223 return FALSE;
2224 }
2225
2226 return NT_SUCCESS(Status);
2227 }
2228
2229
2230 /******************************************************************************
2231 * \name SetConsoleInputExeNameW
2232 * \brief Sets the console input file name from a unicode string.
2233 * \param lpInputExeName Pointer to a unicode string with the name.
2234 * \return TRUE if successful, FALSE if unsuccsedful.
2235 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2236 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2237 */
2238 BOOL
2239 WINAPI
2240 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2241 {
2242 int lenName;
2243
2244 if ( !lpInputExeName ||
2245 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2246 lenName > INPUTEXENAME_BUFLEN - 1 )
2247 {
2248 /* Fail if string is empty or too long */
2249 SetLastError(ERROR_INVALID_PARAMETER);
2250 return FALSE;
2251 }
2252
2253 RtlEnterCriticalSection(&ConsoleLock);
2254 _SEH2_TRY
2255 {
2256 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2257 InputExeName[lenName] = L'\0';
2258 }
2259 _SEH2_FINALLY
2260 {
2261 RtlLeaveCriticalSection(&ConsoleLock);
2262 }
2263 _SEH2_END;
2264
2265 return TRUE;
2266 }
2267
2268
2269 /******************************************************************************
2270 * \name SetConsoleInputExeNameA
2271 * \brief Sets the console input file name from an ansi string.
2272 * \param lpInputExeName Pointer to an ansi string with the name.
2273 * \return TRUE if successful, FALSE if unsuccsedful.
2274 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2275 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2276 */
2277 BOOL
2278 WINAPI
2279 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2280 {
2281 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2282 ANSI_STRING InputExeNameA;
2283 UNICODE_STRING InputExeNameU;
2284 NTSTATUS Status;
2285
2286 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2287
2288 if ( InputExeNameA.Length == 0 ||
2289 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2290 {
2291 /* Fail if string is empty or too long */
2292 SetLastError(ERROR_INVALID_PARAMETER);
2293 return FALSE;
2294 }
2295
2296 InputExeNameU.Buffer = Buffer;
2297 InputExeNameU.MaximumLength = sizeof(Buffer);
2298 InputExeNameU.Length = 0;
2299
2300 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2301 if (!NT_SUCCESS(Status))
2302 {
2303 BaseSetLastNTError(Status);
2304 return FALSE;
2305 }
2306
2307 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2308 }
2309
2310
2311 /******************************************************************************
2312 * \name GetConsoleInputExeNameW
2313 * \brief Retrieves the console input file name as unicode string.
2314 * \param nBufferLength Length of the buffer in WCHARs.
2315 * Specify 0 to receive the needed buffer length.
2316 * \param lpBuffer Pointer to a buffer that receives the string.
2317 * \return Needed buffer size if \p nBufferLength is 0.
2318 * Otherwise 1 if successful, 2 if buffer is too small.
2319 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2320 * is not big enough.
2321 */
2322 DWORD
2323 WINAPI
2324 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2325 {
2326 ULONG lenName = lstrlenW(InputExeName);
2327
2328 if (nBufferLength == 0)
2329 {
2330 /* Buffer size is requested, return it */
2331 return lenName + 1;
2332 }
2333
2334 if (lenName + 1 > nBufferLength)
2335 {
2336 /* Buffer is not large enough! */
2337 SetLastError(ERROR_BUFFER_OVERFLOW);
2338 return 2;
2339 }
2340
2341 RtlEnterCriticalSection(&ConsoleLock);
2342 _SEH2_TRY
2343 {
2344 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2345 lpBuffer[lenName] = '\0';
2346 }
2347 _SEH2_FINALLY
2348 {
2349 RtlLeaveCriticalSection(&ConsoleLock);
2350 }
2351 _SEH2_END;
2352
2353 /* Success, return 1 */
2354 return 1;
2355 }
2356
2357
2358 /******************************************************************************
2359 * \name GetConsoleInputExeNameA
2360 * \brief Retrieves the console input file name as ansi string.
2361 * \param nBufferLength Length of the buffer in CHARs.
2362 * \param lpBuffer Pointer to a buffer that receives the string.
2363 * \return 1 if successful, 2 if buffer is too small.
2364 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2365 * is not big enough. The buffer receives as much characters as fit.
2366 */
2367 DWORD
2368 WINAPI
2369 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2370 {
2371 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2372 DWORD Ret;
2373 UNICODE_STRING BufferU;
2374 ANSI_STRING BufferA;
2375
2376 /* Get the unicode name */
2377 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2378
2379 /* Initialize strings for conversion */
2380 RtlInitUnicodeString(&BufferU, Buffer);
2381 BufferA.Length = 0;
2382 BufferA.MaximumLength = (USHORT)nBufferLength;
2383 BufferA.Buffer = lpBuffer;
2384
2385 /* Convert unicode name to ansi, copying as much chars as fit */
2386 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2387
2388 /* Error handling */
2389 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2390 {
2391 SetLastError(ERROR_BUFFER_OVERFLOW);
2392 return 2;
2393 }
2394
2395 return Ret;
2396 }
2397
2398 BOOL
2399 WINAPI
2400 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2401 {
2402 STUB;
2403 return FALSE;
2404 }
2405
2406 BOOL
2407 WINAPI
2408 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2409 {
2410 STUB;
2411 return FALSE;
2412 }
2413
2414 BOOL
2415 WINAPI
2416 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2417 {
2418 STUB;
2419 return FALSE;
2420 }
2421
2422 BOOL
2423 WINAPI
2424 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2425 {
2426 STUB;
2427 return FALSE;
2428 }
2429
2430 BOOL
2431 WINAPI
2432 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2433 {
2434 STUB;
2435 return FALSE;
2436 }
2437
2438 BOOL
2439 WINAPI
2440 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2441 {
2442 STUB;
2443 return FALSE;
2444 }
2445
2446 BOOL
2447 WINAPI
2448 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2449 {
2450 STUB;
2451 return FALSE;
2452 }
2453
2454 BOOL
2455 WINAPI
2456 RegisterConsoleOS2(BOOL bUnknown)
2457 {
2458 STUB;
2459 return FALSE;
2460 }
2461
2462 BOOL
2463 WINAPI
2464 SetConsoleOS2OemFormat(BOOL bUnknown)
2465 {
2466 STUB;
2467 return FALSE;
2468 }
2469
2470 BOOL
2471 WINAPI
2472 UnregisterConsoleIME(VOID)
2473 {
2474 STUB;
2475 return FALSE;
2476 }
2477
2478
2479 /*
2480 * @unimplemented
2481 */
2482 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2483 {
2484 STUB;
2485 return 0;
2486 }
2487
2488 /*
2489 * @unimplemented
2490 */
2491 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2492 {
2493 STUB;
2494 return 0;
2495 }
2496
2497 /*
2498 * @unimplemented
2499 */
2500 BOOL
2501 WINAPI
2502 SetLastConsoleEventActive(VOID)
2503 {
2504 STUB;
2505 return FALSE;
2506 }
2507
2508 /* EOF */