Partially fixed up tree after merge from HEAD. More to do.
[reactos.git] / reactos / dll / win32 / kernel32 / misc / console.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/console.c
6 * PURPOSE: Win32 server console functions
7 * PROGRAMMER: James Tabor
8 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
9 * UPDATE HISTORY:
10 * 199901?? ?? Created
11 * 19990204 EA SetConsoleTitleA
12 * 19990306 EA Stubs
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 /* File contains Vista Semantics */
18 #undef _WIN32_WINNT
19 #define _WIN32_WINNT 0x0600
20
21 #include <k32.h>
22
23 #define NDEBUG
24 #include "../include/debug.h"
25
26 extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
27 extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
28 extern RTL_CRITICAL_SECTION ConsoleLock;
29 extern BOOL WINAPI IsDebuggerPresent(VOID);
30
31
32 /* GLOBALS *******************************************************************/
33
34 static BOOL IgnoreCtrlEvents = FALSE;
35
36 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
37 static ULONG NrCtrlHandlers = 0;
38 static WCHAR InputExeName[MAX_PATH + 1] = L"";
39
40 /* Default Console Control Handler *******************************************/
41
42 BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
43 {
44 switch(Event)
45 {
46 case CTRL_C_EVENT:
47 DPRINT("Ctrl-C Event\n");
48 break;
49
50 case CTRL_BREAK_EVENT:
51 DPRINT("Ctrl-Break Event\n");
52 break;
53
54 case CTRL_SHUTDOWN_EVENT:
55 DPRINT("Ctrl Shutdown Event\n");
56 break;
57
58 case CTRL_CLOSE_EVENT:
59 DPRINT("Ctrl Close Event\n");
60 break;
61
62 case CTRL_LOGOFF_EVENT:
63 DPRINT("Ctrl Logoff Event\n");
64 break;
65 }
66 ExitProcess(0);
67 return TRUE;
68 }
69
70
71 __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag)
72 {
73 DWORD nExitCode = 0;
74 DWORD nCode = CodeAndFlag & MAXLONG;
75 UINT i;
76
77 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
78
79 switch(nCode)
80 {
81 case CTRL_C_EVENT:
82 case CTRL_BREAK_EVENT:
83 {
84 if(IsDebuggerPresent())
85 {
86 EXCEPTION_RECORD erException;
87 erException.ExceptionCode =
88 (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
89 erException.ExceptionFlags = 0;
90 erException.ExceptionRecord = NULL;
91 erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
92 erException.NumberParameters = 0;
93 RtlRaiseException(&erException);
94 }
95 RtlEnterCriticalSection(&ConsoleLock);
96
97 if(!(nCode == CTRL_C_EVENT &&
98 NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
99 {
100 for(i = NrCtrlHandlers; i > 0; -- i)
101 if(CtrlHandlers[i - 1](nCode)) break;
102 }
103 RtlLeaveCriticalSection(&ConsoleLock);
104 ExitThread(0);
105 }
106 case CTRL_CLOSE_EVENT:
107 case CTRL_LOGOFF_EVENT:
108 case CTRL_SHUTDOWN_EVENT:
109 break;
110
111 default: ExitThread(0);
112 }
113
114 RtlEnterCriticalSection(&ConsoleLock);
115
116 if(!(nCode == CTRL_C_EVENT &&
117 NtCurrentPeb()->ProcessParameters->ConsoleFlags & 1))
118 {
119 i = NrCtrlHandlers;
120 while(i > 0)
121 {
122 if (i == 1 && (CodeAndFlag & MINLONG) &&
123 (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
124 break;
125
126 if(CtrlHandlers[i - 1](nCode))
127 {
128 switch(nCode)
129 {
130 case CTRL_CLOSE_EVENT:
131 case CTRL_LOGOFF_EVENT:
132 case CTRL_SHUTDOWN_EVENT:
133 nExitCode = CodeAndFlag;
134 }
135 break;
136 }
137 --i;
138 }
139 }
140 RtlLeaveCriticalSection(&ConsoleLock);
141 ExitThread(nExitCode);
142 }
143
144
145 /* FUNCTIONS *****************************************************************/
146
147 /*
148 * @unimplemented
149 */
150 BOOL STDCALL
151 AddConsoleAliasA (LPSTR Source,
152 LPSTR Target,
153 LPSTR ExeName)
154 {
155 DPRINT1("AddConsoleAliasA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
156 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
157 return FALSE;
158 }
159
160
161 /*
162 * @unimplemented
163 */
164 BOOL STDCALL
165 AddConsoleAliasW (LPWSTR Source,
166 LPWSTR Target,
167 LPWSTR ExeName)
168 {
169 DPRINT1("AddConsoleAliasW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Source, Target, ExeName);
170 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
171 return FALSE;
172 }
173
174
175 /*
176 * @unimplemented
177 */
178 BOOL STDCALL
179 ConsoleMenuControl (HANDLE hConsole,
180 DWORD Unknown1,
181 DWORD Unknown2)
182 /*
183 * Undocumented
184 */
185 {
186 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
187 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
188 return FALSE;
189 }
190
191
192 /*
193 * @implemented
194 */
195 HANDLE STDCALL
196 DuplicateConsoleHandle (HANDLE hConsole,
197 DWORD dwDesiredAccess,
198 BOOL bInheritHandle,
199 DWORD dwOptions)
200 {
201 CSR_API_MESSAGE Request;
202 ULONG CsrRequest;
203 NTSTATUS Status;
204
205 if (IsConsoleHandle (hConsole) == FALSE)
206 {
207 SetLastError (ERROR_INVALID_PARAMETER);
208 return INVALID_HANDLE_VALUE;
209 }
210
211 CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
212 Request.Data.DuplicateHandleRequest.Handle = hConsole;
213 Request.Data.DuplicateHandleRequest.ProcessId = GetTeb()->Cid.UniqueProcess;
214 Status = CsrClientCallServer(&Request,
215 NULL,
216 CsrRequest,
217 sizeof(CSR_API_MESSAGE));
218 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
219 {
220 SetLastErrorByStatus(Status);
221 return INVALID_HANDLE_VALUE;
222 }
223 return Request.Data.DuplicateHandleRequest.Handle;
224 }
225
226
227 /*
228 * @unimplemented
229 */
230 DWORD STDCALL
231 ExpungeConsoleCommandHistoryW (DWORD Unknown0)
232 /*
233 * Undocumented
234 */
235 {
236 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
237 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
238 return 0;
239 }
240
241
242 /*
243 * @unimplemented
244 */
245 DWORD STDCALL
246 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
247 /*
248 * Undocumented
249 */
250 {
251
252 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
253 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
254 return 0;
255 }
256
257
258 /*
259 * @unimplemented
260 */
261 DWORD STDCALL
262 GetConsoleAliasW (LPWSTR lpSource,
263 LPWSTR lpTargetBuffer,
264 DWORD TargetBufferLength,
265 LPWSTR lpExeName)
266 /*
267 * Undocumented
268 */
269 {
270 DPRINT1("GetConsoleAliasW(0x%p, 0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", lpSource, lpTargetBuffer, TargetBufferLength, lpExeName);
271 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
272 return 0;
273 }
274
275
276 /*
277 * @unimplemented
278 */
279 DWORD STDCALL
280 GetConsoleAliasA (LPSTR lpSource,
281 LPSTR lpTargetBuffer,
282 DWORD TargetBufferLength,
283 LPSTR lpExeName)
284 /*
285 * Undocumented
286 */
287 {
288 DPRINT1("GetConsoleAliasA(0x%p, 0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", lpSource, lpTargetBuffer, TargetBufferLength, lpExeName);
289 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
290 return 0;
291 }
292
293
294 /*
295 * @unimplemented
296 */
297 DWORD STDCALL
298 GetConsoleAliasExesW (LPWSTR lpExeNameBuffer,
299 DWORD ExeNameBufferLength)
300 /*
301 * Undocumented
302 */
303 {
304 DPRINT1("GetConsoleAliasExesW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
305 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
306 return 0;
307 }
308
309
310 /*
311 * @unimplemented
312 */
313 DWORD STDCALL
314 GetConsoleAliasExesA (LPSTR lpExeNameBuffer,
315 DWORD ExeNameBufferLength)
316 /*
317 * Undocumented
318 */
319 {
320 DPRINT1("GetConsoleAliasExesA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpExeNameBuffer, ExeNameBufferLength);
321 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
322 return 0;
323 }
324
325
326 /*
327 * @unimplemented
328 */
329 DWORD STDCALL
330 GetConsoleAliasExesLengthA (VOID)
331 /*
332 * Undocumented
333 */
334 {
335 DPRINT1("GetConsoleAliasExesLengthA() UNIMPLEMENTED!\n");
336 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
337 return 0;
338 }
339
340
341 /*
342 * @unimplemented
343 */
344 DWORD STDCALL
345 GetConsoleAliasExesLengthW (VOID)
346 /*
347 * Undocumented
348 */
349 {
350 DPRINT1("GetConsoleAliasExesLengthW() UNIMPLEMENTED!\n");
351 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
352 return 0;
353 }
354
355
356 /*
357 * @unimplemented
358 */
359 DWORD STDCALL
360 GetConsoleAliasesW (DWORD Unknown0,
361 DWORD Unknown1,
362 DWORD Unknown2)
363 /*
364 * Undocumented
365 */
366 {
367 DPRINT1("GetConsoleAliasesW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
368 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
369 return 0;
370 }
371
372
373 /*
374 * @unimplemented
375 */
376 DWORD STDCALL
377 GetConsoleAliasesA (DWORD Unknown0,
378 DWORD Unknown1,
379 DWORD Unknown2)
380 /*
381 * Undocumented
382 */
383 {
384 DPRINT1("GetConsoleAliasesA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
385 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
386 return 0;
387 }
388
389
390 /*
391 * @unimplemented
392 */
393 DWORD STDCALL
394 GetConsoleAliasesLengthW (LPWSTR lpExeName)
395 /*
396 * Undocumented
397 */
398 {
399 DPRINT1("GetConsoleAliasesLengthW(0x%p) UNIMPLEMENTED!\n", lpExeName);
400 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
401 return 0;
402 }
403
404
405 /*
406 * @unimplemented
407 */
408 DWORD STDCALL
409 GetConsoleAliasesLengthA (LPSTR lpExeName)
410 /*
411 * Undocumented
412 */
413 {
414 DPRINT1("GetConsoleAliasesLengthA(0x%p) UNIMPLEMENTED!\n", lpExeName);
415 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
416 return 0;
417 }
418
419
420 /*
421 * @unimplemented
422 */
423 DWORD STDCALL
424 GetConsoleCommandHistoryW (DWORD Unknown0,
425 DWORD Unknown1,
426 DWORD Unknown2)
427 /*
428 * Undocumented
429 */
430 {
431 DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
432 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
433 return 0;
434 }
435
436
437 /*
438 * @unimplemented
439 */
440 DWORD STDCALL
441 GetConsoleCommandHistoryA (DWORD Unknown0,
442 DWORD Unknown1,
443 DWORD Unknown2)
444 /*
445 * Undocumented
446 */
447 {
448 DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
449 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
450 return 0;
451 }
452
453
454 /*
455 * @unimplemented
456 */
457 DWORD STDCALL
458 GetConsoleCommandHistoryLengthW (DWORD Unknown0)
459 /*
460 * Undocumented
461 */
462 {
463 DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
464 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
465 return 0;
466 }
467
468
469 /*
470 * @unimplemented
471 */
472 DWORD STDCALL
473 GetConsoleCommandHistoryLengthA (DWORD Unknown0)
474 /*
475 * Undocumented
476 */
477 {
478 DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
479 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
480 return 0;
481 }
482
483 /*
484 * @unimplemented
485 */
486 DWORD STDCALL
487 GetConsoleDisplayMode (LPDWORD lpdwMode)
488 /*
489 * FUNCTION: Get the console display mode
490 * ARGUMENTS:
491 * lpdwMode - Address of variable that receives the current value
492 * of display mode
493 * STATUS: Undocumented
494 */
495 {
496 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
497 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
498 return 0;
499 }
500
501
502 /*
503 * @unimplemented
504 */
505 DWORD STDCALL
506 GetConsoleFontInfo (DWORD Unknown0,
507 DWORD Unknown1,
508 DWORD Unknown2,
509 DWORD Unknown3)
510 /*
511 * Undocumented
512 */
513 {
514 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
515 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
516 return 0;
517 }
518
519
520 /*
521 * @unimplemented
522 */
523 COORD STDCALL
524 GetConsoleFontSize(HANDLE hConsoleOutput,
525 DWORD nFont)
526 {
527 COORD Empty = {0, 0};
528 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
529 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
530 return Empty ;
531 }
532
533
534 /*
535 * @implemented
536 */
537 DWORD STDCALL
538 GetConsoleHardwareState (HANDLE hConsole,
539 DWORD Flags,
540 PDWORD State)
541 /*
542 * Undocumented
543 */
544 {
545 CSR_API_MESSAGE Request; ULONG CsrRequest;
546
547 NTSTATUS Status;
548
549 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
550 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
551 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
552
553 Status = CsrClientCallServer(& Request,
554 NULL,
555 CsrRequest,
556 sizeof(CSR_API_MESSAGE));
557 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
558 {
559 SetLastErrorByStatus(Status);
560 return FALSE;
561 }
562 *State = Request.Data.ConsoleHardwareStateRequest.State;
563 return TRUE;
564 }
565
566
567 /*
568 * @implemented
569 */
570 DWORD STDCALL
571 GetConsoleInputWaitHandle (VOID)
572 /*
573 * Undocumented
574 */
575 {
576 CSR_API_MESSAGE Request; ULONG CsrRequest;
577
578 NTSTATUS Status;
579
580 CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
581 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
582 sizeof(CSR_API_MESSAGE));
583 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
584 {
585 SetLastErrorByStatus(Status);
586 return 0;
587 }
588 return (DWORD) Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
589 }
590
591
592 /*
593 * @unimplemented
594 */
595 DWORD STDCALL
596 GetCurrentConsoleFont(HANDLE hConsoleOutput,
597 BOOL bMaximumWindow,
598 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
599 {
600 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
601 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
602 return 0;
603 }
604
605
606 /*
607 * @unimplemented
608 */
609 ULONG STDCALL
610 GetNumberOfConsoleFonts (VOID)
611 /*
612 * Undocumented
613 */
614 {
615 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
616 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
617 return 1; /* FIXME: call csrss.exe */
618 }
619
620
621 /*
622 * @unimplemented
623 */
624 DWORD STDCALL
625 InvalidateConsoleDIBits (DWORD Unknown0,
626 DWORD Unknown1)
627 /*
628 * Undocumented
629 */
630 {
631 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
632 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
633 return 0;
634 }
635
636
637 /*
638 * @unimplemented
639 */
640 HANDLE STDCALL
641 OpenConsoleW (LPWSTR wsName,
642 DWORD dwDesiredAccess,
643 BOOL bInheritHandle,
644 DWORD dwCreationDistribution)
645 /*
646 * Undocumented
647 */
648 {
649 CSR_API_MESSAGE Request; ULONG CsrRequest;
650
651 PHANDLE phConsole = NULL;
652 NTSTATUS Status = STATUS_SUCCESS;
653
654 if(0 == _wcsicmp(wsName, L"CONIN$"))
655 {
656 CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
657 phConsole = & Request.Data.GetInputHandleRequest.InputHandle;
658 }
659 else if (0 == _wcsicmp(wsName, L"CONOUT$"))
660 {
661 CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
662 phConsole = & Request.Data.GetOutputHandleRequest.OutputHandle;
663 }
664 else
665 {
666 SetLastError(ERROR_INVALID_PARAMETER);
667 return(INVALID_HANDLE_VALUE);
668 }
669 if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess)
670 {
671 SetLastError(ERROR_INVALID_PARAMETER);
672 return(INVALID_HANDLE_VALUE);
673 }
674 if (OPEN_EXISTING != dwCreationDistribution)
675 {
676 SetLastError(ERROR_INVALID_PARAMETER);
677 return(INVALID_HANDLE_VALUE);
678 }
679 Status = CsrClientCallServer(& Request,
680 NULL,
681 CsrRequest,
682 sizeof(CSR_API_MESSAGE));
683 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
684 {
685 SetLastErrorByStatus(Status);
686 return INVALID_HANDLE_VALUE;
687 }
688 return(*phConsole);
689 }
690
691
692 /*
693 * @unimplemented
694 */
695 BOOL STDCALL
696 SetConsoleCommandHistoryMode (DWORD dwMode)
697 /*
698 * Undocumented
699 */
700 {
701 DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
702 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
703 return FALSE;
704 }
705
706
707 /*
708 * @unimplemented
709 */
710 BOOL STDCALL
711 SetConsoleCursor (DWORD Unknown0,
712 DWORD Unknown1)
713 /*
714 * Undocumented
715 */
716 {
717 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
718 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
719 return FALSE;
720 }
721
722
723 /*
724 * @unimplemented
725 */
726 BOOL STDCALL
727 SetConsoleDisplayMode (HANDLE hOut,
728 DWORD dwNewMode,
729 LPDWORD lpdwOldMode)
730 /*
731 * FUNCTION: Set the console display mode.
732 * ARGUMENTS:
733 * hOut - Standard output handle.
734 * dwNewMode - New mode.
735 * lpdwOldMode - Address of a variable that receives the old mode.
736 */
737 {
738 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
739 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
740 return FALSE;
741 }
742
743
744 /*
745 * @unimplemented
746 */
747 BOOL STDCALL
748 SetConsoleFont (DWORD Unknown0,
749 DWORD Unknown1)
750 /*
751 * Undocumented
752 */
753 {
754 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
755 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
756 return FALSE;
757 }
758
759
760 /*
761 * @implemented
762 */
763 BOOL STDCALL
764 SetConsoleHardwareState (HANDLE hConsole,
765 DWORD Flags,
766 DWORD State)
767 /*
768 * Undocumented
769 */
770 {
771 CSR_API_MESSAGE Request; ULONG CsrRequest;
772
773 NTSTATUS Status;
774
775 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
776 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
777 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
778 Request.Data.ConsoleHardwareStateRequest.State = State;
779
780 Status = CsrClientCallServer(& Request,
781 NULL,
782 CsrRequest,
783 sizeof(CSR_API_MESSAGE));
784 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
785 {
786 SetLastErrorByStatus(Status);
787 return FALSE;
788 }
789 return TRUE;
790 }
791
792
793 /*
794 * @unimplemented
795 */
796 BOOL STDCALL
797 SetConsoleKeyShortcuts (DWORD Unknown0,
798 DWORD Unknown1,
799 DWORD Unknown2,
800 DWORD Unknown3)
801 /*
802 * Undocumented
803 */
804 {
805 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
806 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
807 return FALSE;
808 }
809
810
811 /*
812 * @unimplemented
813 */
814 BOOL STDCALL
815 SetConsoleMaximumWindowSize (DWORD Unknown0,
816 DWORD Unknown1)
817 /*
818 * Undocumented
819 */
820 {
821 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
822 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
823 return FALSE;
824 }
825
826
827 /*
828 * @unimplemented
829 */
830 BOOL STDCALL
831 SetConsoleMenuClose (DWORD Unknown0)
832 /*
833 * Undocumented
834 */
835 {
836 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
837 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
838 return FALSE;
839 }
840
841
842 /*
843 * @unimplemented
844 */
845 BOOL STDCALL
846 SetConsoleNumberOfCommandsA (DWORD Unknown0,
847 DWORD Unknown1)
848 /*
849 * Undocumented
850 */
851 {
852 DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
853 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
854 return FALSE;
855 }
856
857
858 /*
859 * @unimplemented
860 */
861 BOOL STDCALL
862 SetConsoleNumberOfCommandsW (DWORD Unknown0,
863 DWORD Unknown1)
864 /*
865 * Undocumented
866 */
867 {
868 DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
869 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
870 return FALSE;
871 }
872
873
874 /*
875 * @unimplemented
876 */
877 BOOL STDCALL
878 SetConsolePalette (DWORD Unknown0,
879 DWORD Unknown1,
880 DWORD Unknown2)
881 /*
882 * Undocumented
883 */
884 {
885 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
886 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
887 return FALSE;
888 }
889
890
891 /*
892 * @unimplemented
893 */
894 BOOL STDCALL
895 SetLastConsoleEventActive (VOID)
896 /*
897 * Undocumented
898 */
899 {
900 DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
901 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
902 return FALSE;
903 }
904
905
906 /*
907 * @unimplemented
908 */
909 DWORD STDCALL
910 ShowConsoleCursor (DWORD Unknown0,
911 DWORD Unknown1)
912 /*
913 * Undocumented
914 */
915 {
916 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
917 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
918 return 0;
919 }
920
921
922 /*
923 * FUNCTION: Checks whether the given handle is a valid console handle.
924 * ARGUMENTS:
925 * Handle - Handle to be checked
926 * RETURNS:
927 * TRUE: Handle is a valid console handle
928 * FALSE: Handle is not a valid console handle.
929 * STATUS: Officially undocumented
930 *
931 * @implemented
932 */
933 BOOL STDCALL
934 VerifyConsoleIoHandle(HANDLE Handle)
935 {
936 CSR_API_MESSAGE Request; ULONG CsrRequest;
937
938 NTSTATUS Status;
939
940 CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
941 Request.Data.VerifyHandleRequest.Handle = Handle;
942 Status = CsrClientCallServer(&Request,
943 NULL,
944 CsrRequest,
945 sizeof(CSR_API_MESSAGE));
946 if (!NT_SUCCESS(Status))
947 {
948 SetLastErrorByStatus(Status);
949 return FALSE;
950 }
951
952 return (BOOL)NT_SUCCESS(Request.Status);
953 }
954
955
956 /*
957 * @unimplemented
958 */
959 DWORD STDCALL
960 WriteConsoleInputVDMA (DWORD Unknown0,
961 DWORD Unknown1,
962 DWORD Unknown2,
963 DWORD Unknown3)
964 {
965 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
966 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
967 return 0;
968 }
969
970
971 /*
972 * @unimplemented
973 */
974 DWORD STDCALL
975 WriteConsoleInputVDMW (DWORD Unknown0,
976 DWORD Unknown1,
977 DWORD Unknown2,
978 DWORD Unknown3)
979 {
980 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
981 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
982 return 0;
983 }
984
985
986 /*
987 * @implemented
988 */
989 BOOL STDCALL
990 CloseConsoleHandle(HANDLE Handle)
991 /*
992 * Undocumented
993 */
994 {
995 CSR_API_MESSAGE Request; ULONG CsrRequest;
996
997 NTSTATUS Status;
998
999 if (IsConsoleHandle (Handle) == FALSE)
1000 {
1001 SetLastError (ERROR_INVALID_PARAMETER);
1002 return FALSE;
1003 }
1004
1005 CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
1006 Request.Data.CloseHandleRequest.Handle = Handle;
1007 Status = CsrClientCallServer(&Request,
1008 NULL,
1009 CsrRequest,
1010 sizeof(CSR_API_MESSAGE));
1011 if (!NT_SUCCESS(Status))
1012 {
1013 SetLastErrorByStatus(Status);
1014 return FALSE;
1015 }
1016
1017 return TRUE;
1018 }
1019
1020 /*
1021 * @implemented
1022 */
1023 HANDLE STDCALL
1024 GetStdHandle(DWORD nStdHandle)
1025 /*
1026 * FUNCTION: Get a handle for the standard input, standard output
1027 * and a standard error device.
1028 * ARGUMENTS:
1029 * nStdHandle - Specifies the device for which to return the handle.
1030 * RETURNS: If the function succeeds, the return value is the handle
1031 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1032 */
1033 {
1034 PRTL_USER_PROCESS_PARAMETERS Ppb;
1035
1036 Ppb = NtCurrentPeb()->ProcessParameters;
1037 switch (nStdHandle)
1038 {
1039 case STD_INPUT_HANDLE:
1040 return Ppb->StandardInput;
1041
1042 case STD_OUTPUT_HANDLE:
1043 return Ppb->StandardOutput;
1044
1045 case STD_ERROR_HANDLE:
1046 return Ppb->StandardError;
1047 }
1048
1049 SetLastError (ERROR_INVALID_PARAMETER);
1050 return INVALID_HANDLE_VALUE;
1051 }
1052
1053
1054 /*
1055 * @implemented
1056 */
1057 BOOL WINAPI
1058 SetStdHandle(DWORD nStdHandle,
1059 HANDLE hHandle)
1060 /*
1061 * FUNCTION: Set the handle for the standard input, standard output or
1062 * the standard error device.
1063 * ARGUMENTS:
1064 * nStdHandle - Specifies the handle to be set.
1065 * hHandle - The handle to set.
1066 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1067 */
1068 {
1069 PRTL_USER_PROCESS_PARAMETERS Ppb;
1070
1071 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1072
1073 Ppb = NtCurrentPeb()->ProcessParameters;
1074
1075 switch (nStdHandle)
1076 {
1077 case STD_INPUT_HANDLE:
1078 Ppb->StandardInput = hHandle;
1079 return TRUE;
1080
1081 case STD_OUTPUT_HANDLE:
1082 Ppb->StandardOutput = hHandle;
1083 return TRUE;
1084
1085 case STD_ERROR_HANDLE:
1086 Ppb->StandardError = hHandle;
1087 return TRUE;
1088 }
1089
1090 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1091 SetLastError (ERROR_INVALID_HANDLE);
1092 return FALSE;
1093 }
1094
1095
1096 static BOOL
1097 IntWriteConsole(HANDLE hConsoleOutput,
1098 PVOID lpBuffer,
1099 DWORD nNumberOfCharsToWrite,
1100 LPDWORD lpNumberOfCharsWritten,
1101 LPVOID lpReserved,
1102 BOOL bUnicode)
1103 {
1104 PCSR_API_MESSAGE Request;
1105 ULONG CsrRequest;
1106 NTSTATUS Status;
1107 USHORT nChars;
1108 ULONG SizeBytes, CharSize;
1109 DWORD Written = 0;
1110
1111 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1112 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1113 max(sizeof(CSR_API_MESSAGE),
1114 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE)
1115 + min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
1116 if (Request == NULL)
1117 {
1118 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1119 return FALSE;
1120 }
1121
1122 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
1123
1124 while(nNumberOfCharsToWrite > 0)
1125 {
1126 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1127 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1128
1129 nChars = min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1130 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1131
1132 SizeBytes = nChars * CharSize;
1133
1134 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1135
1136 Status = CsrClientCallServer(Request,
1137 NULL,
1138 CsrRequest,
1139 max(sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1140
1141 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1142 {
1143 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1144 SetLastErrorByStatus(Status);
1145 return FALSE;
1146 }
1147
1148 nNumberOfCharsToWrite -= nChars;
1149 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1150 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1151 }
1152
1153 if(lpNumberOfCharsWritten != NULL)
1154 {
1155 *lpNumberOfCharsWritten = Written;
1156 }
1157 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1158
1159 return TRUE;
1160 }
1161
1162
1163 /*--------------------------------------------------------------
1164 * WriteConsoleA
1165 *
1166 * @implemented
1167 */
1168 BOOL STDCALL
1169 WriteConsoleA(HANDLE hConsoleOutput,
1170 CONST VOID *lpBuffer,
1171 DWORD nNumberOfCharsToWrite,
1172 LPDWORD lpNumberOfCharsWritten,
1173 LPVOID lpReserved)
1174 {
1175 return IntWriteConsole(hConsoleOutput,
1176 (PVOID)lpBuffer,
1177 nNumberOfCharsToWrite,
1178 lpNumberOfCharsWritten,
1179 lpReserved,
1180 FALSE);
1181 }
1182
1183
1184 /*--------------------------------------------------------------
1185 * WriteConsoleW
1186 *
1187 * @implemented
1188 */
1189 BOOL STDCALL
1190 WriteConsoleW(
1191 HANDLE hConsoleOutput,
1192 CONST VOID *lpBuffer,
1193 DWORD nNumberOfCharsToWrite,
1194 LPDWORD lpNumberOfCharsWritten,
1195 LPVOID lpReserved
1196 )
1197 {
1198 return IntWriteConsole(hConsoleOutput,
1199 (PVOID)lpBuffer,
1200 nNumberOfCharsToWrite,
1201 lpNumberOfCharsWritten,
1202 lpReserved,
1203 TRUE);
1204 }
1205
1206
1207 static BOOL
1208 IntReadConsole(HANDLE hConsoleInput,
1209 PVOID lpBuffer,
1210 DWORD nNumberOfCharsToRead,
1211 LPDWORD lpNumberOfCharsRead,
1212 LPVOID lpReserved,
1213 BOOL bUnicode)
1214 {
1215 PCSR_API_MESSAGE Request;
1216 ULONG CsrRequest;
1217 NTSTATUS Status;
1218 ULONG CharSize, CharsRead = 0;
1219
1220 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1221 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1222 max(sizeof(CSR_API_MESSAGE),
1223 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1224 + min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize) * CharSize));
1225 if (Request == NULL)
1226 {
1227 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1228 return FALSE;
1229 }
1230
1231 Request->Status = STATUS_SUCCESS;
1232 CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1233
1234 do
1235 {
1236 if(Request->Status == STATUS_PENDING)
1237 {
1238 Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle, FALSE, 0);
1239 if(!NT_SUCCESS(Status))
1240 {
1241 DPRINT1("Wait for console input failed!\n");
1242 break;
1243 }
1244 }
1245
1246 Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1247 Request->Data.ReadConsoleRequest.Unicode = bUnicode;
1248 Request->Data.ReadConsoleRequest.NrCharactersToRead = min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
1249 Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
1250 Status = CsrClientCallServer(Request,
1251 NULL,
1252 CsrRequest,
1253 max(sizeof(CSR_API_MESSAGE),
1254 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1255 + Request->Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
1256
1257 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1258 {
1259 DPRINT1("CSR returned error in ReadConsole\n");
1260 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1261 SetLastErrorByStatus(Status);
1262 return FALSE;
1263 }
1264
1265 nNumberOfCharsToRead -= Request->Data.ReadConsoleRequest.NrCharactersRead;
1266 memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
1267 Request->Data.ReadConsoleRequest.Buffer,
1268 Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1269 CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead;
1270
1271 if(Request->Status == STATUS_NOTIFY_CLEANUP)
1272 {
1273 if(CharsRead > 0)
1274 {
1275 CharsRead--;
1276 nNumberOfCharsToRead++;
1277 }
1278 Request->Status = STATUS_PENDING;
1279 }
1280 } while(Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
1281
1282 if(lpNumberOfCharsRead != NULL)
1283 {
1284 *lpNumberOfCharsRead = CharsRead;
1285 }
1286
1287 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1288
1289 return TRUE;
1290 }
1291
1292
1293 /*--------------------------------------------------------------
1294 * ReadConsoleA
1295 *
1296 * @implemented
1297 */
1298 BOOL STDCALL
1299 ReadConsoleA(HANDLE hConsoleInput,
1300 LPVOID lpBuffer,
1301 DWORD nNumberOfCharsToRead,
1302 LPDWORD lpNumberOfCharsRead,
1303 LPVOID lpReserved)
1304 {
1305 return IntReadConsole(hConsoleInput,
1306 lpBuffer,
1307 nNumberOfCharsToRead,
1308 lpNumberOfCharsRead,
1309 lpReserved,
1310 FALSE);
1311 }
1312
1313
1314 /*--------------------------------------------------------------
1315 * ReadConsoleW
1316 *
1317 * @implemented
1318 */
1319 BOOL STDCALL
1320 ReadConsoleW(HANDLE hConsoleInput,
1321 LPVOID lpBuffer,
1322 DWORD nNumberOfCharsToRead,
1323 LPDWORD lpNumberOfCharsRead,
1324 LPVOID lpReserved)
1325 {
1326 return IntReadConsole(hConsoleInput,
1327 lpBuffer,
1328 nNumberOfCharsToRead,
1329 lpNumberOfCharsRead,
1330 lpReserved,
1331 TRUE);
1332 }
1333
1334
1335 /*--------------------------------------------------------------
1336 * AllocConsole
1337 *
1338 * @implemented
1339 */
1340 BOOL STDCALL AllocConsole(VOID)
1341 {
1342 CSR_API_MESSAGE Request; ULONG CsrRequest;
1343
1344 NTSTATUS Status;
1345 HANDLE hStdError;
1346
1347 if(NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1348 {
1349 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1350 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1351 return FALSE;
1352 }
1353
1354 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1355 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1356
1357 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1358 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1359 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1360 {
1361 SetLastErrorByStatus ( Status );
1362 return FALSE;
1363 }
1364 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1365 SetStdHandle( STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle );
1366 SetStdHandle( STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle );
1367 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1368 0,
1369 TRUE,
1370 DUPLICATE_SAME_ACCESS);
1371 SetStdHandle( STD_ERROR_HANDLE, hStdError );
1372 return TRUE;
1373 }
1374
1375
1376 /*--------------------------------------------------------------
1377 * FreeConsole
1378 *
1379 * @implemented
1380 */
1381 BOOL STDCALL FreeConsole(VOID)
1382 {
1383 // AG: I'm not sure if this is correct (what happens to std handles?)
1384 // but I just tried to reverse what AllocConsole() does...
1385
1386 CSR_API_MESSAGE Request; ULONG CsrRequest;
1387
1388 NTSTATUS Status;
1389
1390 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1391 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1392 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1393 {
1394 SetLastErrorByStatus ( Status );
1395 return FALSE;
1396 }
1397
1398 return TRUE;
1399 }
1400
1401
1402 /*--------------------------------------------------------------
1403 * GetConsoleScreenBufferInfo
1404 *
1405 * @implemented
1406 */
1407 BOOL
1408 STDCALL
1409 GetConsoleScreenBufferInfo(
1410 HANDLE hConsoleOutput,
1411 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
1412 )
1413 {
1414 CSR_API_MESSAGE Request; ULONG CsrRequest;
1415
1416 NTSTATUS Status;
1417
1418 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1419 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1420 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1421 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1422 {
1423 SetLastErrorByStatus ( Status );
1424 return FALSE;
1425 }
1426 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1427 return TRUE;
1428 }
1429
1430
1431 /*--------------------------------------------------------------
1432 * SetConsoleCursorPosition
1433 *
1434 * @implemented
1435 */
1436 BOOL
1437 STDCALL
1438 SetConsoleCursorPosition(
1439 HANDLE hConsoleOutput,
1440 COORD dwCursorPosition
1441 )
1442 {
1443 CSR_API_MESSAGE Request; ULONG CsrRequest;
1444
1445 NTSTATUS Status;
1446
1447 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1448 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1449 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1450 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1451 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1452 {
1453 SetLastErrorByStatus ( Status );
1454 return FALSE;
1455 }
1456 return TRUE;
1457 }
1458
1459
1460 static BOOL
1461 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1462 PVOID cCharacter,
1463 DWORD nLength,
1464 COORD dwWriteCoord,
1465 LPDWORD lpNumberOfCharsWritten,
1466 BOOL bUnicode)
1467 {
1468 CSR_API_MESSAGE Request; ULONG CsrRequest;
1469
1470 NTSTATUS Status;
1471
1472 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1473 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1474 Request.Data.FillOutputRequest.Unicode = bUnicode;
1475 if(bUnicode)
1476 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1477 else
1478 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1479 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1480 Request.Data.FillOutputRequest.Length = nLength;
1481 Status = CsrClientCallServer(&Request, NULL,
1482 CsrRequest,
1483 sizeof(CSR_API_MESSAGE));
1484
1485 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1486 {
1487 SetLastErrorByStatus(Status);
1488 return FALSE;
1489 }
1490
1491 if(lpNumberOfCharsWritten != NULL)
1492 {
1493 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1494 }
1495
1496 return TRUE;
1497 }
1498
1499 /*--------------------------------------------------------------
1500 * FillConsoleOutputCharacterA
1501 *
1502 * @implemented
1503 */
1504 BOOL STDCALL
1505 FillConsoleOutputCharacterA(
1506 HANDLE hConsoleOutput,
1507 CHAR cCharacter,
1508 DWORD nLength,
1509 COORD dwWriteCoord,
1510 LPDWORD lpNumberOfCharsWritten
1511 )
1512 {
1513 return IntFillConsoleOutputCharacter(hConsoleOutput,
1514 &cCharacter,
1515 nLength,
1516 dwWriteCoord,
1517 lpNumberOfCharsWritten,
1518 FALSE);
1519 }
1520
1521
1522 /*--------------------------------------------------------------
1523 * FillConsoleOutputCharacterW
1524 *
1525 * @implemented
1526 */
1527 BOOL
1528 STDCALL
1529 FillConsoleOutputCharacterW(
1530 HANDLE hConsoleOutput,
1531 WCHAR cCharacter,
1532 DWORD nLength,
1533 COORD dwWriteCoord,
1534 LPDWORD lpNumberOfCharsWritten
1535 )
1536 {
1537 return IntFillConsoleOutputCharacter(hConsoleOutput,
1538 &cCharacter,
1539 nLength,
1540 dwWriteCoord,
1541 lpNumberOfCharsWritten,
1542 TRUE);
1543 }
1544
1545
1546 static BOOL
1547 IntPeekConsoleInput(HANDLE hConsoleInput,
1548 PINPUT_RECORD lpBuffer,
1549 DWORD nLength,
1550 LPDWORD lpNumberOfEventsRead,
1551 BOOL bUnicode)
1552 {
1553 CSR_API_MESSAGE Request; ULONG CsrRequest;
1554 PCSR_CAPTURE_BUFFER CaptureBuffer;
1555 NTSTATUS Status;
1556 ULONG Size;
1557
1558 if(lpBuffer == NULL)
1559 {
1560 SetLastError(ERROR_INVALID_PARAMETER);
1561 return FALSE;
1562 }
1563
1564 Size = nLength * sizeof(INPUT_RECORD);
1565
1566 /* Allocate a Capture Buffer */
1567 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
1568 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1569
1570 /* Allocate space in the Buffer */
1571 CsrCaptureMessageBuffer(CaptureBuffer,
1572 NULL,
1573 Size,
1574 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
1575
1576 /* Set up the data to send to the Console Server */
1577 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
1578 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1579 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
1580 Request.Data.PeekConsoleInputRequest.Length = nLength;
1581
1582 /* Call the server */
1583 Status = CsrClientCallServer(&Request,
1584 CaptureBuffer,
1585 CsrRequest,
1586 sizeof(CSR_API_MESSAGE));
1587 DPRINT("Server returned: %x\n", Request.Status);
1588
1589 /* Check for success*/
1590 if (NT_SUCCESS(Request.Status))
1591 {
1592 /* Return the number of events read */
1593 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
1594 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
1595
1596 /* Copy into the buffer */
1597 DPRINT("Copying to buffer\n");
1598 RtlCopyMemory(lpBuffer,
1599 Request.Data.PeekConsoleInputRequest.InputRecord,
1600 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
1601 }
1602 else
1603 {
1604 /* Error out */
1605 *lpNumberOfEventsRead = 0;
1606 SetLastErrorByStatus(Request.Status);
1607 }
1608
1609 /* Release the capture buffer */
1610 CsrFreeCaptureBuffer(CaptureBuffer);
1611
1612 /* Return TRUE or FALSE */
1613 return NT_SUCCESS(Request.Status);
1614 }
1615
1616 /*--------------------------------------------------------------
1617 * PeekConsoleInputA
1618 *
1619 * @implemented
1620 */
1621 BOOL
1622 WINAPI
1623 PeekConsoleInputA(
1624 HANDLE hConsoleInput,
1625 PINPUT_RECORD lpBuffer,
1626 DWORD nLength,
1627 LPDWORD lpNumberOfEventsRead
1628 )
1629 {
1630 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1631 lpNumberOfEventsRead, FALSE);
1632 }
1633
1634
1635 /*--------------------------------------------------------------
1636 * PeekConsoleInputW
1637 *
1638 * @implemented
1639 */
1640 BOOL
1641 WINAPI
1642 PeekConsoleInputW(
1643 HANDLE hConsoleInput,
1644 PINPUT_RECORD lpBuffer,
1645 DWORD nLength,
1646 LPDWORD lpNumberOfEventsRead
1647 )
1648 {
1649 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1650 lpNumberOfEventsRead, TRUE);
1651 }
1652
1653
1654 static BOOL
1655 IntReadConsoleInput(HANDLE hConsoleInput,
1656 PINPUT_RECORD lpBuffer,
1657 DWORD nLength,
1658 LPDWORD lpNumberOfEventsRead,
1659 BOOL bUnicode)
1660 {
1661 CSR_API_MESSAGE Request; ULONG CsrRequest;
1662
1663 ULONG Read;
1664 NTSTATUS Status;
1665
1666 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
1667 Read = 0;
1668 while(nLength > 0)
1669 {
1670 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1671 Request.Data.ReadInputRequest.Unicode = bUnicode;
1672 Status = CsrClientCallServer(&Request, NULL,
1673 CsrRequest,
1674 sizeof(CSR_API_MESSAGE));
1675 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1676 {
1677 if(Read == 0)
1678 {
1679 /* we couldn't read a single record, fail */
1680 SetLastErrorByStatus(Status);
1681 return FALSE;
1682 }
1683 else
1684 {
1685 /* FIXME - fail gracefully in case we already read at least one record? */
1686 break;
1687 }
1688 }
1689 else if(Status == STATUS_PENDING)
1690 {
1691 if(Read == 0)
1692 {
1693 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
1694 if(!NT_SUCCESS(Status))
1695 {
1696 SetLastErrorByStatus(Status);
1697 break;
1698 }
1699 }
1700 else
1701 {
1702 /* nothing more to read (waiting for more input??), let's just bail */
1703 break;
1704 }
1705 }
1706 else
1707 {
1708 lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
1709 nLength--;
1710
1711 if(!Request.Data.ReadInputRequest.MoreEvents)
1712 {
1713 /* nothing more to read, bail */
1714 break;
1715 }
1716 }
1717 }
1718
1719 if(lpNumberOfEventsRead != NULL)
1720 {
1721 *lpNumberOfEventsRead = Read;
1722 }
1723
1724 return (Read > 0);
1725 }
1726
1727
1728 /*--------------------------------------------------------------
1729 * ReadConsoleInputA
1730 *
1731 * @implemented
1732 */
1733 BOOL WINAPI
1734 ReadConsoleInputA(HANDLE hConsoleInput,
1735 PINPUT_RECORD lpBuffer,
1736 DWORD nLength,
1737 LPDWORD lpNumberOfEventsRead)
1738 {
1739 return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
1740 lpNumberOfEventsRead, FALSE);
1741 }
1742
1743
1744 /*--------------------------------------------------------------
1745 * ReadConsoleInputW
1746 *
1747 * @implemented
1748 */
1749 BOOL
1750 WINAPI
1751 ReadConsoleInputW(
1752 HANDLE hConsoleInput,
1753 PINPUT_RECORD lpBuffer,
1754 DWORD nLength,
1755 LPDWORD lpNumberOfEventsRead
1756 )
1757 {
1758 return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
1759 lpNumberOfEventsRead, TRUE);
1760 }
1761
1762
1763 static BOOL
1764 IntWriteConsoleInput(HANDLE hConsoleInput,
1765 PINPUT_RECORD lpBuffer,
1766 DWORD nLength,
1767 LPDWORD lpNumberOfEventsWritten,
1768 BOOL bUnicode)
1769 {
1770 CSR_API_MESSAGE Request; ULONG CsrRequest;
1771 PCSR_CAPTURE_BUFFER CaptureBuffer;
1772 NTSTATUS Status;
1773 DWORD Size;
1774
1775 if(lpBuffer == NULL)
1776 {
1777 SetLastError(ERROR_INVALID_PARAMETER);
1778 return FALSE;
1779 }
1780
1781 Size = nLength * sizeof(INPUT_RECORD);
1782
1783 /* Allocate a Capture Buffer */
1784 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
1785 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1786
1787 /* Allocate space in the Buffer */
1788 CsrCaptureMessageBuffer(CaptureBuffer,
1789 NULL,
1790 Size,
1791 (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
1792
1793 /* Set up the data to send to the Console Server */
1794 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
1795 Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
1796 Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
1797 Request.Data.WriteConsoleInputRequest.Length = nLength;
1798
1799 /* Call the server */
1800 Status = CsrClientCallServer(&Request,
1801 CaptureBuffer,
1802 CsrRequest,
1803 sizeof(CSR_API_MESSAGE));
1804 DPRINT("Server returned: %x\n", Request.Status);
1805
1806 /* Check for success*/
1807 if (NT_SUCCESS(Request.Status))
1808 {
1809 /* Return the number of events read */
1810 DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
1811 *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
1812
1813 /* Copy into the buffer */
1814 DPRINT("Copying to buffer\n");
1815 RtlCopyMemory(lpBuffer,
1816 Request.Data.WriteConsoleInputRequest.InputRecord,
1817 sizeof(INPUT_RECORD) * *lpNumberOfEventsWritten);
1818 }
1819 else
1820 {
1821 /* Error out */
1822 *lpNumberOfEventsWritten = 0;
1823 SetLastErrorByStatus(Request.Status);
1824 }
1825
1826 /* Release the capture buffer */
1827 CsrFreeCaptureBuffer(CaptureBuffer);
1828
1829 /* Return TRUE or FALSE */
1830 return NT_SUCCESS(Request.Status);
1831 }
1832
1833
1834 /*--------------------------------------------------------------
1835 * WriteConsoleInputA
1836 *
1837 * @implemented
1838 */
1839 BOOL
1840 WINAPI
1841 WriteConsoleInputA(
1842 HANDLE hConsoleInput,
1843 CONST INPUT_RECORD *lpBuffer,
1844 DWORD nLength,
1845 LPDWORD lpNumberOfEventsWritten
1846 )
1847 {
1848 return IntWriteConsoleInput(hConsoleInput,
1849 (PINPUT_RECORD)lpBuffer,
1850 nLength,
1851 lpNumberOfEventsWritten,
1852 FALSE);
1853 }
1854
1855
1856 /*--------------------------------------------------------------
1857 * WriteConsoleInputW
1858 *
1859 * @implemented
1860 */
1861 BOOL
1862 WINAPI
1863 WriteConsoleInputW(
1864 HANDLE hConsoleInput,
1865 CONST INPUT_RECORD *lpBuffer,
1866 DWORD nLength,
1867 LPDWORD lpNumberOfEventsWritten
1868 )
1869 {
1870 return IntWriteConsoleInput(hConsoleInput,
1871 (PINPUT_RECORD)lpBuffer,
1872 nLength,
1873 lpNumberOfEventsWritten,
1874 TRUE);
1875 }
1876
1877
1878 static BOOL
1879 IntReadConsoleOutput(HANDLE hConsoleOutput,
1880 PCHAR_INFO lpBuffer,
1881 COORD dwBufferSize,
1882 COORD dwBufferCoord,
1883 PSMALL_RECT lpReadRegion,
1884 BOOL bUnicode)
1885 {
1886 CSR_API_MESSAGE Request; ULONG CsrRequest;
1887 PCSR_CAPTURE_BUFFER CaptureBuffer;
1888 NTSTATUS Status;
1889 DWORD Size, SizeX, SizeY;
1890
1891 if(lpBuffer == NULL)
1892 {
1893 SetLastError(ERROR_INVALID_PARAMETER);
1894 return FALSE;
1895 }
1896
1897 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
1898
1899 /* Allocate a Capture Buffer */
1900 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
1901 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1902
1903 /* Allocate space in the Buffer */
1904 CsrCaptureMessageBuffer(CaptureBuffer,
1905 NULL,
1906 Size,
1907 (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
1908
1909 /* Set up the data to send to the Console Server */
1910 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
1911 Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1912 Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
1913 Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
1914 Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
1915 Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
1916
1917 /* Call the server */
1918 Status = CsrClientCallServer(&Request,
1919 CaptureBuffer,
1920 CsrRequest,
1921 sizeof(CSR_API_MESSAGE));
1922 DPRINT("Server returned: %x\n", Request.Status);
1923
1924 /* Check for success*/
1925 if (NT_SUCCESS(Request.Status))
1926 {
1927 /* Copy into the buffer */
1928 DPRINT("Copying to buffer\n");
1929 SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
1930 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
1931 SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
1932 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
1933 RtlCopyMemory(lpBuffer,
1934 Request.Data.ReadConsoleOutputRequest.CharInfo,
1935 sizeof(CHAR_INFO) * SizeX * SizeY);
1936 }
1937 else
1938 {
1939 /* Error out */
1940 SetLastErrorByStatus(Request.Status);
1941 }
1942
1943 /* Return the read region */
1944 DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
1945 *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
1946
1947 /* Release the capture buffer */
1948 CsrFreeCaptureBuffer(CaptureBuffer);
1949
1950 /* Return TRUE or FALSE */
1951 return NT_SUCCESS(Request.Status);
1952 }
1953
1954 /*--------------------------------------------------------------
1955 * ReadConsoleOutputA
1956 *
1957 * @implemented
1958 */
1959 BOOL
1960 WINAPI
1961 ReadConsoleOutputA(
1962 HANDLE hConsoleOutput,
1963 PCHAR_INFO lpBuffer,
1964 COORD dwBufferSize,
1965 COORD dwBufferCoord,
1966 PSMALL_RECT lpReadRegion
1967 )
1968 {
1969 return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1970 dwBufferCoord, lpReadRegion, FALSE);
1971 }
1972
1973
1974 /*--------------------------------------------------------------
1975 * ReadConsoleOutputW
1976 *
1977 * @implemented
1978 */
1979 BOOL
1980 WINAPI
1981 ReadConsoleOutputW(
1982 HANDLE hConsoleOutput,
1983 PCHAR_INFO lpBuffer,
1984 COORD dwBufferSize,
1985 COORD dwBufferCoord,
1986 PSMALL_RECT lpReadRegion
1987 )
1988 {
1989 return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1990 dwBufferCoord, lpReadRegion, TRUE);
1991 }
1992
1993
1994 static BOOL
1995 IntWriteConsoleOutput(HANDLE hConsoleOutput,
1996 CONST CHAR_INFO *lpBuffer,
1997 COORD dwBufferSize,
1998 COORD dwBufferCoord,
1999 PSMALL_RECT lpWriteRegion,
2000 BOOL bUnicode)
2001 {
2002 CSR_API_MESSAGE Request; ULONG CsrRequest;
2003 PCSR_CAPTURE_BUFFER CaptureBuffer;
2004 NTSTATUS Status;
2005 ULONG Size;
2006
2007 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
2008
2009 /* Allocate a Capture Buffer */
2010 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
2011 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2012
2013 /* Allocate space in the Buffer */
2014 CsrCaptureMessageBuffer(CaptureBuffer,
2015 NULL,
2016 Size,
2017 (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
2018
2019 /* Copy from the buffer */
2020 RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
2021
2022 /* Set up the data to send to the Console Server */
2023 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
2024 Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2025 Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
2026 Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
2027 Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
2028 Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
2029
2030 /* Call the server */
2031 Status = CsrClientCallServer(&Request,
2032 CaptureBuffer,
2033 CsrRequest,
2034 sizeof(CSR_API_MESSAGE));
2035 DPRINT("Server returned: %x\n", Request.Status);
2036
2037 /* Check for success*/
2038 if (!NT_SUCCESS(Request.Status))
2039 {
2040 /* Error out */
2041 SetLastErrorByStatus(Request.Status);
2042 }
2043
2044 /* Return the read region */
2045 DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
2046 *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
2047
2048 /* Release the capture buffer */
2049 CsrFreeCaptureBuffer(CaptureBuffer);
2050
2051 /* Return TRUE or FALSE */
2052 return NT_SUCCESS(Request.Status);
2053 }
2054
2055 /*--------------------------------------------------------------
2056 * WriteConsoleOutputA
2057 *
2058 * @implemented
2059 */
2060 BOOL WINAPI
2061 WriteConsoleOutputA(HANDLE hConsoleOutput,
2062 CONST CHAR_INFO *lpBuffer,
2063 COORD dwBufferSize,
2064 COORD dwBufferCoord,
2065 PSMALL_RECT lpWriteRegion)
2066 {
2067 return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
2068 dwBufferCoord, lpWriteRegion, FALSE);
2069 }
2070
2071
2072 /*--------------------------------------------------------------
2073 * WriteConsoleOutputW
2074 *
2075 * @implemented
2076 */
2077 BOOL
2078 WINAPI
2079 WriteConsoleOutputW(
2080 HANDLE hConsoleOutput,
2081 CONST CHAR_INFO *lpBuffer,
2082 COORD dwBufferSize,
2083 COORD dwBufferCoord,
2084 PSMALL_RECT lpWriteRegion
2085 )
2086 {
2087 return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
2088 dwBufferCoord, lpWriteRegion, TRUE);
2089 }
2090
2091
2092 static BOOL
2093 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
2094 PVOID lpCharacter,
2095 DWORD nLength,
2096 COORD dwReadCoord,
2097 LPDWORD lpNumberOfCharsRead,
2098 BOOL bUnicode)
2099 {
2100 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2101 NTSTATUS Status;
2102 ULONG nChars, SizeBytes, CharSize;
2103 DWORD CharsRead = 0;
2104
2105 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2106
2107 nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) / CharSize;
2108 SizeBytes = nChars * CharSize;
2109
2110 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2111 max(sizeof(CSR_API_MESSAGE),
2112 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)
2113 + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2114 if (Request == NULL)
2115 {
2116 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2117 return FALSE;
2118 }
2119
2120 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2121 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
2122
2123 while(nLength > 0)
2124 {
2125 DWORD BytesRead;
2126
2127 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2128 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
2129 Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
2130 SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
2131
2132 Status = CsrClientCallServer(Request,
2133 NULL,
2134 CsrRequest,
2135 max (sizeof(CSR_API_MESSAGE),
2136 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
2137 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2138 {
2139 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2140 SetLastErrorByStatus(Status);
2141 break;
2142 }
2143
2144 BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
2145 memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
2146 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
2147 CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2148 nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2149
2150 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
2151 }
2152
2153 if(lpNumberOfCharsRead != NULL)
2154 {
2155 *lpNumberOfCharsRead = CharsRead;
2156 }
2157
2158 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2159
2160 return TRUE;
2161 }
2162
2163
2164 /*--------------------------------------------------------------
2165 * ReadConsoleOutputCharacterA
2166 *
2167 * @implemented
2168 */
2169 BOOL
2170 WINAPI
2171 ReadConsoleOutputCharacterA(
2172 HANDLE hConsoleOutput,
2173 LPSTR lpCharacter,
2174 DWORD nLength,
2175 COORD dwReadCoord,
2176 LPDWORD lpNumberOfCharsRead
2177 )
2178 {
2179 return IntReadConsoleOutputCharacter(hConsoleOutput,
2180 (PVOID)lpCharacter,
2181 nLength,
2182 dwReadCoord,
2183 lpNumberOfCharsRead,
2184 FALSE);
2185 }
2186
2187
2188 /*--------------------------------------------------------------
2189 * ReadConsoleOutputCharacterW
2190 *
2191 * @implemented
2192 */
2193 BOOL
2194 WINAPI
2195 ReadConsoleOutputCharacterW(
2196 HANDLE hConsoleOutput,
2197 LPWSTR lpCharacter,
2198 DWORD nLength,
2199 COORD dwReadCoord,
2200 LPDWORD lpNumberOfCharsRead
2201 )
2202 {
2203 return IntReadConsoleOutputCharacter(hConsoleOutput,
2204 (PVOID)lpCharacter,
2205 nLength,
2206 dwReadCoord,
2207 lpNumberOfCharsRead,
2208 TRUE);
2209 }
2210
2211
2212 /*--------------------------------------------------------------
2213 * ReadConsoleOutputAttribute
2214 *
2215 * @implemented
2216 */
2217 BOOL
2218 WINAPI
2219 ReadConsoleOutputAttribute(
2220 HANDLE hConsoleOutput,
2221 LPWORD lpAttribute,
2222 DWORD nLength,
2223 COORD dwReadCoord,
2224 LPDWORD lpNumberOfAttrsRead
2225 )
2226 {
2227 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2228 NTSTATUS Status;
2229 DWORD Size;
2230
2231 if (lpNumberOfAttrsRead != NULL)
2232 *lpNumberOfAttrsRead = nLength;
2233
2234 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2235 max(sizeof(CSR_API_MESSAGE),
2236 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
2237 + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2238 if (Request == NULL)
2239 {
2240 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2241 return FALSE;
2242 }
2243
2244 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2245
2246 while (nLength != 0)
2247 {
2248 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2249 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2250
2251 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2252 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2253 else
2254 Size = nLength;
2255
2256 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2257
2258 Status = CsrClientCallServer(Request,
2259 NULL,
2260 CsrRequest,
2261 max (sizeof(CSR_API_MESSAGE),
2262 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2263 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2264 {
2265 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2266 SetLastErrorByStatus(Status);
2267 return(FALSE);
2268 }
2269
2270 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2271 lpAttribute += Size;
2272 nLength -= Size;
2273 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2274 }
2275
2276 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2277
2278 return(TRUE);
2279 }
2280
2281
2282 static BOOL
2283 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2284 PVOID lpCharacter,
2285 DWORD nLength,
2286 COORD dwWriteCoord,
2287 LPDWORD lpNumberOfCharsWritten,
2288 BOOL bUnicode)
2289 {
2290 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2291 NTSTATUS Status;
2292 ULONG SizeBytes, CharSize, nChars;
2293 DWORD Written = 0;
2294
2295 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2296
2297 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2298 SizeBytes = nChars * CharSize;
2299
2300 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2301 max (sizeof(CSR_API_MESSAGE),
2302 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2303 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2304 if (Request == NULL)
2305 {
2306 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2307 return FALSE;
2308 }
2309
2310 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2311 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2312
2313 while(nLength > 0)
2314 {
2315 DWORD BytesWrite;
2316
2317 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2318 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2319 Request->Data.WriteConsoleOutputCharRequest.Length = min(nLength, nChars);
2320 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2321
2322 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2323
2324 Status = CsrClientCallServer(Request,
2325 NULL,
2326 CsrRequest,
2327 max (sizeof(CSR_API_MESSAGE),
2328 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2329
2330 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2331 {
2332 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2333 SetLastErrorByStatus(Status);
2334 return FALSE;
2335 }
2336
2337 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2338 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2339 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2340
2341 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2342 }
2343
2344 if(lpNumberOfCharsWritten != NULL)
2345 {
2346 *lpNumberOfCharsWritten = Written;
2347 }
2348
2349 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2350
2351 return TRUE;
2352 }
2353
2354
2355 /*--------------------------------------------------------------
2356 * WriteConsoleOutputCharacterA
2357 *
2358 * @implemented
2359 */
2360 BOOL WINAPI
2361 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2362 LPCSTR lpCharacter,
2363 DWORD nLength,
2364 COORD dwWriteCoord,
2365 LPDWORD lpNumberOfCharsWritten)
2366 {
2367 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2368 (PVOID)lpCharacter,
2369 nLength,
2370 dwWriteCoord,
2371 lpNumberOfCharsWritten,
2372 FALSE);
2373 }
2374
2375
2376 /*--------------------------------------------------------------
2377 * WriteConsoleOutputCharacterW
2378 *
2379 * @implemented
2380 */
2381 BOOL WINAPI
2382 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2383 LPCWSTR lpCharacter,
2384 DWORD nLength,
2385 COORD dwWriteCoord,
2386 LPDWORD lpNumberOfCharsWritten)
2387 {
2388 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2389 (PVOID)lpCharacter,
2390 nLength,
2391 dwWriteCoord,
2392 lpNumberOfCharsWritten,
2393 TRUE);
2394 }
2395
2396
2397 /*--------------------------------------------------------------
2398 * WriteConsoleOutputAttribute
2399 *
2400 * @implemented
2401 */
2402 BOOL
2403 WINAPI
2404 WriteConsoleOutputAttribute(
2405 HANDLE hConsoleOutput,
2406 CONST WORD *lpAttribute,
2407 DWORD nLength,
2408 COORD dwWriteCoord,
2409 LPDWORD lpNumberOfAttrsWritten
2410 )
2411 {
2412 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2413 NTSTATUS Status;
2414 WORD Size;
2415
2416 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2417 max (sizeof(CSR_API_MESSAGE),
2418 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2419 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2420 if (Request == NULL)
2421 {
2422 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2423 return FALSE;
2424 }
2425
2426 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2427 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2428
2429 if( lpNumberOfAttrsWritten )
2430 *lpNumberOfAttrsWritten = nLength;
2431 while( nLength )
2432 {
2433 Size = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2434 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2435 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2436 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2437
2438 Status = CsrClientCallServer( Request,
2439 NULL,
2440 CsrRequest,
2441 max (sizeof(CSR_API_MESSAGE),
2442 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2443
2444 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request->Status ) )
2445 {
2446 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2447 SetLastErrorByStatus ( Status );
2448 return FALSE;
2449 }
2450 nLength -= Size;
2451 lpAttribute += Size;
2452 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2453 }
2454
2455 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2456
2457 return TRUE;
2458 }
2459
2460
2461 /*--------------------------------------------------------------
2462 * FillConsoleOutputAttribute
2463 *
2464 * @implemented
2465 */
2466 BOOL
2467 WINAPI
2468 FillConsoleOutputAttribute(
2469 HANDLE hConsoleOutput,
2470 WORD wAttribute,
2471 DWORD nLength,
2472 COORD dwWriteCoord,
2473 LPDWORD lpNumberOfAttrsWritten
2474 )
2475 {
2476 CSR_API_MESSAGE Request; ULONG CsrRequest;
2477
2478 NTSTATUS Status;
2479
2480 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2481 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2482 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
2483 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2484 Request.Data.FillOutputAttribRequest.Length = nLength;
2485 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2486 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2487 {
2488 SetLastErrorByStatus ( Status );
2489 return FALSE;
2490 }
2491 if( lpNumberOfAttrsWritten )
2492 *lpNumberOfAttrsWritten = nLength;
2493 return TRUE;
2494 }
2495
2496
2497 /*--------------------------------------------------------------
2498 * GetConsoleMode
2499 *
2500 * @implemented
2501 */
2502 BOOL
2503 WINAPI
2504 GetConsoleMode(
2505 HANDLE hConsoleHandle,
2506 LPDWORD lpMode
2507 )
2508 {
2509 CSR_API_MESSAGE Request; ULONG CsrRequest;
2510
2511 NTSTATUS Status;
2512
2513 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
2514 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2515 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2516 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2517 {
2518 SetLastErrorByStatus ( Status );
2519 return FALSE;
2520 }
2521 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
2522 return TRUE;
2523 }
2524
2525
2526 /*--------------------------------------------------------------
2527 * GetNumberOfConsoleInputEvents
2528 *
2529 * @implemented
2530 */
2531 BOOL
2532 WINAPI
2533 GetNumberOfConsoleInputEvents(
2534 HANDLE hConsoleInput,
2535 LPDWORD lpNumberOfEvents
2536 )
2537 {
2538 CSR_API_MESSAGE Request; ULONG CsrRequest;
2539
2540 NTSTATUS Status;
2541
2542 if(lpNumberOfEvents == NULL)
2543 {
2544 SetLastError(ERROR_INVALID_PARAMETER);
2545 return FALSE;
2546 }
2547
2548 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
2549 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2550 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2551 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2552 {
2553 SetLastErrorByStatus(Status);
2554 return FALSE;
2555 }
2556
2557 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
2558
2559 return TRUE;
2560 }
2561
2562
2563 /*--------------------------------------------------------------
2564 * GetLargestConsoleWindowSize
2565 *
2566 * @unimplemented
2567 */
2568 COORD
2569 WINAPI
2570 GetLargestConsoleWindowSize(
2571 HANDLE hConsoleOutput
2572 )
2573 {
2574 COORD Coord = {80,25};
2575 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
2576 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2577 return Coord;
2578 }
2579
2580
2581 /*--------------------------------------------------------------
2582 * GetConsoleCursorInfo
2583 *
2584 * @implemented
2585 */
2586 BOOL
2587 WINAPI
2588 GetConsoleCursorInfo(
2589 HANDLE hConsoleOutput,
2590 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
2591 )
2592 {
2593 CSR_API_MESSAGE Request; ULONG CsrRequest;
2594
2595 NTSTATUS Status;
2596
2597 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
2598 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2599 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2600
2601 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2602 {
2603 SetLastErrorByStatus ( Status );
2604 return FALSE;
2605 }
2606 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
2607 return TRUE;
2608 }
2609
2610
2611 /*--------------------------------------------------------------
2612 * GetNumberOfConsoleMouseButtons
2613 *
2614 * @unimplemented
2615 */
2616 BOOL
2617 WINAPI
2618 GetNumberOfConsoleMouseButtons(
2619 LPDWORD lpNumberOfMouseButtons
2620 )
2621 {
2622 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
2623 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2624 return FALSE;
2625 }
2626
2627
2628 /*--------------------------------------------------------------
2629 * SetConsoleMode
2630 *
2631 * @implemented
2632 */
2633 BOOL
2634 WINAPI
2635 SetConsoleMode(
2636 HANDLE hConsoleHandle,
2637 DWORD dwMode
2638 )
2639 {
2640 CSR_API_MESSAGE Request; ULONG CsrRequest;
2641
2642 NTSTATUS Status;
2643
2644 if (!IsConsoleHandle (hConsoleHandle))
2645 {
2646 DPRINT("SetConsoleMode was called with a non console handle\n");
2647 SetLastError (ERROR_INVALID_PARAMETER);
2648 return FALSE;
2649 }
2650
2651
2652 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
2653 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2654 Request.Data.SetConsoleModeRequest.Mode = dwMode;
2655 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2656 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2657 {
2658 SetLastErrorByStatus ( Status );
2659 return FALSE;
2660 }
2661 return TRUE;
2662 }
2663
2664
2665 /*--------------------------------------------------------------
2666 * SetConsoleActiveScreenBuffer
2667 *
2668 * @implemented
2669 */
2670 BOOL
2671 WINAPI
2672 SetConsoleActiveScreenBuffer(
2673 HANDLE hConsoleOutput
2674 )
2675 {
2676 CSR_API_MESSAGE Request; ULONG CsrRequest;
2677
2678 NTSTATUS Status;
2679
2680 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
2681 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
2682 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2683 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2684 {
2685 SetLastErrorByStatus ( Status );
2686 return FALSE;
2687 }
2688 return TRUE;
2689 }
2690
2691
2692 /*--------------------------------------------------------------
2693 * FlushConsoleInputBuffer
2694 *
2695 * @implemented
2696 */
2697 BOOL
2698 WINAPI
2699 FlushConsoleInputBuffer(
2700 HANDLE hConsoleInput
2701 )
2702 {
2703 CSR_API_MESSAGE Request; ULONG CsrRequest;
2704
2705 NTSTATUS Status;
2706
2707 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
2708 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
2709 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2710 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2711 {
2712 SetLastErrorByStatus ( Status );
2713 return FALSE;
2714 }
2715 return TRUE;
2716 }
2717
2718
2719 /*--------------------------------------------------------------
2720 * SetConsoleScreenBufferSize
2721 *
2722 * @unimplemented
2723 */
2724 BOOL
2725 WINAPI
2726 SetConsoleScreenBufferSize(
2727 HANDLE hConsoleOutput,
2728 COORD dwSize
2729 )
2730 {
2731 DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
2732 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2733 return FALSE;
2734 }
2735
2736 /*--------------------------------------------------------------
2737 * SetConsoleCursorInfo
2738 *
2739 * @implemented
2740 */
2741 BOOL
2742 WINAPI
2743 SetConsoleCursorInfo(
2744 HANDLE hConsoleOutput,
2745 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
2746 )
2747 {
2748 CSR_API_MESSAGE Request; ULONG CsrRequest;
2749
2750 NTSTATUS Status;
2751
2752 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
2753 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2754 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
2755 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2756
2757 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2758 {
2759 SetLastErrorByStatus ( Status );
2760 return FALSE;
2761 }
2762 return TRUE;
2763 }
2764
2765
2766 static BOOL
2767 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
2768 PSMALL_RECT lpScrollRectangle,
2769 PSMALL_RECT lpClipRectangle,
2770 COORD dwDestinationOrigin,
2771 PCHAR_INFO lpFill,
2772 BOOL bUnicode)
2773 {
2774 CSR_API_MESSAGE Request; ULONG CsrRequest;
2775
2776 NTSTATUS Status;
2777
2778 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
2779 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
2780 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
2781 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
2782
2783 if(lpClipRectangle != NULL)
2784 {
2785 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
2786 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
2787 }
2788 else
2789 {
2790 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
2791 }
2792
2793 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
2794 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
2795 Status = CsrClientCallServer(&Request, NULL,
2796 CsrRequest,
2797 sizeof(CSR_API_MESSAGE));
2798
2799 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2800 {
2801 SetLastErrorByStatus(Status);
2802 return FALSE;
2803 }
2804
2805 return TRUE;
2806 }
2807
2808
2809 /*--------------------------------------------------------------
2810 * ScrollConsoleScreenBufferA
2811 *
2812 * @implemented
2813 */
2814 BOOL
2815 WINAPI
2816 ScrollConsoleScreenBufferA(
2817 HANDLE hConsoleOutput,
2818 CONST SMALL_RECT *lpScrollRectangle,
2819 CONST SMALL_RECT *lpClipRectangle,
2820 COORD dwDestinationOrigin,
2821 CONST CHAR_INFO *lpFill
2822 )
2823 {
2824 return IntScrollConsoleScreenBuffer(hConsoleOutput,
2825 (PSMALL_RECT)lpScrollRectangle,
2826 (PSMALL_RECT)lpClipRectangle,
2827 dwDestinationOrigin,
2828 (PCHAR_INFO)lpFill,
2829 FALSE);
2830 }
2831
2832
2833 /*--------------------------------------------------------------
2834 * ScrollConsoleScreenBufferW
2835 *
2836 * @implemented
2837 */
2838 BOOL
2839 WINAPI
2840 ScrollConsoleScreenBufferW(
2841 HANDLE hConsoleOutput,
2842 CONST SMALL_RECT *lpScrollRectangle,
2843 CONST SMALL_RECT *lpClipRectangle,
2844 COORD dwDestinationOrigin,
2845 CONST CHAR_INFO *lpFill
2846 )
2847 {
2848 return IntScrollConsoleScreenBuffer(hConsoleOutput,
2849 (PSMALL_RECT)lpScrollRectangle,
2850 (PSMALL_RECT)lpClipRectangle,
2851 dwDestinationOrigin,
2852 (PCHAR_INFO)lpFill,
2853 TRUE);
2854 }
2855
2856
2857 /*--------------------------------------------------------------
2858 * SetConsoleWindowInfo
2859 *
2860 * @unimplemented
2861 */
2862 BOOL
2863 WINAPI
2864 SetConsoleWindowInfo(
2865 HANDLE hConsoleOutput,
2866 BOOL bAbsolute,
2867 CONST SMALL_RECT *lpConsoleWindow
2868 )
2869 {
2870 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
2871 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2872 return FALSE;
2873 }
2874
2875
2876 /*--------------------------------------------------------------
2877 * SetConsoleTextAttribute
2878 *
2879 * @implemented
2880 */
2881 BOOL
2882 WINAPI
2883 SetConsoleTextAttribute(
2884 HANDLE hConsoleOutput,
2885 WORD wAttributes
2886 )
2887 {
2888 CSR_API_MESSAGE Request; ULONG CsrRequest;
2889
2890 NTSTATUS Status;
2891
2892 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
2893 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2894 Request.Data.SetAttribRequest.Attrib = wAttributes;
2895 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2896 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2897 {
2898 SetLastErrorByStatus ( Status );
2899 return FALSE;
2900 }
2901 return TRUE;
2902 }
2903
2904
2905 static BOOL
2906 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2907 {
2908 if (HandlerRoutine == NULL)
2909 {
2910 IgnoreCtrlEvents = TRUE;
2911 return(TRUE);
2912 }
2913 else
2914 {
2915 NrCtrlHandlers++;
2916 if (CtrlHandlers == NULL)
2917 {
2918 CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
2919 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2920 }
2921 else
2922 {
2923 CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
2924 (PVOID)CtrlHandlers,
2925 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2926 }
2927 if (CtrlHandlers == NULL)
2928 {
2929 NrCtrlHandlers = 0;
2930 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2931 return(FALSE);
2932 }
2933 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2934 return(TRUE);
2935 }
2936 }
2937
2938
2939 static BOOL
2940 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2941 {
2942 ULONG i;
2943
2944 if (HandlerRoutine == NULL)
2945 {
2946 IgnoreCtrlEvents = FALSE;
2947 return(TRUE);
2948 }
2949 else
2950 {
2951 for (i = 0; i < NrCtrlHandlers; i++)
2952 {
2953 if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
2954 {
2955 NrCtrlHandlers--;
2956 memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
2957 (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
2958 CtrlHandlers =
2959 RtlReAllocateHeap(RtlGetProcessHeap(),
2960 HEAP_ZERO_MEMORY,
2961 (PVOID)CtrlHandlers,
2962 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2963 return(TRUE);
2964 }
2965 }
2966 }
2967 return(FALSE);
2968 }
2969
2970
2971 /*
2972 * @implemented
2973 */
2974 BOOL WINAPI
2975 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2976 BOOL Add)
2977 {
2978 BOOLEAN Ret;
2979
2980 RtlEnterCriticalSection(&DllLock);
2981 if (Add)
2982 {
2983 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2984 }
2985 else
2986 {
2987 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2988 }
2989 RtlLeaveCriticalSection(&DllLock);
2990 return(Ret);
2991 }
2992
2993
2994 /*--------------------------------------------------------------
2995 * GenerateConsoleCtrlEvent
2996 *
2997 * @unimplemented
2998 */
2999 BOOL WINAPI
3000 GenerateConsoleCtrlEvent(
3001 DWORD dwCtrlEvent,
3002 DWORD dwProcessGroupId
3003 )
3004 {
3005 DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
3006 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3007 return FALSE;
3008 }
3009
3010
3011 /*--------------------------------------------------------------
3012 * GetConsoleTitleW
3013 *
3014 * @implemented
3015 */
3016 DWORD
3017 WINAPI
3018 GetConsoleTitleW(
3019 LPWSTR lpConsoleTitle,
3020 DWORD nSize
3021 )
3022 {
3023 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3024 NTSTATUS Status;
3025 HANDLE hConsole;
3026
3027 hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3028 if (hConsole == INVALID_HANDLE_VALUE)
3029 {
3030 return 0;
3031 }
3032
3033 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3034 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3035 if (Request == NULL)
3036 {
3037 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3038 return FALSE;
3039 }
3040
3041 CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
3042 Request->Data.GetTitleRequest.ConsoleHandle = hConsole;
3043
3044 Status = CsrClientCallServer(Request,
3045 NULL,
3046 CsrRequest,
3047 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3048 CloseHandle(hConsole);
3049 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status)))
3050 {
3051 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3052 SetLastErrorByStatus(Status);
3053 return 0;
3054 }
3055
3056 if(nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length)
3057 {
3058 nSize--;
3059 }
3060 else
3061 {
3062 nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
3063 }
3064 memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR));
3065 lpConsoleTitle[nSize] = L'\0';
3066
3067 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3068
3069 return nSize;
3070 }
3071
3072
3073 /*--------------------------------------------------------------
3074 * GetConsoleTitleA
3075 *
3076 * 19990306 EA
3077 *
3078 * @implemented
3079 */
3080 DWORD
3081 WINAPI
3082 GetConsoleTitleA(
3083 LPSTR lpConsoleTitle,
3084 DWORD nSize
3085 )
3086 {
3087 WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1];
3088 DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1;
3089 DWORD nWritten;
3090
3091 if (!lpConsoleTitle || !nSize) return 0;
3092 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
3093 if (!nWideTitle) return 0;
3094
3095 if ( (nWritten = WideCharToMultiByte(
3096 CP_ACP, // ANSI code page
3097 0, // performance and mapping flags
3098 (LPWSTR) WideTitle, // address of wide-character string
3099 nWideTitle, // number of characters in string
3100 lpConsoleTitle, // address of buffer for new string
3101 nSize - 1, // size of buffer
3102 NULL, // FAST
3103 NULL // FAST
3104 )))
3105 {
3106 lpConsoleTitle[nWritten] = '\0';
3107 return nWritten;
3108 }
3109
3110 return 0;
3111 }
3112
3113
3114 /*--------------------------------------------------------------
3115 * SetConsoleTitleW
3116 *
3117 * @implemented
3118 */
3119 BOOL
3120 WINAPI
3121 SetConsoleTitleW(
3122 LPCWSTR lpConsoleTitle
3123 )
3124 {
3125 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3126 NTSTATUS Status;
3127 unsigned int c;
3128 HANDLE hConsole;
3129
3130 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3131 if (hConsole == INVALID_HANDLE_VALUE)
3132 {
3133 return FALSE;
3134 }
3135
3136 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3137 max (sizeof(CSR_API_MESSAGE),
3138 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3139 min (wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3140 if (Request == NULL)
3141 {
3142 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3143 return FALSE;
3144 }
3145
3146 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3147 Request->Data.SetTitleRequest.Console = hConsole;
3148
3149 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
3150 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3151 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3152 Status = CsrClientCallServer(Request,
3153 NULL,
3154 CsrRequest,
3155 max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3156 CloseHandle(hConsole);
3157 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
3158 {
3159 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3160 SetLastErrorByStatus (Status);
3161 return(FALSE);
3162 }
3163
3164 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3165
3166 return TRUE;
3167 }
3168
3169
3170 /*--------------------------------------------------------------
3171 * SetConsoleTitleA
3172 *
3173 * 19990204 EA Added
3174 *
3175 * @implemented
3176 */
3177 BOOL
3178 WINAPI
3179 SetConsoleTitleA(
3180 LPCSTR lpConsoleTitle
3181 )
3182 {
3183 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3184 NTSTATUS Status;
3185 unsigned int c;
3186 HANDLE hConsole;
3187
3188 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3189 if (hConsole == INVALID_HANDLE_VALUE)
3190 {
3191 return FALSE;
3192 }
3193
3194 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3195 max (sizeof(CSR_API_MESSAGE),
3196 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3197 min (strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3198 if (Request == NULL)
3199 {
3200 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3201 return FALSE;
3202 }
3203
3204 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3205 Request->Data.SetTitleRequest.Console = hConsole;
3206
3207 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
3208 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3209 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3210 Status = CsrClientCallServer(Request,
3211 NULL,
3212 CsrRequest,
3213 max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3214 CloseHandle(hConsole);
3215 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
3216 {
3217 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3218 SetLastErrorByStatus (Status);
3219 return(FALSE);
3220 }
3221
3222 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3223
3224 return TRUE;
3225 }
3226
3227
3228 /*--------------------------------------------------------------
3229 * CreateConsoleScreenBuffer
3230 *
3231 * @implemented
3232 */
3233 HANDLE
3234 WINAPI
3235 CreateConsoleScreenBuffer(
3236 DWORD dwDesiredAccess,
3237 DWORD dwShareMode,
3238 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3239 DWORD dwFlags,
3240 LPVOID lpScreenBufferData
3241 )
3242 {
3243 // FIXME: don't ignore access, share mode, and security
3244 CSR_API_MESSAGE Request; ULONG CsrRequest;
3245
3246 NTSTATUS Status;
3247
3248 CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
3249 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3250 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
3251 {
3252 SetLastErrorByStatus ( Status );
3253 return FALSE;
3254 }
3255 return Request.Data.CreateScreenBufferRequest.OutputHandle;
3256 }
3257
3258
3259 /*--------------------------------------------------------------
3260 * GetConsoleCP
3261 *
3262 * @implemented
3263 */
3264 UINT
3265 WINAPI
3266 GetConsoleCP( VOID )
3267 {
3268 CSR_API_MESSAGE Request; ULONG CsrRequest;
3269
3270 NTSTATUS Status;
3271
3272 CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
3273 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3274 sizeof(CSR_API_MESSAGE));
3275 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3276 {
3277 SetLastErrorByStatus (Status);
3278 return 0;
3279 }
3280 return Request.Data.GetConsoleCodePage.CodePage;
3281 }
3282
3283
3284 /*--------------------------------------------------------------
3285 * SetConsoleCP
3286 *
3287 * @implemented
3288 */
3289 BOOL
3290 WINAPI
3291 SetConsoleCP(
3292 UINT wCodePageID
3293 )
3294 {
3295 CSR_API_MESSAGE Request; ULONG CsrRequest;
3296
3297 NTSTATUS Status;
3298
3299 CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
3300 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3301 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3302 sizeof(CSR_API_MESSAGE));
3303 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3304 {
3305 SetLastErrorByStatus (Status);
3306 }
3307 return NT_SUCCESS(Status);
3308 }
3309
3310
3311 /*--------------------------------------------------------------
3312 * GetConsoleOutputCP
3313 *
3314 * @implemented
3315 */
3316 UINT
3317 WINAPI
3318 GetConsoleOutputCP( VOID )
3319 {
3320 CSR_API_MESSAGE Request; ULONG CsrRequest;
3321
3322 NTSTATUS Status;
3323
3324 CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3325 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3326 sizeof(CSR_API_MESSAGE));
3327 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3328 {
3329 SetLastErrorByStatus (Status);
3330 return 0;
3331 }
3332 return Request.Data.GetConsoleOutputCodePage.CodePage;
3333 }
3334
3335
3336 /*--------------------------------------------------------------
3337 * SetConsoleOutputCP
3338 *
3339 * @implemented
3340 */
3341 BOOL
3342 WINAPI
3343 SetConsoleOutputCP(
3344 UINT wCodePageID
3345 )
3346 {
3347 CSR_API_MESSAGE Request; ULONG CsrRequest;
3348
3349 NTSTATUS Status;
3350
3351 CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3352 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3353 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3354 sizeof(CSR_API_MESSAGE));
3355 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3356 {
3357 SetLastErrorByStatus (Status);
3358 }
3359 return NT_SUCCESS(Status);
3360 }
3361
3362
3363 /*--------------------------------------------------------------
3364 * GetConsoleProcessList
3365 *
3366 * @implemented
3367 */
3368 DWORD STDCALL
3369 GetConsoleProcessList(LPDWORD lpdwProcessList,
3370 DWORD dwProcessCount)
3371 {
3372 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3373 ULONG nProcesses;
3374 NTSTATUS Status;
3375
3376 if(lpdwProcessList == NULL || dwProcessCount == 0)
3377 {
3378 SetLastError(ERROR_INVALID_PARAMETER);
3379 return 0;
3380 }
3381
3382 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3383 max (sizeof(CSR_API_MESSAGE),
3384 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3385 + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
3386 if (Request == NULL)
3387 {
3388 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3389 return FALSE;
3390 }
3391
3392 CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
3393 Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
3394
3395 Status = CsrClientCallServer(Request,
3396 NULL,
3397 CsrRequest,
3398 max (sizeof(CSR_API_MESSAGE),
3399 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3400 + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
3401 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3402 {
3403 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3404 SetLastErrorByStatus (Status);
3405 nProcesses = 0;
3406 }
3407 else
3408 {
3409 nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
3410 if(dwProcessCount >= nProcesses)
3411 {
3412 memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
3413 }
3414 }
3415
3416 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3417
3418 return nProcesses;
3419 }
3420
3421
3422
3423 /*--------------------------------------------------------------
3424 * GetConsoleSelectionInfo
3425 *
3426 * @unimplemented
3427 */
3428 BOOL STDCALL
3429 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3430 {
3431 DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
3432 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3433 return FALSE;
3434 }
3435
3436
3437
3438 /*--------------------------------------------------------------
3439 * AttachConsole
3440 *
3441 * @unimplemented
3442 */
3443 BOOL STDCALL
3444 AttachConsole(DWORD dwProcessId)
3445 {
3446 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
3447 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3448 return FALSE;
3449 }
3450
3451 /*--------------------------------------------------------------
3452 * GetConsoleWindow
3453 *
3454 * @implemented
3455 */
3456 HWND STDCALL
3457 GetConsoleWindow (VOID)
3458 {
3459 CSR_API_MESSAGE Request; ULONG CsrRequest;
3460
3461 NTSTATUS Status;
3462
3463 CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
3464 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3465 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
3466 {
3467 SetLastErrorByStatus (Status);
3468 return (HWND) NULL;
3469 }
3470 return Request.Data.GetConsoleWindowRequest.WindowHandle;
3471 }
3472
3473
3474 /*--------------------------------------------------------------
3475 * SetConsoleIcon
3476 *
3477 * @implemented
3478 */
3479 BOOL STDCALL SetConsoleIcon(HICON hicon)
3480 {
3481 CSR_API_MESSAGE Request; ULONG CsrRequest;
3482
3483 NTSTATUS Status;
3484
3485 CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
3486 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3487 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3488 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3489 {
3490 SetLastErrorByStatus (Status);
3491 return FALSE;
3492 }
3493 return NT_SUCCESS(Status);
3494 }
3495
3496
3497 /*--------------------------------------------------------------
3498 * SetConsoleInputExeNameW
3499 *
3500 * @implemented
3501 */
3502 BOOL STDCALL
3503 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
3504 {
3505 BOOL Ret = FALSE;
3506 int lenName = lstrlenW(lpInputExeName);
3507
3508 if(lenName < 1 ||
3509 lenName > (int)(sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
3510 {
3511 /* Fail if string is empty or too long */
3512 SetLastError(ERROR_INVALID_PARAMETER);
3513 return FALSE;
3514 }
3515
3516 RtlEnterCriticalSection(&ConsoleLock);
3517 /* wrap copying into SEH as we may copy from invalid buffer and in case of an
3518 exception the console lock would've never been released, which would cause
3519 further calls (if the exception was handled by the caller) to recursively
3520 acquire the lock... */
3521 _SEH_TRY
3522 {
3523 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
3524 InputExeName[lenName] = L'\0';
3525 Ret = TRUE;
3526 }
3527 _SEH_HANDLE
3528 {
3529 lenName = 0;
3530 SetLastErrorByStatus(_SEH_GetExceptionCode());
3531 }
3532 _SEH_END;
3533 RtlLeaveCriticalSection(&ConsoleLock);
3534
3535 return Ret;
3536 }
3537
3538
3539 /*--------------------------------------------------------------
3540 * SetConsoleInputExeNameA
3541 *
3542 * @implemented
3543 */
3544 BOOL STDCALL
3545 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
3546 {
3547 ANSI_STRING InputExeNameA;
3548 UNICODE_STRING InputExeNameU;
3549 NTSTATUS Status;
3550 BOOL Ret;
3551
3552 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
3553
3554 if(InputExeNameA.Length < sizeof(InputExeNameA.Buffer[0]) ||
3555 InputExeNameA.Length >= (sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
3556 {
3557 /* Fail if string is empty or too long */
3558 SetLastError(ERROR_INVALID_PARAMETER);
3559 return FALSE;
3560 }
3561
3562 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, TRUE);
3563 if(NT_SUCCESS(Status))
3564 {
3565 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
3566 RtlFreeUnicodeString(&InputExeNameU);
3567 }
3568 else
3569 {
3570 SetLastErrorByStatus(Status);
3571 Ret = FALSE;
3572 }
3573
3574 return Ret;
3575 }
3576
3577
3578 /*--------------------------------------------------------------
3579 * GetConsoleInputExeNameW
3580 *
3581 * @implemented
3582 */
3583 DWORD STDCALL
3584 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
3585 {
3586 int lenName;
3587
3588 RtlEnterCriticalSection(&ConsoleLock);
3589
3590 lenName = lstrlenW(InputExeName);
3591 if(lenName >= (int)nBufferLength)
3592 {
3593 /* buffer is not large enough, return the required size */
3594 RtlLeaveCriticalSection(&ConsoleLock);
3595 return lenName + 1;
3596 }
3597
3598 /* wrap copying into SEH as we may copy to invalid buffer and in case of an
3599 exception the console lock would've never been released, which would cause
3600 further calls (if the exception was handled by the caller) to recursively
3601 acquire the lock... */
3602 _SEH_TRY
3603 {
3604 RtlCopyMemory(lpBuffer, InputExeName, (lenName + 1) * sizeof(WCHAR));
3605 }
3606 _SEH_HANDLE
3607 {
3608 lenName = 0;
3609 SetLastErrorByStatus(_SEH_GetExceptionCode());
3610 }
3611 _SEH_END;
3612
3613 RtlLeaveCriticalSection(&ConsoleLock);
3614
3615 return lenName;
3616 }
3617
3618
3619 /*--------------------------------------------------------------
3620 * GetConsoleInputExeNameA
3621 *
3622 * @implemented
3623 */
3624 DWORD STDCALL
3625 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
3626 {
3627 WCHAR *Buffer;
3628 DWORD Ret;
3629
3630 if(nBufferLength > 0)
3631 {
3632 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
3633 if(Buffer == NULL)
3634 {
3635 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3636 return 0;
3637 }
3638 }
3639 else
3640 {
3641 Buffer = NULL;
3642 }
3643
3644 Ret = GetConsoleInputExeNameW(nBufferLength, Buffer);
3645 if(nBufferLength > 0)
3646 {
3647 if(Ret > 0)
3648 {
3649 UNICODE_STRING BufferU;
3650 ANSI_STRING BufferA;
3651
3652 RtlInitUnicodeString(&BufferU, Buffer);
3653
3654 BufferA.Length = 0;
3655 BufferA.MaximumLength = nBufferLength;
3656 BufferA.Buffer = lpBuffer;
3657
3658 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
3659 }
3660
3661 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
3662 }
3663
3664 return Ret;
3665 }
3666
3667
3668 /*--------------------------------------------------------------
3669 * GetConsoleHistoryInfo
3670 *
3671 * @unimplemented
3672 */
3673 BOOL STDCALL
3674 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
3675 {
3676 DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
3677 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3678 return FALSE;
3679 }
3680
3681
3682 /*--------------------------------------------------------------
3683 * SetConsoleHistoryInfo
3684 *
3685 * @unimplemented
3686 */
3687 BOOL STDCALL
3688 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
3689 {
3690 DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
3691 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3692 return FALSE;
3693 }
3694
3695
3696 /*--------------------------------------------------------------
3697 * GetConsoleOriginalTitleW
3698 *
3699 * @unimplemented
3700 */
3701 DWORD STDCALL
3702 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
3703 IN DWORD nSize)
3704 {
3705 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
3706 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3707 return 0;
3708 }
3709
3710
3711 /*--------------------------------------------------------------
3712 * GetConsoleOriginalTitleA
3713 *
3714 * @unimplemented
3715 */
3716 DWORD STDCALL
3717 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
3718 IN DWORD nSize)
3719 {
3720 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
3721 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3722 return 0;
3723 }
3724
3725
3726 /*--------------------------------------------------------------
3727 * GetConsoleScreenBufferInfoEx
3728 *
3729 * @unimplemented
3730 */
3731 BOOL STDCALL
3732 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
3733 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
3734 {
3735 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
3736 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3737 return FALSE;
3738 }
3739
3740
3741 /*--------------------------------------------------------------
3742 * SetConsoleScreenBufferInfoEx
3743 *
3744 * @unimplemented
3745 */
3746 BOOL STDCALL
3747 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
3748 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
3749 {
3750 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
3751 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3752 return FALSE;
3753 }
3754
3755
3756 /*--------------------------------------------------------------
3757 * GetCurrentConsoleFontEx
3758 *
3759 * @unimplemented
3760 */
3761 BOOL STDCALL
3762 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
3763 IN BOOL bMaximumWindow,
3764 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
3765 {
3766 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
3767 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3768 return FALSE;
3769 }
3770
3771 /* EOF */