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