[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 BaseSetLastNTError(Status);
800 return FALSE;
801 }
802
803 return TRUE;
804 }
805
806
807 /*
808 * @implemented (Undocumented)
809 */
810 BOOL
811 WINAPI
812 CloseConsoleHandle(HANDLE Handle)
813 {
814 NTSTATUS Status;
815 CONSOLE_API_MESSAGE ApiMessage;
816
817 ApiMessage.Data.CloseHandleRequest.ConsoleHandle = Handle;
818
819 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
820 NULL,
821 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle),
822 sizeof(CONSOLE_CLOSEHANDLE));
823 if (!NT_SUCCESS(Status))
824 {
825 BaseSetLastNTError(Status);
826 return FALSE;
827 }
828
829 return TRUE;
830 }
831
832
833 /*
834 * @implemented
835 */
836 HANDLE
837 WINAPI
838 GetStdHandle(DWORD nStdHandle)
839 /*
840 * FUNCTION: Get a handle for the standard input, standard output
841 * and a standard error device.
842 *
843 * ARGUMENTS:
844 * nStdHandle - Specifies the device for which to return the handle.
845 *
846 * RETURNS: If the function succeeds, the return value is the handle
847 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
848 */
849 {
850 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
851
852 switch (nStdHandle)
853 {
854 case STD_INPUT_HANDLE:
855 return Ppb->StandardInput;
856
857 case STD_OUTPUT_HANDLE:
858 return Ppb->StandardOutput;
859
860 case STD_ERROR_HANDLE:
861 return Ppb->StandardError;
862 }
863
864 SetLastError(ERROR_INVALID_HANDLE);
865 return INVALID_HANDLE_VALUE;
866 }
867
868
869 /*
870 * @implemented
871 */
872 BOOL
873 WINAPI
874 SetStdHandle(DWORD nStdHandle,
875 HANDLE hHandle)
876 /*
877 * FUNCTION: Set the handle for the standard input, standard output or
878 * the standard error device.
879 *
880 * ARGUMENTS:
881 * nStdHandle - Specifies the handle to be set.
882 * hHandle - The handle to set.
883 *
884 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
885 */
886 {
887 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
888
889 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
890
891 switch (nStdHandle)
892 {
893 case STD_INPUT_HANDLE:
894 Ppb->StandardInput = hHandle;
895 return TRUE;
896
897 case STD_OUTPUT_HANDLE:
898 Ppb->StandardOutput = hHandle;
899 return TRUE;
900
901 case STD_ERROR_HANDLE:
902 Ppb->StandardError = hHandle;
903 return TRUE;
904 }
905
906 /* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
907 SetLastError(ERROR_INVALID_HANDLE);
908 return FALSE;
909 }
910
911
912 /*--------------------------------------------------------------
913 * AllocConsole
914 *
915 * @implemented
916 */
917 BOOL
918 WINAPI
919 AllocConsole(VOID)
920 {
921 NTSTATUS Status;
922 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
923 CONSOLE_API_MESSAGE ApiMessage;
924 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
925 PCSR_CAPTURE_BUFFER CaptureBuffer;
926
927 if (Parameters->ConsoleHandle)
928 {
929 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
930 SetLastError(ERROR_ACCESS_DENIED);
931 return FALSE;
932 }
933
934 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
935 if (CaptureBuffer == NULL)
936 {
937 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
938 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
939 return FALSE;
940 }
941
942 CsrAllocateMessagePointer(CaptureBuffer,
943 sizeof(CONSOLE_START_INFO),
944 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
945
946 InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo,
947 &Parameters->ImagePathName);
948
949 AllocConsoleRequest->ConsoleHandle = NULL;
950 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
951 AllocConsoleRequest->PropDispatcher = PropDialogHandler;
952
953 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
954 CaptureBuffer,
955 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
956 sizeof(CONSOLE_ALLOCCONSOLE));
957
958 CsrFreeCaptureBuffer(CaptureBuffer);
959
960 if (!NT_SUCCESS(Status))
961 {
962 BaseSetLastNTError(Status);
963 return FALSE;
964 }
965
966 Parameters->ConsoleHandle = AllocConsoleRequest->ConsoleHandle;
967 SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
968 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
969 SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
970
971 /* Initialize Console Ctrl Handler */
972 InitConsoleCtrlHandling();
973
974 InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
975
976 return TRUE;
977 }
978
979
980 /*--------------------------------------------------------------
981 * FreeConsole
982 *
983 * @implemented
984 */
985 BOOL
986 WINAPI
987 FreeConsole(VOID)
988 {
989 // AG: I'm not sure if this is correct (what happens to std handles?)
990 // but I just tried to reverse what AllocConsole() does...
991
992 NTSTATUS Status;
993 CONSOLE_API_MESSAGE ApiMessage;
994
995 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
996 NULL,
997 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
998 sizeof(CONSOLE_FREECONSOLE));
999 if (!NT_SUCCESS(Status))
1000 {
1001 BaseSetLastNTError(Status);
1002 return FALSE;
1003 }
1004
1005 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1006
1007 CloseHandle(InputWaitHandle);
1008 InputWaitHandle = INVALID_HANDLE_VALUE;
1009
1010 return TRUE;
1011 }
1012
1013
1014 /*--------------------------------------------------------------
1015 * GetConsoleScreenBufferInfo
1016 *
1017 * @implemented
1018 */
1019 BOOL
1020 WINAPI
1021 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1022 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1023 {
1024 NTSTATUS Status;
1025 CONSOLE_API_MESSAGE ApiMessage;
1026
1027 if (lpConsoleScreenBufferInfo == NULL)
1028 {
1029 SetLastError(ERROR_INVALID_PARAMETER);
1030 return FALSE;
1031 }
1032
1033 ApiMessage.Data.ScreenBufferInfoRequest.OutputHandle = hConsoleOutput;
1034
1035 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1036 NULL,
1037 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1038 sizeof(CONSOLE_GETSCREENBUFFERINFO));
1039 if (!NT_SUCCESS(Status))
1040 {
1041 BaseSetLastNTError(Status);
1042 return FALSE;
1043 }
1044
1045 *lpConsoleScreenBufferInfo = ApiMessage.Data.ScreenBufferInfoRequest.Info;
1046
1047 return TRUE;
1048 }
1049
1050
1051 /*--------------------------------------------------------------
1052 * SetConsoleCursorPosition
1053 *
1054 * @implemented
1055 */
1056 BOOL
1057 WINAPI
1058 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1059 COORD dwCursorPosition)
1060 {
1061 NTSTATUS Status;
1062 CONSOLE_API_MESSAGE ApiMessage;
1063
1064 ApiMessage.Data.SetCursorPositionRequest.OutputHandle = hConsoleOutput;
1065 ApiMessage.Data.SetCursorPositionRequest.Position = dwCursorPosition;
1066
1067 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1068 NULL,
1069 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1070 sizeof(CONSOLE_SETCURSORPOSITION));
1071 if (!NT_SUCCESS(Status))
1072 {
1073 BaseSetLastNTError(Status);
1074 return FALSE;
1075 }
1076
1077 return TRUE;
1078 }
1079
1080
1081 /*--------------------------------------------------------------
1082 * GetConsoleMode
1083 *
1084 * @implemented
1085 */
1086 BOOL
1087 WINAPI
1088 GetConsoleMode(HANDLE hConsoleHandle,
1089 LPDWORD lpMode)
1090 {
1091 NTSTATUS Status;
1092 CONSOLE_API_MESSAGE ApiMessage;
1093 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1094
1095 if (lpMode == NULL)
1096 {
1097 SetLastError(ERROR_INVALID_PARAMETER);
1098 return FALSE;
1099 }
1100
1101 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1102
1103 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1104 NULL,
1105 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1106 sizeof(CONSOLE_GETSETCONSOLEMODE));
1107 if (!NT_SUCCESS(Status))
1108 {
1109 BaseSetLastNTError(Status);
1110 return FALSE;
1111 }
1112
1113 *lpMode = ConsoleModeRequest->ConsoleMode;
1114
1115 return TRUE;
1116 }
1117
1118
1119 /*--------------------------------------------------------------
1120 * GetNumberOfConsoleInputEvents
1121 *
1122 * @implemented
1123 */
1124 BOOL
1125 WINAPI
1126 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1127 LPDWORD lpNumberOfEvents)
1128 {
1129 NTSTATUS Status;
1130 CONSOLE_API_MESSAGE ApiMessage;
1131 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1132
1133 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1134 GetNumInputEventsRequest->NumInputEvents = 0;
1135
1136 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1137 NULL,
1138 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1139 sizeof(CONSOLE_GETNUMINPUTEVENTS));
1140 if (!NT_SUCCESS(Status))
1141 {
1142 BaseSetLastNTError(Status);
1143 return FALSE;
1144 }
1145
1146 if (lpNumberOfEvents == NULL)
1147 {
1148 SetLastError(ERROR_INVALID_ACCESS);
1149 return FALSE;
1150 }
1151
1152 *lpNumberOfEvents = GetNumInputEventsRequest->NumInputEvents;
1153
1154 return TRUE;
1155 }
1156
1157
1158 /*--------------------------------------------------------------
1159 * GetLargestConsoleWindowSize
1160 *
1161 * @implemented
1162 */
1163 COORD
1164 WINAPI
1165 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1166 {
1167 NTSTATUS Status;
1168 CONSOLE_API_MESSAGE ApiMessage;
1169 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1170
1171 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1172 GetLargestWindowSizeRequest->Size.X = 0;
1173 GetLargestWindowSizeRequest->Size.Y = 0;
1174
1175 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1176 NULL,
1177 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1178 sizeof(CONSOLE_GETLARGESTWINDOWSIZE));
1179 if (!NT_SUCCESS(Status))
1180 {
1181 BaseSetLastNTError(Status);
1182 }
1183
1184 DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1185 return GetLargestWindowSizeRequest->Size;
1186 }
1187
1188
1189 /*--------------------------------------------------------------
1190 * GetConsoleCursorInfo
1191 *
1192 * @implemented
1193 */
1194 BOOL
1195 WINAPI
1196 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1197 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1198 {
1199 NTSTATUS Status;
1200 CONSOLE_API_MESSAGE ApiMessage;
1201
1202 if (!lpConsoleCursorInfo)
1203 {
1204 if (!hConsoleOutput)
1205 SetLastError(ERROR_INVALID_HANDLE);
1206 else
1207 SetLastError(ERROR_INVALID_ACCESS);
1208
1209 return FALSE;
1210 }
1211
1212 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1213
1214 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1215 NULL,
1216 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1217 sizeof(CONSOLE_GETSETCURSORINFO));
1218 if (!NT_SUCCESS(Status))
1219 {
1220 BaseSetLastNTError(Status);
1221 return FALSE;
1222 }
1223
1224 *lpConsoleCursorInfo = ApiMessage.Data.CursorInfoRequest.Info;
1225
1226 return TRUE;
1227 }
1228
1229
1230 /*--------------------------------------------------------------
1231 * GetNumberOfConsoleMouseButtons
1232 *
1233 * @unimplemented
1234 */
1235 BOOL
1236 WINAPI
1237 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1238 {
1239 DPRINT1("GetNumberOfConsoleMouseButtons(0x%p) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
1240 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1241 return FALSE;
1242 }
1243
1244
1245 /*--------------------------------------------------------------
1246 * SetConsoleMode
1247 *
1248 * @implemented
1249 */
1250 BOOL
1251 WINAPI
1252 SetConsoleMode(HANDLE hConsoleHandle,
1253 DWORD dwMode)
1254 {
1255 NTSTATUS Status;
1256 CONSOLE_API_MESSAGE ApiMessage;
1257 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1258
1259 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1260 ConsoleModeRequest->ConsoleMode = dwMode;
1261
1262 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1263 NULL,
1264 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1265 sizeof(CONSOLE_GETSETCONSOLEMODE));
1266 if (!NT_SUCCESS(Status))
1267 {
1268 BaseSetLastNTError(Status);
1269 return FALSE;
1270 }
1271
1272 return TRUE;
1273 }
1274
1275
1276 /*--------------------------------------------------------------
1277 * SetConsoleActiveScreenBuffer
1278 *
1279 * @implemented
1280 */
1281 BOOL
1282 WINAPI
1283 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1284 {
1285 NTSTATUS Status;
1286 CONSOLE_API_MESSAGE ApiMessage;
1287
1288 ApiMessage.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
1289
1290 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1291 NULL,
1292 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1293 sizeof(CONSOLE_SETACTIVESCREENBUFFER));
1294 if (!NT_SUCCESS(Status))
1295 {
1296 BaseSetLastNTError(Status);
1297 return FALSE;
1298 }
1299
1300 return TRUE;
1301 }
1302
1303
1304 /*--------------------------------------------------------------
1305 * FlushConsoleInputBuffer
1306 *
1307 * @implemented
1308 */
1309 BOOL
1310 WINAPI
1311 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1312 {
1313 NTSTATUS Status;
1314 CONSOLE_API_MESSAGE ApiMessage;
1315
1316 ApiMessage.Data.FlushInputBufferRequest.InputHandle = hConsoleInput;
1317
1318 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1319 NULL,
1320 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1321 sizeof(CONSOLE_FLUSHINPUTBUFFER));
1322 if (!NT_SUCCESS(Status))
1323 {
1324 BaseSetLastNTError(Status);
1325 return FALSE;
1326 }
1327
1328 return TRUE;
1329 }
1330
1331
1332 /*--------------------------------------------------------------
1333 * SetConsoleScreenBufferSize
1334 *
1335 * @implemented
1336 */
1337 BOOL
1338 WINAPI
1339 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1340 COORD dwSize)
1341 {
1342 NTSTATUS Status;
1343 CONSOLE_API_MESSAGE ApiMessage;
1344
1345 ApiMessage.Data.SetScreenBufferSizeRequest.OutputHandle = hConsoleOutput;
1346 ApiMessage.Data.SetScreenBufferSizeRequest.Size = dwSize;
1347
1348 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1349 NULL,
1350 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1351 sizeof(CONSOLE_SETSCREENBUFFERSIZE));
1352 if (!NT_SUCCESS(Status))
1353 {
1354 BaseSetLastNTError(Status);
1355 return FALSE;
1356 }
1357
1358 return TRUE;
1359 }
1360
1361
1362 /*--------------------------------------------------------------
1363 * SetConsoleCursorInfo
1364 *
1365 * @implemented
1366 */
1367 BOOL
1368 WINAPI
1369 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1370 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1371 {
1372 NTSTATUS Status;
1373 CONSOLE_API_MESSAGE ApiMessage;
1374
1375 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1376 ApiMessage.Data.CursorInfoRequest.Info = *lpConsoleCursorInfo;
1377
1378 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1379 NULL,
1380 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1381 sizeof(CONSOLE_GETSETCURSORINFO));
1382 if (!NT_SUCCESS(Status))
1383 {
1384 BaseSetLastNTError(Status);
1385 return FALSE;
1386 }
1387
1388 return TRUE;
1389 }
1390
1391
1392 static
1393 BOOL
1394 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1395 const SMALL_RECT *lpScrollRectangle,
1396 const SMALL_RECT *lpClipRectangle,
1397 COORD dwDestinationOrigin,
1398 const CHAR_INFO *lpFill,
1399 BOOL bUnicode)
1400 {
1401 NTSTATUS Status;
1402 CONSOLE_API_MESSAGE ApiMessage;
1403 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1404
1405 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1406 ScrollScreenBufferRequest->Unicode = bUnicode;
1407 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1408
1409 if (lpClipRectangle != NULL)
1410 {
1411 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1412 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1413 }
1414 else
1415 {
1416 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1417 }
1418
1419 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1420 ScrollScreenBufferRequest->Fill = *lpFill;
1421
1422 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1423 NULL,
1424 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1425 sizeof(CONSOLE_SCROLLSCREENBUFFER));
1426
1427 if (!NT_SUCCESS(Status))
1428 {
1429 BaseSetLastNTError(Status);
1430 return FALSE;
1431 }
1432
1433 return TRUE;
1434 }
1435
1436
1437 /*--------------------------------------------------------------
1438 * ScrollConsoleScreenBufferA
1439 *
1440 * @implemented
1441 */
1442 BOOL
1443 WINAPI
1444 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1445 CONST SMALL_RECT *lpScrollRectangle,
1446 CONST SMALL_RECT *lpClipRectangle,
1447 COORD dwDestinationOrigin,
1448 CONST CHAR_INFO *lpFill)
1449 {
1450 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1451 (PSMALL_RECT)lpScrollRectangle,
1452 (PSMALL_RECT)lpClipRectangle,
1453 dwDestinationOrigin,
1454 (PCHAR_INFO)lpFill,
1455 FALSE);
1456 }
1457
1458
1459 /*--------------------------------------------------------------
1460 * ScrollConsoleScreenBufferW
1461 *
1462 * @implemented
1463 */
1464 BOOL
1465 WINAPI
1466 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1467 CONST SMALL_RECT *lpScrollRectangle,
1468 CONST SMALL_RECT *lpClipRectangle,
1469 COORD dwDestinationOrigin,
1470 CONST CHAR_INFO *lpFill)
1471 {
1472 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1473 lpScrollRectangle,
1474 lpClipRectangle,
1475 dwDestinationOrigin,
1476 lpFill,
1477 TRUE);
1478 }
1479
1480
1481 /*--------------------------------------------------------------
1482 * SetConsoleWindowInfo
1483 *
1484 * @implemented
1485 */
1486 BOOL
1487 WINAPI
1488 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1489 BOOL bAbsolute,
1490 CONST SMALL_RECT *lpConsoleWindow)
1491 {
1492 NTSTATUS Status;
1493 CONSOLE_API_MESSAGE ApiMessage;
1494 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1495
1496 if (lpConsoleWindow == NULL)
1497 {
1498 SetLastError(ERROR_INVALID_PARAMETER);
1499 return FALSE;
1500 }
1501
1502 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1503 SetWindowInfoRequest->Absolute = bAbsolute;
1504 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1505
1506 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1507 NULL,
1508 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1509 sizeof(CONSOLE_SETWINDOWINFO));
1510 if (!NT_SUCCESS(Status))
1511 {
1512 BaseSetLastNTError(Status);
1513 return FALSE;
1514 }
1515
1516 return TRUE;
1517 }
1518
1519
1520 /*--------------------------------------------------------------
1521 * SetConsoleTextAttribute
1522 *
1523 * @implemented
1524 */
1525 BOOL
1526 WINAPI
1527 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1528 WORD wAttributes)
1529 {
1530 NTSTATUS Status;
1531 CONSOLE_API_MESSAGE ApiMessage;
1532
1533 ApiMessage.Data.SetTextAttribRequest.OutputHandle = hConsoleOutput;
1534 ApiMessage.Data.SetTextAttribRequest.Attrib = wAttributes;
1535
1536 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1537 NULL,
1538 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1539 sizeof(CONSOLE_SETTEXTATTRIB));
1540 if (!NT_SUCCESS(Status))
1541 {
1542 BaseSetLastNTError(Status);
1543 return FALSE;
1544 }
1545
1546 return TRUE;
1547 }
1548
1549
1550 static
1551 BOOL
1552 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1553 {
1554 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1555
1556 if (HandlerRoutine == NULL)
1557 {
1558 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1559 return TRUE;
1560 }
1561
1562 if (NrCtrlHandlers == NrAllocatedHandlers)
1563 {
1564 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1565 0,
1566 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1567 if (NewCtrlHandlers == NULL)
1568 {
1569 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1570 return FALSE;
1571 }
1572
1573 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1574
1575 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1576
1577 CtrlHandlers = NewCtrlHandlers;
1578 NrAllocatedHandlers += 4;
1579 }
1580
1581 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1582
1583 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1584 return TRUE;
1585 }
1586
1587
1588 static
1589 BOOL
1590 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1591 {
1592 ULONG i;
1593
1594 if (HandlerRoutine == NULL)
1595 {
1596 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1597 return TRUE;
1598 }
1599
1600 for (i = 0; i < NrCtrlHandlers; i++)
1601 {
1602 if (CtrlHandlers[i] == HandlerRoutine)
1603 {
1604 if (i < (NrCtrlHandlers - 1))
1605 {
1606 memmove(&CtrlHandlers[i],
1607 &CtrlHandlers[i+1],
1608 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1609 }
1610
1611 NrCtrlHandlers--;
1612 return TRUE;
1613 }
1614 }
1615
1616 SetLastError(ERROR_INVALID_PARAMETER);
1617 return FALSE;
1618 }
1619
1620
1621 /*
1622 * @implemented
1623 */
1624 BOOL
1625 WINAPI
1626 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1627 BOOL Add)
1628 {
1629 BOOL Ret;
1630
1631 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1632 if (Add)
1633 {
1634 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1635 }
1636 else
1637 {
1638 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1639 }
1640
1641 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1642 return(Ret);
1643 }
1644
1645
1646 /*--------------------------------------------------------------
1647 * GenerateConsoleCtrlEvent
1648 *
1649 * @implemented
1650 */
1651 BOOL
1652 WINAPI
1653 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1654 DWORD dwProcessGroupId)
1655 {
1656 NTSTATUS Status;
1657 CONSOLE_API_MESSAGE ApiMessage;
1658
1659 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1660 {
1661 SetLastError(ERROR_INVALID_PARAMETER);
1662 return FALSE;
1663 }
1664
1665 ApiMessage.Data.GenerateCtrlEventRequest.Event = dwCtrlEvent;
1666 ApiMessage.Data.GenerateCtrlEventRequest.ProcessGroup = dwProcessGroupId;
1667
1668 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1669 NULL,
1670 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1671 sizeof(CONSOLE_GENERATECTRLEVENT));
1672 if (!NT_SUCCESS(Status))
1673 {
1674 BaseSetLastNTError(Status);
1675 return FALSE;
1676 }
1677
1678 return TRUE;
1679 }
1680
1681
1682 static DWORD
1683 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
1684 {
1685 NTSTATUS Status;
1686 CONSOLE_API_MESSAGE ApiMessage;
1687 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1688 PCSR_CAPTURE_BUFFER CaptureBuffer;
1689
1690 if (nSize == 0) return 0;
1691
1692 TitleRequest->Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
1693 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1694 if (CaptureBuffer == NULL)
1695 {
1696 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1697 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1698 return 0;
1699 }
1700
1701 CsrAllocateMessagePointer(CaptureBuffer,
1702 TitleRequest->Length,
1703 (PVOID*)&TitleRequest->Title);
1704
1705 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1706 CaptureBuffer,
1707 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1708 sizeof(CONSOLE_GETSETCONSOLETITLE));
1709 if (!NT_SUCCESS(Status))
1710 {
1711 CsrFreeCaptureBuffer(CaptureBuffer);
1712 BaseSetLastNTError(Status);
1713 return 0;
1714 }
1715
1716 if (bUnicode)
1717 {
1718 if (nSize >= sizeof(WCHAR))
1719 wcscpy((LPWSTR)lpConsoleTitle, TitleRequest->Title);
1720 }
1721 else
1722 {
1723 if (nSize < TitleRequest->Length / sizeof(WCHAR) ||
1724 !WideCharToMultiByte(CP_ACP, // ANSI code page
1725 0, // performance and mapping flags
1726 TitleRequest->Title, // address of wide-character string
1727 -1, // number of characters in string
1728 (LPSTR)lpConsoleTitle, // address of buffer for new string
1729 nSize, // size of buffer
1730 NULL, // FAST
1731 NULL))
1732 {
1733 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1734 *(LPSTR)lpConsoleTitle = '\0';
1735 TitleRequest->Length = 0;
1736 }
1737 }
1738 CsrFreeCaptureBuffer(CaptureBuffer);
1739
1740 return TitleRequest->Length / sizeof(WCHAR);
1741 }
1742
1743
1744 /*--------------------------------------------------------------
1745 * GetConsoleTitleW
1746 *
1747 * @implemented
1748 */
1749 DWORD
1750 WINAPI
1751 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1752 DWORD nSize)
1753 {
1754 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1755 }
1756
1757
1758 /*--------------------------------------------------------------
1759 * GetConsoleTitleA
1760 *
1761 * @implemented
1762 */
1763 DWORD
1764 WINAPI
1765 GetConsoleTitleA(LPSTR lpConsoleTitle,
1766 DWORD nSize)
1767 {
1768 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1769 }
1770
1771
1772 /*--------------------------------------------------------------
1773 * SetConsoleTitleW
1774 *
1775 * @implemented
1776 */
1777 BOOL
1778 WINAPI
1779 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1780 {
1781 NTSTATUS Status;
1782 CONSOLE_API_MESSAGE ApiMessage;
1783 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1784 PCSR_CAPTURE_BUFFER CaptureBuffer;
1785
1786 TitleRequest->Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
1787
1788 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1789 if (CaptureBuffer == NULL)
1790 {
1791 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1792 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1793 return FALSE;
1794 }
1795
1796 CsrCaptureMessageBuffer(CaptureBuffer,
1797 (PVOID)lpConsoleTitle,
1798 TitleRequest->Length,
1799 (PVOID*)&TitleRequest->Title);
1800
1801 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1802 CaptureBuffer,
1803 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1804 sizeof(CONSOLE_GETSETCONSOLETITLE));
1805
1806 CsrFreeCaptureBuffer(CaptureBuffer);
1807
1808 if (!NT_SUCCESS(Status))
1809 {
1810 BaseSetLastNTError(Status);
1811 return FALSE;
1812 }
1813
1814 return TRUE;
1815 }
1816
1817
1818 /*--------------------------------------------------------------
1819 * SetConsoleTitleA
1820 *
1821 * @implemented
1822 */
1823 BOOL
1824 WINAPI
1825 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1826 {
1827 BOOL Ret;
1828 ULONG Length = strlen(lpConsoleTitle) + 1;
1829 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1830
1831 if (!WideTitle)
1832 {
1833 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1834 return FALSE;
1835 }
1836
1837 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
1838
1839 Ret = SetConsoleTitleW(WideTitle);
1840
1841 HeapFree(GetProcessHeap(), 0, WideTitle);
1842 return Ret;
1843 }
1844
1845
1846 /*--------------------------------------------------------------
1847 * CreateConsoleScreenBuffer
1848 *
1849 * @implemented
1850 */
1851 HANDLE
1852 WINAPI
1853 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1854 DWORD dwShareMode,
1855 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1856 DWORD dwFlags,
1857 LPVOID lpScreenBufferData)
1858 {
1859 NTSTATUS Status;
1860 CONSOLE_API_MESSAGE ApiMessage;
1861 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1862 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1863 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData;
1864
1865 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1866 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1867 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1868 {
1869 SetLastError(ERROR_INVALID_PARAMETER);
1870 return INVALID_HANDLE_VALUE;
1871 }
1872
1873 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1874 CreateScreenBufferRequest->Access = dwDesiredAccess;
1875 CreateScreenBufferRequest->ShareMode = dwShareMode;
1876 CreateScreenBufferRequest->Inheritable =
1877 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1878
1879 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1880 {
1881 if (CreateScreenBufferRequest->Inheritable || GraphicsBufferInfo == NULL)
1882 {
1883 SetLastError(ERROR_INVALID_PARAMETER);
1884 return INVALID_HANDLE_VALUE;
1885 }
1886
1887 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
1888
1889 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
1890 if (CaptureBuffer == NULL)
1891 {
1892 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1893 return FALSE;
1894 }
1895
1896 CsrCaptureMessageBuffer(CaptureBuffer,
1897 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
1898 GraphicsBufferInfo->dwBitMapInfoLength,
1899 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
1900 }
1901
1902 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1903 CaptureBuffer,
1904 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1905 sizeof(CONSOLE_CREATESCREENBUFFER));
1906
1907 if (CaptureBuffer)
1908 CsrFreeCaptureBuffer(CaptureBuffer);
1909
1910 if (!NT_SUCCESS(Status))
1911 {
1912 BaseSetLastNTError(Status);
1913 return INVALID_HANDLE_VALUE;
1914 }
1915
1916 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
1917 {
1918 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
1919 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
1920 }
1921
1922 return CreateScreenBufferRequest->OutputHandle;
1923 }
1924
1925
1926 /*--------------------------------------------------------------
1927 * GetConsoleCP
1928 *
1929 * @implemented
1930 */
1931 UINT
1932 WINAPI
1933 GetConsoleCP(VOID)
1934 {
1935 NTSTATUS Status;
1936 CONSOLE_API_MESSAGE ApiMessage;
1937
1938 /* Get the Input Code Page */
1939 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1940 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
1941
1942 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1943 NULL,
1944 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1945 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1946
1947 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1948
1949 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1950 }
1951
1952
1953 /*--------------------------------------------------------------
1954 * SetConsoleCP
1955 *
1956 * @implemented
1957 */
1958 BOOL
1959 WINAPI
1960 SetConsoleCP(UINT wCodePageID)
1961 {
1962 NTSTATUS Status;
1963 CONSOLE_API_MESSAGE ApiMessage;
1964
1965 /* Set the Input Code Page */
1966 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1967 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1968
1969 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1970 NULL,
1971 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1972 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1973
1974 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1975
1976 return NT_SUCCESS(Status);
1977 }
1978
1979
1980 /*--------------------------------------------------------------
1981 * GetConsoleOutputCP
1982 *
1983 * @implemented
1984 */
1985 UINT
1986 WINAPI
1987 GetConsoleOutputCP(VOID)
1988 {
1989 NTSTATUS Status;
1990 CONSOLE_API_MESSAGE ApiMessage;
1991
1992 /* Get the Output Code Page */
1993 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1994 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
1995
1996 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1997 NULL,
1998 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1999 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2000
2001 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2002
2003 return ApiMessage.Data.ConsoleCPRequest.CodePage;
2004 }
2005
2006
2007 /*--------------------------------------------------------------
2008 * SetConsoleOutputCP
2009 *
2010 * @implemented
2011 */
2012 BOOL
2013 WINAPI
2014 SetConsoleOutputCP(UINT wCodePageID)
2015 {
2016 NTSTATUS Status;
2017 CONSOLE_API_MESSAGE ApiMessage;
2018
2019 /* Set the Output Code Page */
2020 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
2021 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
2022
2023 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2024 NULL,
2025 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2026 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2027
2028 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2029
2030 return NT_SUCCESS(Status);
2031 }
2032
2033
2034 /*--------------------------------------------------------------
2035 * GetConsoleProcessList
2036 *
2037 * @implemented
2038 */
2039 DWORD
2040 WINAPI
2041 GetConsoleProcessList(LPDWORD lpdwProcessList,
2042 DWORD dwProcessCount)
2043 {
2044 NTSTATUS Status;
2045 CONSOLE_API_MESSAGE ApiMessage;
2046 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2047 PCSR_CAPTURE_BUFFER CaptureBuffer;
2048 ULONG nProcesses;
2049
2050 if (lpdwProcessList == NULL || dwProcessCount == 0)
2051 {
2052 SetLastError(ERROR_INVALID_PARAMETER);
2053 return 0;
2054 }
2055
2056 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2057 if (CaptureBuffer == NULL)
2058 {
2059 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2060 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2061 return FALSE;
2062 }
2063
2064 GetProcessListRequest->nMaxIds = dwProcessCount;
2065
2066 CsrAllocateMessagePointer(CaptureBuffer,
2067 dwProcessCount * sizeof(DWORD),
2068 (PVOID*)&GetProcessListRequest->pProcessIds);
2069
2070 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2071 CaptureBuffer,
2072 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2073 sizeof(CONSOLE_GETPROCESSLIST));
2074 if (!NT_SUCCESS(Status))
2075 {
2076 BaseSetLastNTError (Status);
2077 nProcesses = 0;
2078 }
2079 else
2080 {
2081 nProcesses = GetProcessListRequest->nProcessIdsTotal;
2082 if (dwProcessCount >= nProcesses)
2083 {
2084 memcpy(lpdwProcessList, GetProcessListRequest->pProcessIds, nProcesses * sizeof(DWORD));
2085 }
2086 }
2087
2088 CsrFreeCaptureBuffer(CaptureBuffer);
2089 return nProcesses;
2090 }
2091
2092
2093 /*--------------------------------------------------------------
2094 * GetConsoleSelectionInfo
2095 *
2096 * @implemented
2097 */
2098 BOOL
2099 WINAPI
2100 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2101 {
2102 NTSTATUS Status;
2103 CONSOLE_API_MESSAGE ApiMessage;
2104
2105 if (lpConsoleSelectionInfo == NULL)
2106 {
2107 SetLastError(ERROR_INVALID_PARAMETER);
2108 return FALSE;
2109 }
2110
2111 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2112 NULL,
2113 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2114 sizeof(CONSOLE_GETSELECTIONINFO));
2115 if (!NT_SUCCESS(Status))
2116 {
2117 BaseSetLastNTError(Status);
2118 return FALSE;
2119 }
2120
2121 *lpConsoleSelectionInfo = ApiMessage.Data.GetSelectionInfoRequest.Info;
2122 return TRUE;
2123 }
2124
2125
2126 /*--------------------------------------------------------------
2127 * AttachConsole
2128 *
2129 * @implemented
2130 *
2131 * @note Strongly inspired by AllocConsole.
2132 */
2133 BOOL
2134 WINAPI
2135 AttachConsole(DWORD dwProcessId)
2136 {
2137 NTSTATUS Status;
2138 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2139 CONSOLE_API_MESSAGE ApiMessage;
2140 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2141
2142 if (Parameters->ConsoleHandle)
2143 {
2144 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2145 SetLastError(ERROR_ACCESS_DENIED);
2146 return FALSE;
2147 }
2148
2149 AttachConsoleRequest->ProcessId = dwProcessId;
2150 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2151 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2152
2153 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2154 NULL,
2155 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2156 sizeof(CONSOLE_ATTACHCONSOLE));
2157 if (!NT_SUCCESS(Status))
2158 {
2159 BaseSetLastNTError(Status);
2160 return FALSE;
2161 }
2162
2163 Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle;
2164 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2165 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2166 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2167
2168 /* Initialize Console Ctrl Handler */
2169 InitConsoleCtrlHandling();
2170
2171 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2172
2173 return TRUE;
2174 }
2175
2176
2177 /*--------------------------------------------------------------
2178 * GetConsoleWindow
2179 *
2180 * @implemented
2181 */
2182 HWND
2183 WINAPI
2184 GetConsoleWindow(VOID)
2185 {
2186 NTSTATUS Status;
2187 CONSOLE_API_MESSAGE ApiMessage;
2188
2189 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2190 NULL,
2191 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2192 sizeof(CONSOLE_GETWINDOW));
2193 if (!NT_SUCCESS(Status))
2194 {
2195 BaseSetLastNTError(Status);
2196 return (HWND)NULL;
2197 }
2198
2199 return ApiMessage.Data.GetWindowRequest.WindowHandle;
2200 }
2201
2202
2203 /*--------------------------------------------------------------
2204 * SetConsoleIcon
2205 *
2206 * @implemented
2207 */
2208 BOOL
2209 WINAPI
2210 SetConsoleIcon(HICON hicon)
2211 {
2212 NTSTATUS Status;
2213 CONSOLE_API_MESSAGE ApiMessage;
2214
2215 ApiMessage.Data.SetIconRequest.WindowIcon = hicon;
2216
2217 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2218 NULL,
2219 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2220 sizeof(CONSOLE_SETICON));
2221 if (!NT_SUCCESS(Status))
2222 {
2223 BaseSetLastNTError(Status);
2224 return FALSE;
2225 }
2226
2227 return NT_SUCCESS(Status);
2228 }
2229
2230
2231 /******************************************************************************
2232 * \name SetConsoleInputExeNameW
2233 * \brief Sets the console input file name from a unicode string.
2234 * \param lpInputExeName Pointer to a unicode string with the name.
2235 * \return TRUE if successful, FALSE if unsuccsedful.
2236 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2237 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2238 */
2239 BOOL
2240 WINAPI
2241 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2242 {
2243 int lenName;
2244
2245 if ( !lpInputExeName ||
2246 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2247 lenName > INPUTEXENAME_BUFLEN - 1 )
2248 {
2249 /* Fail if string is empty or too long */
2250 SetLastError(ERROR_INVALID_PARAMETER);
2251 return FALSE;
2252 }
2253
2254 RtlEnterCriticalSection(&ConsoleLock);
2255 _SEH2_TRY
2256 {
2257 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2258 InputExeName[lenName] = L'\0';
2259 }
2260 _SEH2_FINALLY
2261 {
2262 RtlLeaveCriticalSection(&ConsoleLock);
2263 }
2264 _SEH2_END;
2265
2266 return TRUE;
2267 }
2268
2269
2270 /******************************************************************************
2271 * \name SetConsoleInputExeNameA
2272 * \brief Sets the console input file name from an ansi string.
2273 * \param lpInputExeName Pointer to an ansi string with the name.
2274 * \return TRUE if successful, FALSE if unsuccsedful.
2275 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2276 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2277 */
2278 BOOL
2279 WINAPI
2280 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2281 {
2282 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2283 ANSI_STRING InputExeNameA;
2284 UNICODE_STRING InputExeNameU;
2285 NTSTATUS Status;
2286
2287 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2288
2289 if ( InputExeNameA.Length == 0 ||
2290 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2291 {
2292 /* Fail if string is empty or too long */
2293 SetLastError(ERROR_INVALID_PARAMETER);
2294 return FALSE;
2295 }
2296
2297 InputExeNameU.Buffer = Buffer;
2298 InputExeNameU.MaximumLength = sizeof(Buffer);
2299 InputExeNameU.Length = 0;
2300
2301 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2302 if (!NT_SUCCESS(Status))
2303 {
2304 BaseSetLastNTError(Status);
2305 return FALSE;
2306 }
2307
2308 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2309 }
2310
2311
2312 /******************************************************************************
2313 * \name GetConsoleInputExeNameW
2314 * \brief Retrieves the console input file name as unicode string.
2315 * \param nBufferLength Length of the buffer in WCHARs.
2316 * Specify 0 to receive the needed buffer length.
2317 * \param lpBuffer Pointer to a buffer that receives the string.
2318 * \return Needed buffer size if \p nBufferLength is 0.
2319 * Otherwise 1 if successful, 2 if buffer is too small.
2320 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2321 * is not big enough.
2322 */
2323 DWORD
2324 WINAPI
2325 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2326 {
2327 ULONG lenName = lstrlenW(InputExeName);
2328
2329 if (nBufferLength == 0)
2330 {
2331 /* Buffer size is requested, return it */
2332 return lenName + 1;
2333 }
2334
2335 if (lenName + 1 > nBufferLength)
2336 {
2337 /* Buffer is not large enough! */
2338 SetLastError(ERROR_BUFFER_OVERFLOW);
2339 return 2;
2340 }
2341
2342 RtlEnterCriticalSection(&ConsoleLock);
2343 _SEH2_TRY
2344 {
2345 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2346 lpBuffer[lenName] = '\0';
2347 }
2348 _SEH2_FINALLY
2349 {
2350 RtlLeaveCriticalSection(&ConsoleLock);
2351 }
2352 _SEH2_END;
2353
2354 /* Success, return 1 */
2355 return 1;
2356 }
2357
2358
2359 /******************************************************************************
2360 * \name GetConsoleInputExeNameA
2361 * \brief Retrieves the console input file name as ansi string.
2362 * \param nBufferLength Length of the buffer in CHARs.
2363 * \param lpBuffer Pointer to a buffer that receives the string.
2364 * \return 1 if successful, 2 if buffer is too small.
2365 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2366 * is not big enough. The buffer receives as much characters as fit.
2367 */
2368 DWORD
2369 WINAPI
2370 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2371 {
2372 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2373 DWORD Ret;
2374 UNICODE_STRING BufferU;
2375 ANSI_STRING BufferA;
2376
2377 /* Get the unicode name */
2378 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2379
2380 /* Initialize strings for conversion */
2381 RtlInitUnicodeString(&BufferU, Buffer);
2382 BufferA.Length = 0;
2383 BufferA.MaximumLength = (USHORT)nBufferLength;
2384 BufferA.Buffer = lpBuffer;
2385
2386 /* Convert unicode name to ansi, copying as much chars as fit */
2387 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2388
2389 /* Error handling */
2390 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2391 {
2392 SetLastError(ERROR_BUFFER_OVERFLOW);
2393 return 2;
2394 }
2395
2396 return Ret;
2397 }
2398
2399 BOOL
2400 WINAPI
2401 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2402 {
2403 STUB;
2404 return FALSE;
2405 }
2406
2407 BOOL
2408 WINAPI
2409 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2410 {
2411 STUB;
2412 return FALSE;
2413 }
2414
2415 BOOL
2416 WINAPI
2417 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2418 {
2419 STUB;
2420 return FALSE;
2421 }
2422
2423 BOOL
2424 WINAPI
2425 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2426 {
2427 STUB;
2428 return FALSE;
2429 }
2430
2431 BOOL
2432 WINAPI
2433 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2434 {
2435 STUB;
2436 return FALSE;
2437 }
2438
2439 BOOL
2440 WINAPI
2441 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2442 {
2443 STUB;
2444 return FALSE;
2445 }
2446
2447 BOOL
2448 WINAPI
2449 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2450 {
2451 STUB;
2452 return FALSE;
2453 }
2454
2455 BOOL
2456 WINAPI
2457 RegisterConsoleOS2(BOOL bUnknown)
2458 {
2459 STUB;
2460 return FALSE;
2461 }
2462
2463 BOOL
2464 WINAPI
2465 SetConsoleOS2OemFormat(BOOL bUnknown)
2466 {
2467 STUB;
2468 return FALSE;
2469 }
2470
2471 BOOL
2472 WINAPI
2473 UnregisterConsoleIME(VOID)
2474 {
2475 STUB;
2476 return FALSE;
2477 }
2478
2479
2480 /*
2481 * @unimplemented
2482 */
2483 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2484 {
2485 STUB;
2486 return 0;
2487 }
2488
2489 /*
2490 * @unimplemented
2491 */
2492 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2493 {
2494 STUB;
2495 return 0;
2496 }
2497
2498 /*
2499 * @unimplemented
2500 */
2501 BOOL
2502 WINAPI
2503 SetLastConsoleEventActive(VOID)
2504 {
2505 STUB;
2506 return FALSE;
2507 }
2508
2509 /* EOF */