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