- Turns out MSVC wasn't compiling one file because it had the same name as another...
[reactos.git] / reactos / dll / win32 / kernel32 / misc / console.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/console.c
6 * PURPOSE: Win32 server console functions
7 * PROGRAMMER: James Tabor
8 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
9 * UPDATE HISTORY:
10 * 199901?? ?? Created
11 * 19990204 EA SetConsoleTitleA
12 * 19990306 EA Stubs
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 #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 (LPWSTR AliasBuffer,
357 DWORD AliasBufferLength,
358 LPWSTR ExeName)
359 /*
360 * Undocumented
361 */
362 {
363 DPRINT1("GetConsoleAliasesW(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", AliasBuffer, AliasBufferLength, ExeName);
364 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
365 return 0;
366 }
367
368
369 /*
370 * @unimplemented
371 */
372 DWORD STDCALL
373 GetConsoleAliasesA (LPSTR AliasBuffer,
374 DWORD AliasBufferLength,
375 LPSTR ExeName)
376 /*
377 * Undocumented
378 */
379 {
380 DPRINT1("GetConsoleAliasesA(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", AliasBuffer, AliasBufferLength, ExeName);
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 INT 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 HANDLE 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 Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
585 }
586
587
588 /*
589 * @unimplemented
590 */
591 INT 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 PCOORD 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%p) 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
1120 while(nNumberOfCharsToWrite > 0)
1121 {
1122 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1123 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1124
1125 nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1126 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1127
1128 SizeBytes = nChars * CharSize;
1129
1130 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1131
1132 Status = CsrClientCallServer(Request,
1133 NULL,
1134 CsrRequest,
1135 max(sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1136
1137 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1138 {
1139 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1140 SetLastErrorByStatus(Status);
1141 return FALSE;
1142 }
1143
1144 nNumberOfCharsToWrite -= nChars;
1145 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1146 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1147 }
1148
1149 if(lpNumberOfCharsWritten != NULL)
1150 {
1151 *lpNumberOfCharsWritten = Written;
1152 }
1153 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1154
1155 return TRUE;
1156 }
1157
1158
1159 /*--------------------------------------------------------------
1160 * WriteConsoleA
1161 *
1162 * @implemented
1163 */
1164 BOOL STDCALL
1165 WriteConsoleA(HANDLE hConsoleOutput,
1166 CONST VOID *lpBuffer,
1167 DWORD nNumberOfCharsToWrite,
1168 LPDWORD lpNumberOfCharsWritten,
1169 LPVOID lpReserved)
1170 {
1171 return IntWriteConsole(hConsoleOutput,
1172 (PVOID)lpBuffer,
1173 nNumberOfCharsToWrite,
1174 lpNumberOfCharsWritten,
1175 lpReserved,
1176 FALSE);
1177 }
1178
1179
1180 /*--------------------------------------------------------------
1181 * WriteConsoleW
1182 *
1183 * @implemented
1184 */
1185 BOOL STDCALL
1186 WriteConsoleW(
1187 HANDLE hConsoleOutput,
1188 CONST VOID *lpBuffer,
1189 DWORD nNumberOfCharsToWrite,
1190 LPDWORD lpNumberOfCharsWritten,
1191 LPVOID lpReserved
1192 )
1193 {
1194 return IntWriteConsole(hConsoleOutput,
1195 (PVOID)lpBuffer,
1196 nNumberOfCharsToWrite,
1197 lpNumberOfCharsWritten,
1198 lpReserved,
1199 TRUE);
1200 }
1201
1202
1203 static BOOL
1204 IntReadConsole(HANDLE hConsoleInput,
1205 PVOID lpBuffer,
1206 DWORD nNumberOfCharsToRead,
1207 LPDWORD lpNumberOfCharsRead,
1208 PCONSOLE_READCONSOLE_CONTROL lpReserved,
1209 BOOL bUnicode)
1210 {
1211 PCSR_API_MESSAGE Request;
1212 ULONG CsrRequest;
1213 NTSTATUS Status;
1214 ULONG CharSize, CharsRead = 0;
1215
1216 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1217 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
1218 max(sizeof(CSR_API_MESSAGE),
1219 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1220 + min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize) * CharSize));
1221 if (Request == NULL)
1222 {
1223 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1224 return FALSE;
1225 }
1226
1227 Request->Status = STATUS_SUCCESS;
1228 CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1229
1230 do
1231 {
1232 if(Request->Status == STATUS_PENDING)
1233 {
1234 Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle, FALSE, 0);
1235 if(!NT_SUCCESS(Status))
1236 {
1237 DPRINT1("Wait for console input failed!\n");
1238 break;
1239 }
1240 }
1241
1242 Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1243 Request->Data.ReadConsoleRequest.Unicode = bUnicode;
1244 Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
1245 Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead;
1246 Status = CsrClientCallServer(Request,
1247 NULL,
1248 CsrRequest,
1249 max(sizeof(CSR_API_MESSAGE),
1250 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1251 + Request->Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
1252
1253 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1254 {
1255 DPRINT1("CSR returned error in ReadConsole\n");
1256 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1257 SetLastErrorByStatus(Status);
1258 return FALSE;
1259 }
1260
1261 nNumberOfCharsToRead -= Request->Data.ReadConsoleRequest.NrCharactersRead;
1262 memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
1263 Request->Data.ReadConsoleRequest.Buffer,
1264 Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1265 CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead;
1266
1267 if(Request->Status == STATUS_NOTIFY_CLEANUP)
1268 {
1269 if(CharsRead > 0)
1270 {
1271 CharsRead--;
1272 nNumberOfCharsToRead++;
1273 }
1274 Request->Status = STATUS_PENDING;
1275 }
1276 } while(Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
1277
1278 if(lpNumberOfCharsRead != NULL)
1279 {
1280 *lpNumberOfCharsRead = CharsRead;
1281 }
1282
1283 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1284
1285 return TRUE;
1286 }
1287
1288
1289 /*--------------------------------------------------------------
1290 * ReadConsoleA
1291 *
1292 * @implemented
1293 */
1294 BOOL STDCALL
1295 ReadConsoleA(HANDLE hConsoleInput,
1296 LPVOID lpBuffer,
1297 DWORD nNumberOfCharsToRead,
1298 LPDWORD lpNumberOfCharsRead,
1299 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1300 {
1301 return IntReadConsole(hConsoleInput,
1302 lpBuffer,
1303 nNumberOfCharsToRead,
1304 lpNumberOfCharsRead,
1305 pInputControl,
1306 FALSE);
1307 }
1308
1309
1310 /*--------------------------------------------------------------
1311 * ReadConsoleW
1312 *
1313 * @implemented
1314 */
1315 BOOL STDCALL
1316 ReadConsoleW(HANDLE hConsoleInput,
1317 LPVOID lpBuffer,
1318 DWORD nNumberOfCharsToRead,
1319 LPDWORD lpNumberOfCharsRead,
1320 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1321 {
1322 return IntReadConsole(hConsoleInput,
1323 lpBuffer,
1324 nNumberOfCharsToRead,
1325 lpNumberOfCharsRead,
1326 pInputControl,
1327 TRUE);
1328 }
1329
1330
1331 /*--------------------------------------------------------------
1332 * AllocConsole
1333 *
1334 * @implemented
1335 */
1336 BOOL STDCALL AllocConsole(VOID)
1337 {
1338 CSR_API_MESSAGE Request; ULONG CsrRequest;
1339
1340 NTSTATUS Status;
1341 HANDLE hStdError;
1342
1343 if(NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1344 {
1345 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1346 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1347 return FALSE;
1348 }
1349
1350 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1351 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1352
1353 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1354 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1355 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1356 {
1357 SetLastErrorByStatus ( Status );
1358 return FALSE;
1359 }
1360 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1361 SetStdHandle( STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle );
1362 SetStdHandle( STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle );
1363 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1364 0,
1365 TRUE,
1366 DUPLICATE_SAME_ACCESS);
1367 SetStdHandle( STD_ERROR_HANDLE, hStdError );
1368 return TRUE;
1369 }
1370
1371
1372 /*--------------------------------------------------------------
1373 * FreeConsole
1374 *
1375 * @implemented
1376 */
1377 BOOL STDCALL FreeConsole(VOID)
1378 {
1379 // AG: I'm not sure if this is correct (what happens to std handles?)
1380 // but I just tried to reverse what AllocConsole() does...
1381
1382 CSR_API_MESSAGE Request; ULONG CsrRequest;
1383
1384 NTSTATUS Status;
1385
1386 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1387 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1388 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1389 {
1390 SetLastErrorByStatus ( Status );
1391 return FALSE;
1392 }
1393
1394 return TRUE;
1395 }
1396
1397
1398 /*--------------------------------------------------------------
1399 * GetConsoleScreenBufferInfo
1400 *
1401 * @implemented
1402 */
1403 BOOL
1404 STDCALL
1405 GetConsoleScreenBufferInfo(
1406 HANDLE hConsoleOutput,
1407 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
1408 )
1409 {
1410 CSR_API_MESSAGE Request; ULONG CsrRequest;
1411
1412 NTSTATUS Status;
1413
1414 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1415 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1416 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1417 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1418 {
1419 SetLastErrorByStatus ( Status );
1420 return FALSE;
1421 }
1422 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1423 return TRUE;
1424 }
1425
1426
1427 /*--------------------------------------------------------------
1428 * SetConsoleCursorPosition
1429 *
1430 * @implemented
1431 */
1432 BOOL
1433 STDCALL
1434 SetConsoleCursorPosition(
1435 HANDLE hConsoleOutput,
1436 COORD dwCursorPosition
1437 )
1438 {
1439 CSR_API_MESSAGE Request; ULONG CsrRequest;
1440
1441 NTSTATUS Status;
1442
1443 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1444 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1445 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1446 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
1447 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
1448 {
1449 SetLastErrorByStatus ( Status );
1450 return FALSE;
1451 }
1452 return TRUE;
1453 }
1454
1455
1456 static BOOL
1457 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1458 PVOID cCharacter,
1459 DWORD nLength,
1460 COORD dwWriteCoord,
1461 LPDWORD lpNumberOfCharsWritten,
1462 BOOL bUnicode)
1463 {
1464 CSR_API_MESSAGE Request; ULONG CsrRequest;
1465
1466 NTSTATUS Status;
1467
1468 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1469 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1470 Request.Data.FillOutputRequest.Unicode = bUnicode;
1471 if(bUnicode)
1472 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1473 else
1474 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1475 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1476 Request.Data.FillOutputRequest.Length = (WORD)nLength;
1477 Status = CsrClientCallServer(&Request, NULL,
1478 CsrRequest,
1479 sizeof(CSR_API_MESSAGE));
1480
1481 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1482 {
1483 SetLastErrorByStatus(Status);
1484 return FALSE;
1485 }
1486
1487 if(lpNumberOfCharsWritten != NULL)
1488 {
1489 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1490 }
1491
1492 return TRUE;
1493 }
1494
1495 /*--------------------------------------------------------------
1496 * FillConsoleOutputCharacterA
1497 *
1498 * @implemented
1499 */
1500 BOOL STDCALL
1501 FillConsoleOutputCharacterA(
1502 HANDLE hConsoleOutput,
1503 CHAR cCharacter,
1504 DWORD nLength,
1505 COORD dwWriteCoord,
1506 LPDWORD lpNumberOfCharsWritten
1507 )
1508 {
1509 return IntFillConsoleOutputCharacter(hConsoleOutput,
1510 &cCharacter,
1511 nLength,
1512 dwWriteCoord,
1513 lpNumberOfCharsWritten,
1514 FALSE);
1515 }
1516
1517
1518 /*--------------------------------------------------------------
1519 * FillConsoleOutputCharacterW
1520 *
1521 * @implemented
1522 */
1523 BOOL
1524 STDCALL
1525 FillConsoleOutputCharacterW(
1526 HANDLE hConsoleOutput,
1527 WCHAR cCharacter,
1528 DWORD nLength,
1529 COORD dwWriteCoord,
1530 LPDWORD lpNumberOfCharsWritten
1531 )
1532 {
1533 return IntFillConsoleOutputCharacter(hConsoleOutput,
1534 &cCharacter,
1535 nLength,
1536 dwWriteCoord,
1537 lpNumberOfCharsWritten,
1538 TRUE);
1539 }
1540
1541
1542 static BOOL
1543 IntPeekConsoleInput(HANDLE hConsoleInput,
1544 PINPUT_RECORD lpBuffer,
1545 DWORD nLength,
1546 LPDWORD lpNumberOfEventsRead,
1547 BOOL bUnicode)
1548 {
1549 CSR_API_MESSAGE Request; ULONG CsrRequest;
1550 PCSR_CAPTURE_BUFFER CaptureBuffer;
1551 NTSTATUS Status;
1552 ULONG Size;
1553
1554 if(lpBuffer == NULL)
1555 {
1556 SetLastError(ERROR_INVALID_PARAMETER);
1557 return FALSE;
1558 }
1559
1560 Size = nLength * sizeof(INPUT_RECORD);
1561
1562 /* Allocate a Capture Buffer */
1563 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
1564 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1565
1566 /* Allocate space in the Buffer */
1567 CsrCaptureMessageBuffer(CaptureBuffer,
1568 NULL,
1569 Size,
1570 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
1571
1572 /* Set up the data to send to the Console Server */
1573 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
1574 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1575 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
1576 Request.Data.PeekConsoleInputRequest.Length = nLength;
1577
1578 /* Call the server */
1579 Status = CsrClientCallServer(&Request,
1580 CaptureBuffer,
1581 CsrRequest,
1582 sizeof(CSR_API_MESSAGE));
1583 DPRINT("Server returned: %x\n", Request.Status);
1584
1585 /* Check for success*/
1586 if (NT_SUCCESS(Request.Status))
1587 {
1588 /* Return the number of events read */
1589 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
1590 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
1591
1592 /* Copy into the buffer */
1593 DPRINT("Copying to buffer\n");
1594 RtlCopyMemory(lpBuffer,
1595 Request.Data.PeekConsoleInputRequest.InputRecord,
1596 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
1597 }
1598 else
1599 {
1600 /* Error out */
1601 *lpNumberOfEventsRead = 0;
1602 SetLastErrorByStatus(Request.Status);
1603 }
1604
1605 /* Release the capture buffer */
1606 CsrFreeCaptureBuffer(CaptureBuffer);
1607
1608 /* Return TRUE or FALSE */
1609 return NT_SUCCESS(Request.Status);
1610 }
1611
1612 /*--------------------------------------------------------------
1613 * PeekConsoleInputA
1614 *
1615 * @implemented
1616 */
1617 BOOL
1618 WINAPI
1619 PeekConsoleInputA(
1620 HANDLE hConsoleInput,
1621 PINPUT_RECORD lpBuffer,
1622 DWORD nLength,
1623 LPDWORD lpNumberOfEventsRead
1624 )
1625 {
1626 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1627 lpNumberOfEventsRead, FALSE);
1628 }
1629
1630
1631 /*--------------------------------------------------------------
1632 * PeekConsoleInputW
1633 *
1634 * @implemented
1635 */
1636 BOOL
1637 WINAPI
1638 PeekConsoleInputW(
1639 HANDLE hConsoleInput,
1640 PINPUT_RECORD lpBuffer,
1641 DWORD nLength,
1642 LPDWORD lpNumberOfEventsRead
1643 )
1644 {
1645 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1646 lpNumberOfEventsRead, TRUE);
1647 }
1648
1649
1650 static BOOL
1651 IntReadConsoleInput(HANDLE hConsoleInput,
1652 PINPUT_RECORD lpBuffer,
1653 DWORD nLength,
1654 LPDWORD lpNumberOfEventsRead,
1655 BOOL bUnicode)
1656 {
1657 CSR_API_MESSAGE Request; ULONG CsrRequest;
1658
1659 ULONG Read;
1660 NTSTATUS Status;
1661
1662 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
1663 Read = 0;
1664 while(nLength > 0)
1665 {
1666 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1667 Request.Data.ReadInputRequest.Unicode = bUnicode;
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.ReadCoord = dwReadCoord;
2118
2119 while(nLength > 0)
2120 {
2121 DWORD BytesRead;
2122
2123 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2124 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
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
2242 while (nLength != 0)
2243 {
2244 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2245 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2246
2247 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2248 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2249 else
2250 Size = nLength;
2251
2252 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2253
2254 Status = CsrClientCallServer(Request,
2255 NULL,
2256 CsrRequest,
2257 max (sizeof(CSR_API_MESSAGE),
2258 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2259 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2260 {
2261 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2262 SetLastErrorByStatus(Status);
2263 return(FALSE);
2264 }
2265
2266 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2267 lpAttribute += Size;
2268 nLength -= Size;
2269 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2270 }
2271
2272 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2273
2274 return(TRUE);
2275 }
2276
2277
2278 static BOOL
2279 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2280 PVOID lpCharacter,
2281 DWORD nLength,
2282 COORD dwWriteCoord,
2283 LPDWORD lpNumberOfCharsWritten,
2284 BOOL bUnicode)
2285 {
2286 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2287 NTSTATUS Status;
2288 ULONG SizeBytes, CharSize, nChars;
2289 DWORD Written = 0;
2290
2291 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2292
2293 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2294 SizeBytes = nChars * CharSize;
2295
2296 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2297 max (sizeof(CSR_API_MESSAGE),
2298 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2299 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2300 if (Request == NULL)
2301 {
2302 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2303 return FALSE;
2304 }
2305
2306 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2307 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2308
2309 while(nLength > 0)
2310 {
2311 DWORD BytesWrite;
2312
2313 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2314 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2315 Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
2316 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2317
2318 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2319
2320 Status = CsrClientCallServer(Request,
2321 NULL,
2322 CsrRequest,
2323 max (sizeof(CSR_API_MESSAGE),
2324 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2325
2326 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2327 {
2328 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2329 SetLastErrorByStatus(Status);
2330 return FALSE;
2331 }
2332
2333 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2334 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2335 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2336
2337 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2338 }
2339
2340 if(lpNumberOfCharsWritten != NULL)
2341 {
2342 *lpNumberOfCharsWritten = Written;
2343 }
2344
2345 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2346
2347 return TRUE;
2348 }
2349
2350
2351 /*--------------------------------------------------------------
2352 * WriteConsoleOutputCharacterA
2353 *
2354 * @implemented
2355 */
2356 BOOL WINAPI
2357 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2358 LPCSTR lpCharacter,
2359 DWORD nLength,
2360 COORD dwWriteCoord,
2361 LPDWORD lpNumberOfCharsWritten)
2362 {
2363 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2364 (PVOID)lpCharacter,
2365 nLength,
2366 dwWriteCoord,
2367 lpNumberOfCharsWritten,
2368 FALSE);
2369 }
2370
2371
2372 /*--------------------------------------------------------------
2373 * WriteConsoleOutputCharacterW
2374 *
2375 * @implemented
2376 */
2377 BOOL WINAPI
2378 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2379 LPCWSTR lpCharacter,
2380 DWORD nLength,
2381 COORD dwWriteCoord,
2382 LPDWORD lpNumberOfCharsWritten)
2383 {
2384 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2385 (PVOID)lpCharacter,
2386 nLength,
2387 dwWriteCoord,
2388 lpNumberOfCharsWritten,
2389 TRUE);
2390 }
2391
2392
2393 /*--------------------------------------------------------------
2394 * WriteConsoleOutputAttribute
2395 *
2396 * @implemented
2397 */
2398 BOOL
2399 WINAPI
2400 WriteConsoleOutputAttribute(
2401 HANDLE hConsoleOutput,
2402 CONST WORD *lpAttribute,
2403 DWORD nLength,
2404 COORD dwWriteCoord,
2405 LPDWORD lpNumberOfAttrsWritten
2406 )
2407 {
2408 PCSR_API_MESSAGE Request; ULONG CsrRequest;
2409 NTSTATUS Status;
2410 WORD Size;
2411
2412 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2413 max (sizeof(CSR_API_MESSAGE),
2414 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2415 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2416 if (Request == NULL)
2417 {
2418 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2419 return FALSE;
2420 }
2421
2422 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2423 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2424
2425 if( lpNumberOfAttrsWritten )
2426 *lpNumberOfAttrsWritten = nLength;
2427 while( nLength )
2428 {
2429 Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2430 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2431 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2432 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2433
2434 Status = CsrClientCallServer( Request,
2435 NULL,
2436 CsrRequest,
2437 max (sizeof(CSR_API_MESSAGE),
2438 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2439
2440 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request->Status ) )
2441 {
2442 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2443 SetLastErrorByStatus ( Status );
2444 return FALSE;
2445 }
2446 nLength -= Size;
2447 lpAttribute += Size;
2448 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2449 }
2450
2451 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2452
2453 return TRUE;
2454 }
2455
2456
2457 /*--------------------------------------------------------------
2458 * FillConsoleOutputAttribute
2459 *
2460 * @implemented
2461 */
2462 BOOL
2463 WINAPI
2464 FillConsoleOutputAttribute(
2465 HANDLE hConsoleOutput,
2466 WORD wAttribute,
2467 DWORD nLength,
2468 COORD dwWriteCoord,
2469 LPDWORD lpNumberOfAttrsWritten
2470 )
2471 {
2472 CSR_API_MESSAGE Request; ULONG CsrRequest;
2473
2474 NTSTATUS Status;
2475
2476 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2477 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2478 Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
2479 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2480 Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
2481 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2482 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2483 {
2484 SetLastErrorByStatus ( Status );
2485 return FALSE;
2486 }
2487 if( lpNumberOfAttrsWritten )
2488 *lpNumberOfAttrsWritten = nLength;
2489 return TRUE;
2490 }
2491
2492
2493 /*--------------------------------------------------------------
2494 * GetConsoleMode
2495 *
2496 * @implemented
2497 */
2498 BOOL
2499 WINAPI
2500 GetConsoleMode(
2501 HANDLE hConsoleHandle,
2502 LPDWORD lpMode
2503 )
2504 {
2505 CSR_API_MESSAGE Request; ULONG CsrRequest;
2506
2507 NTSTATUS Status;
2508
2509 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
2510 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2511 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2512 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2513 {
2514 SetLastErrorByStatus ( Status );
2515 return FALSE;
2516 }
2517 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
2518 return TRUE;
2519 }
2520
2521
2522 /*--------------------------------------------------------------
2523 * GetNumberOfConsoleInputEvents
2524 *
2525 * @implemented
2526 */
2527 BOOL
2528 WINAPI
2529 GetNumberOfConsoleInputEvents(
2530 HANDLE hConsoleInput,
2531 LPDWORD lpNumberOfEvents
2532 )
2533 {
2534 CSR_API_MESSAGE Request; ULONG CsrRequest;
2535
2536 NTSTATUS Status;
2537
2538 if(lpNumberOfEvents == NULL)
2539 {
2540 SetLastError(ERROR_INVALID_PARAMETER);
2541 return FALSE;
2542 }
2543
2544 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
2545 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2546 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2547 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2548 {
2549 SetLastErrorByStatus(Status);
2550 return FALSE;
2551 }
2552
2553 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
2554
2555 return TRUE;
2556 }
2557
2558
2559 /*--------------------------------------------------------------
2560 * GetLargestConsoleWindowSize
2561 *
2562 * @unimplemented
2563 */
2564 COORD
2565 WINAPI
2566 GetLargestConsoleWindowSize(
2567 HANDLE hConsoleOutput
2568 )
2569 {
2570 COORD Coord = {80,25};
2571 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
2572 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2573 return Coord;
2574 }
2575
2576
2577 /*--------------------------------------------------------------
2578 * GetConsoleCursorInfo
2579 *
2580 * @implemented
2581 */
2582 BOOL
2583 WINAPI
2584 GetConsoleCursorInfo(
2585 HANDLE hConsoleOutput,
2586 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
2587 )
2588 {
2589 CSR_API_MESSAGE Request; ULONG CsrRequest;
2590
2591 NTSTATUS Status;
2592
2593 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
2594 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2595 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2596
2597 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2598 {
2599 SetLastErrorByStatus ( Status );
2600 return FALSE;
2601 }
2602 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
2603 return TRUE;
2604 }
2605
2606
2607 /*--------------------------------------------------------------
2608 * GetNumberOfConsoleMouseButtons
2609 *
2610 * @unimplemented
2611 */
2612 BOOL
2613 WINAPI
2614 GetNumberOfConsoleMouseButtons(
2615 LPDWORD lpNumberOfMouseButtons
2616 )
2617 {
2618 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
2619 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2620 return FALSE;
2621 }
2622
2623
2624 /*--------------------------------------------------------------
2625 * SetConsoleMode
2626 *
2627 * @implemented
2628 */
2629 BOOL
2630 WINAPI
2631 SetConsoleMode(
2632 HANDLE hConsoleHandle,
2633 DWORD dwMode
2634 )
2635 {
2636 CSR_API_MESSAGE Request; ULONG CsrRequest;
2637
2638 NTSTATUS Status;
2639
2640 if (!IsConsoleHandle (hConsoleHandle))
2641 {
2642 DPRINT("SetConsoleMode was called with a non console handle\n");
2643 SetLastError (ERROR_INVALID_PARAMETER);
2644 return FALSE;
2645 }
2646
2647
2648 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
2649 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2650 Request.Data.SetConsoleModeRequest.Mode = dwMode;
2651 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2652 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2653 {
2654 SetLastErrorByStatus ( Status );
2655 return FALSE;
2656 }
2657 return TRUE;
2658 }
2659
2660
2661 /*--------------------------------------------------------------
2662 * SetConsoleActiveScreenBuffer
2663 *
2664 * @implemented
2665 */
2666 BOOL
2667 WINAPI
2668 SetConsoleActiveScreenBuffer(
2669 HANDLE hConsoleOutput
2670 )
2671 {
2672 CSR_API_MESSAGE Request; ULONG CsrRequest;
2673
2674 NTSTATUS Status;
2675
2676 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
2677 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
2678 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2679 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2680 {
2681 SetLastErrorByStatus ( Status );
2682 return FALSE;
2683 }
2684 return TRUE;
2685 }
2686
2687
2688 /*--------------------------------------------------------------
2689 * FlushConsoleInputBuffer
2690 *
2691 * @implemented
2692 */
2693 BOOL
2694 WINAPI
2695 FlushConsoleInputBuffer(
2696 HANDLE hConsoleInput
2697 )
2698 {
2699 CSR_API_MESSAGE Request; ULONG CsrRequest;
2700
2701 NTSTATUS Status;
2702
2703 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
2704 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
2705 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2706 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2707 {
2708 SetLastErrorByStatus ( Status );
2709 return FALSE;
2710 }
2711 return TRUE;
2712 }
2713
2714
2715 /*--------------------------------------------------------------
2716 * SetConsoleScreenBufferSize
2717 *
2718 * @unimplemented
2719 */
2720 BOOL
2721 WINAPI
2722 SetConsoleScreenBufferSize(
2723 HANDLE hConsoleOutput,
2724 COORD dwSize
2725 )
2726 {
2727 DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
2728 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2729 return FALSE;
2730 }
2731
2732 /*--------------------------------------------------------------
2733 * SetConsoleCursorInfo
2734 *
2735 * @implemented
2736 */
2737 BOOL
2738 WINAPI
2739 SetConsoleCursorInfo(
2740 HANDLE hConsoleOutput,
2741 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
2742 )
2743 {
2744 CSR_API_MESSAGE Request; ULONG CsrRequest;
2745
2746 NTSTATUS Status;
2747
2748 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
2749 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2750 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
2751 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2752
2753 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2754 {
2755 SetLastErrorByStatus ( Status );
2756 return FALSE;
2757 }
2758 return TRUE;
2759 }
2760
2761
2762 static BOOL
2763 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
2764 const SMALL_RECT *lpScrollRectangle,
2765 const SMALL_RECT *lpClipRectangle,
2766 COORD dwDestinationOrigin,
2767 const CHAR_INFO *lpFill,
2768 BOOL bUnicode)
2769 {
2770 CSR_API_MESSAGE Request; ULONG CsrRequest;
2771
2772 NTSTATUS Status;
2773
2774 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
2775 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
2776 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
2777 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
2778
2779 if(lpClipRectangle != NULL)
2780 {
2781 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
2782 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
2783 }
2784 else
2785 {
2786 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
2787 }
2788
2789 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
2790 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
2791 Status = CsrClientCallServer(&Request, NULL,
2792 CsrRequest,
2793 sizeof(CSR_API_MESSAGE));
2794
2795 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2796 {
2797 SetLastErrorByStatus(Status);
2798 return FALSE;
2799 }
2800
2801 return TRUE;
2802 }
2803
2804
2805 /*--------------------------------------------------------------
2806 * ScrollConsoleScreenBufferA
2807 *
2808 * @implemented
2809 */
2810 BOOL
2811 WINAPI
2812 ScrollConsoleScreenBufferA(
2813 HANDLE hConsoleOutput,
2814 CONST SMALL_RECT *lpScrollRectangle,
2815 CONST SMALL_RECT *lpClipRectangle,
2816 COORD dwDestinationOrigin,
2817 CONST CHAR_INFO *lpFill
2818 )
2819 {
2820 return IntScrollConsoleScreenBuffer(hConsoleOutput,
2821 (PSMALL_RECT)lpScrollRectangle,
2822 (PSMALL_RECT)lpClipRectangle,
2823 dwDestinationOrigin,
2824 (PCHAR_INFO)lpFill,
2825 FALSE);
2826 }
2827
2828
2829 /*--------------------------------------------------------------
2830 * ScrollConsoleScreenBufferW
2831 *
2832 * @implemented
2833 */
2834 BOOL
2835 WINAPI
2836 ScrollConsoleScreenBufferW(
2837 HANDLE hConsoleOutput,
2838 CONST SMALL_RECT *lpScrollRectangle,
2839 CONST SMALL_RECT *lpClipRectangle,
2840 COORD dwDestinationOrigin,
2841 CONST CHAR_INFO *lpFill
2842 )
2843 {
2844 return IntScrollConsoleScreenBuffer(hConsoleOutput,
2845 lpScrollRectangle,
2846 lpClipRectangle,
2847 dwDestinationOrigin,
2848 lpFill,
2849 TRUE);
2850 }
2851
2852
2853 /*--------------------------------------------------------------
2854 * SetConsoleWindowInfo
2855 *
2856 * @unimplemented
2857 */
2858 BOOL
2859 WINAPI
2860 SetConsoleWindowInfo(
2861 HANDLE hConsoleOutput,
2862 BOOL bAbsolute,
2863 CONST SMALL_RECT *lpConsoleWindow
2864 )
2865 {
2866 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
2867 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2868 return FALSE;
2869 }
2870
2871
2872 /*--------------------------------------------------------------
2873 * SetConsoleTextAttribute
2874 *
2875 * @implemented
2876 */
2877 BOOL
2878 WINAPI
2879 SetConsoleTextAttribute(
2880 HANDLE hConsoleOutput,
2881 WORD wAttributes
2882 )
2883 {
2884 CSR_API_MESSAGE Request; ULONG CsrRequest;
2885
2886 NTSTATUS Status;
2887
2888 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
2889 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2890 Request.Data.SetAttribRequest.Attrib = (CHAR)wAttributes;
2891 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2892 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
2893 {
2894 SetLastErrorByStatus ( Status );
2895 return FALSE;
2896 }
2897 return TRUE;
2898 }
2899
2900
2901 static BOOL
2902 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2903 {
2904 if (HandlerRoutine == NULL)
2905 {
2906 IgnoreCtrlEvents = TRUE;
2907 return(TRUE);
2908 }
2909 else
2910 {
2911 NrCtrlHandlers++;
2912 if (CtrlHandlers == NULL)
2913 {
2914 CtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
2915 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2916 }
2917 else
2918 {
2919 CtrlHandlers = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY,
2920 (PVOID)CtrlHandlers,
2921 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2922 }
2923 if (CtrlHandlers == NULL)
2924 {
2925 NrCtrlHandlers = 0;
2926 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2927 return(FALSE);
2928 }
2929 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2930 return(TRUE);
2931 }
2932 }
2933
2934
2935 static BOOL
2936 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2937 {
2938 ULONG i;
2939
2940 if (HandlerRoutine == NULL)
2941 {
2942 IgnoreCtrlEvents = FALSE;
2943 return(TRUE);
2944 }
2945 else
2946 {
2947 for (i = 0; i < NrCtrlHandlers; i++)
2948 {
2949 if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
2950 {
2951 NrCtrlHandlers--;
2952 memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
2953 (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
2954 CtrlHandlers =
2955 RtlReAllocateHeap(RtlGetProcessHeap(),
2956 HEAP_ZERO_MEMORY,
2957 (PVOID)CtrlHandlers,
2958 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2959 return(TRUE);
2960 }
2961 }
2962 }
2963 return(FALSE);
2964 }
2965
2966
2967 /*
2968 * @implemented
2969 */
2970 BOOL WINAPI
2971 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2972 BOOL Add)
2973 {
2974 BOOL Ret;
2975
2976 RtlEnterCriticalSection(&DllLock);
2977 if (Add)
2978 {
2979 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2980 }
2981 else
2982 {
2983 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2984 }
2985 RtlLeaveCriticalSection(&DllLock);
2986 return(Ret);
2987 }
2988
2989
2990 /*--------------------------------------------------------------
2991 * GenerateConsoleCtrlEvent
2992 *
2993 * @unimplemented
2994 */
2995 BOOL WINAPI
2996 GenerateConsoleCtrlEvent(
2997 DWORD dwCtrlEvent,
2998 DWORD dwProcessGroupId
2999 )
3000 {
3001 DPRINT1("GenerateConsoleCtrlEvent(0x%x, 0x%x) UNIMPLEMENTED!\n", dwCtrlEvent, dwProcessGroupId);
3002 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3003 return FALSE;
3004 }
3005
3006
3007 /*--------------------------------------------------------------
3008 * GetConsoleTitleW
3009 *
3010 * @implemented
3011 */
3012 DWORD
3013 WINAPI
3014 GetConsoleTitleW(
3015 LPWSTR lpConsoleTitle,
3016 DWORD nSize
3017 )
3018 {
3019 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3020 NTSTATUS Status;
3021 HANDLE hConsole;
3022
3023 hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3024 if (hConsole == INVALID_HANDLE_VALUE)
3025 {
3026 return 0;
3027 }
3028
3029 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3030 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3031 if (Request == NULL)
3032 {
3033 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3034 return FALSE;
3035 }
3036
3037 CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
3038 Request->Data.GetTitleRequest.ConsoleHandle = hConsole;
3039
3040 Status = CsrClientCallServer(Request,
3041 NULL,
3042 CsrRequest,
3043 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3044 CloseHandle(hConsole);
3045 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status)))
3046 {
3047 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3048 SetLastErrorByStatus(Status);
3049 return 0;
3050 }
3051
3052 if(nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length)
3053 {
3054 nSize--;
3055 }
3056 else
3057 {
3058 nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
3059 }
3060 memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR));
3061 lpConsoleTitle[nSize] = L'\0';
3062
3063 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3064
3065 return nSize;
3066 }
3067
3068
3069 /*--------------------------------------------------------------
3070 * GetConsoleTitleA
3071 *
3072 * 19990306 EA
3073 *
3074 * @implemented
3075 */
3076 DWORD
3077 WINAPI
3078 GetConsoleTitleA(
3079 LPSTR lpConsoleTitle,
3080 DWORD nSize
3081 )
3082 {
3083 WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1];
3084 DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1;
3085 DWORD nWritten;
3086
3087 if (!lpConsoleTitle || !nSize) return 0;
3088 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
3089 if (!nWideTitle) return 0;
3090
3091 if ( (nWritten = WideCharToMultiByte(
3092 CP_ACP, // ANSI code page
3093 0, // performance and mapping flags
3094 (LPWSTR) WideTitle, // address of wide-character string
3095 nWideTitle, // number of characters in string
3096 lpConsoleTitle, // address of buffer for new string
3097 nSize - 1, // size of buffer
3098 NULL, // FAST
3099 NULL // FAST
3100 )))
3101 {
3102 lpConsoleTitle[nWritten] = '\0';
3103 return nWritten;
3104 }
3105
3106 return 0;
3107 }
3108
3109
3110 /*--------------------------------------------------------------
3111 * SetConsoleTitleW
3112 *
3113 * @implemented
3114 */
3115 BOOL
3116 WINAPI
3117 SetConsoleTitleW(
3118 LPCWSTR lpConsoleTitle
3119 )
3120 {
3121 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3122 NTSTATUS Status;
3123 unsigned int c;
3124 HANDLE hConsole;
3125
3126 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3127 if (hConsole == INVALID_HANDLE_VALUE)
3128 {
3129 return FALSE;
3130 }
3131
3132 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3133 max (sizeof(CSR_API_MESSAGE),
3134 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3135 min (wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3136 if (Request == NULL)
3137 {
3138 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3139 return FALSE;
3140 }
3141
3142 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3143 Request->Data.SetTitleRequest.Console = hConsole;
3144
3145 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
3146 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3147 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3148 Status = CsrClientCallServer(Request,
3149 NULL,
3150 CsrRequest,
3151 max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3152 CloseHandle(hConsole);
3153 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
3154 {
3155 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3156 SetLastErrorByStatus (Status);
3157 return(FALSE);
3158 }
3159
3160 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3161
3162 return TRUE;
3163 }
3164
3165
3166 /*--------------------------------------------------------------
3167 * SetConsoleTitleA
3168 *
3169 * 19990204 EA Added
3170 *
3171 * @implemented
3172 */
3173 BOOL
3174 WINAPI
3175 SetConsoleTitleA(
3176 LPCSTR lpConsoleTitle
3177 )
3178 {
3179 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3180 NTSTATUS Status;
3181 unsigned int c;
3182 HANDLE hConsole;
3183
3184 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
3185 if (hConsole == INVALID_HANDLE_VALUE)
3186 {
3187 return FALSE;
3188 }
3189
3190 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3191 max (sizeof(CSR_API_MESSAGE),
3192 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3193 min (strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3194 if (Request == NULL)
3195 {
3196 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3197 return FALSE;
3198 }
3199
3200 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3201 Request->Data.SetTitleRequest.Console = hConsole;
3202
3203 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
3204 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3205 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3206 Status = CsrClientCallServer(Request,
3207 NULL,
3208 CsrRequest,
3209 max (sizeof(CSR_API_MESSAGE), CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3210 CloseHandle(hConsole);
3211 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Request->Status ) )
3212 {
3213 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3214 SetLastErrorByStatus (Status);
3215 return(FALSE);
3216 }
3217
3218 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3219
3220 return TRUE;
3221 }
3222
3223
3224 /*--------------------------------------------------------------
3225 * CreateConsoleScreenBuffer
3226 *
3227 * @implemented
3228 */
3229 HANDLE
3230 WINAPI
3231 CreateConsoleScreenBuffer(
3232 DWORD dwDesiredAccess,
3233 DWORD dwShareMode,
3234 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3235 DWORD dwFlags,
3236 LPVOID lpScreenBufferData
3237 )
3238 {
3239 // FIXME: don't ignore access, share mode, and security
3240 CSR_API_MESSAGE Request; ULONG CsrRequest;
3241
3242 NTSTATUS Status;
3243
3244 CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
3245 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3246 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Request.Status ) )
3247 {
3248 SetLastErrorByStatus ( Status );
3249 return FALSE;
3250 }
3251 return Request.Data.CreateScreenBufferRequest.OutputHandle;
3252 }
3253
3254
3255 /*--------------------------------------------------------------
3256 * GetConsoleCP
3257 *
3258 * @implemented
3259 */
3260 UINT
3261 WINAPI
3262 GetConsoleCP( VOID )
3263 {
3264 CSR_API_MESSAGE Request; ULONG CsrRequest;
3265
3266 NTSTATUS Status;
3267
3268 CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
3269 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3270 sizeof(CSR_API_MESSAGE));
3271 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3272 {
3273 SetLastErrorByStatus (Status);
3274 return 0;
3275 }
3276 return Request.Data.GetConsoleCodePage.CodePage;
3277 }
3278
3279
3280 /*--------------------------------------------------------------
3281 * SetConsoleCP
3282 *
3283 * @implemented
3284 */
3285 BOOL
3286 WINAPI
3287 SetConsoleCP(
3288 UINT wCodePageID
3289 )
3290 {
3291 CSR_API_MESSAGE Request; ULONG CsrRequest;
3292
3293 NTSTATUS Status;
3294
3295 CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
3296 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3297 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3298 sizeof(CSR_API_MESSAGE));
3299 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3300 {
3301 SetLastErrorByStatus (Status);
3302 }
3303 return NT_SUCCESS(Status);
3304 }
3305
3306
3307 /*--------------------------------------------------------------
3308 * GetConsoleOutputCP
3309 *
3310 * @implemented
3311 */
3312 UINT
3313 WINAPI
3314 GetConsoleOutputCP( VOID )
3315 {
3316 CSR_API_MESSAGE Request; ULONG CsrRequest;
3317
3318 NTSTATUS Status;
3319
3320 CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3321 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3322 sizeof(CSR_API_MESSAGE));
3323 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3324 {
3325 SetLastErrorByStatus (Status);
3326 return 0;
3327 }
3328 return Request.Data.GetConsoleOutputCodePage.CodePage;
3329 }
3330
3331
3332 /*--------------------------------------------------------------
3333 * SetConsoleOutputCP
3334 *
3335 * @implemented
3336 */
3337 BOOL
3338 WINAPI
3339 SetConsoleOutputCP(
3340 UINT wCodePageID
3341 )
3342 {
3343 CSR_API_MESSAGE Request; ULONG CsrRequest;
3344
3345 NTSTATUS Status;
3346
3347 CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3348 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3349 Status = CsrClientCallServer(&Request, NULL, CsrRequest,
3350 sizeof(CSR_API_MESSAGE));
3351 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3352 {
3353 SetLastErrorByStatus (Status);
3354 }
3355 return NT_SUCCESS(Status);
3356 }
3357
3358
3359 /*--------------------------------------------------------------
3360 * GetConsoleProcessList
3361 *
3362 * @implemented
3363 */
3364 DWORD STDCALL
3365 GetConsoleProcessList(LPDWORD lpdwProcessList,
3366 DWORD dwProcessCount)
3367 {
3368 PCSR_API_MESSAGE Request; ULONG CsrRequest;
3369 ULONG nProcesses;
3370 NTSTATUS Status;
3371
3372 if(lpdwProcessList == NULL || dwProcessCount == 0)
3373 {
3374 SetLastError(ERROR_INVALID_PARAMETER);
3375 return 0;
3376 }
3377
3378 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3379 max (sizeof(CSR_API_MESSAGE),
3380 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3381 + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
3382 if (Request == NULL)
3383 {
3384 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3385 return FALSE;
3386 }
3387
3388 CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
3389 Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
3390
3391 Status = CsrClientCallServer(Request,
3392 NULL,
3393 CsrRequest,
3394 max (sizeof(CSR_API_MESSAGE),
3395 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3396 + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
3397 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3398 {
3399 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3400 SetLastErrorByStatus (Status);
3401 nProcesses = 0;
3402 }
3403 else
3404 {
3405 nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
3406 if(dwProcessCount >= nProcesses)
3407 {
3408 memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
3409 }
3410 }
3411
3412 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3413
3414 return nProcesses;
3415 }
3416
3417
3418
3419 /*--------------------------------------------------------------
3420 * GetConsoleSelectionInfo
3421 *
3422 * @unimplemented
3423 */
3424 BOOL STDCALL
3425 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3426 {
3427 DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
3428 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3429 return FALSE;
3430 }
3431
3432
3433
3434 /*--------------------------------------------------------------
3435 * AttachConsole
3436 *
3437 * @unimplemented
3438 */
3439 BOOL STDCALL
3440 AttachConsole(DWORD dwProcessId)
3441 {
3442 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
3443 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3444 return FALSE;
3445 }
3446
3447 /*--------------------------------------------------------------
3448 * GetConsoleWindow
3449 *
3450 * @implemented
3451 */
3452 HWND STDCALL
3453 GetConsoleWindow (VOID)
3454 {
3455 CSR_API_MESSAGE Request; ULONG CsrRequest;
3456
3457 NTSTATUS Status;
3458
3459 CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
3460 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3461 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
3462 {
3463 SetLastErrorByStatus (Status);
3464 return (HWND) NULL;
3465 }
3466 return Request.Data.GetConsoleWindowRequest.WindowHandle;
3467 }
3468
3469
3470 /*--------------------------------------------------------------
3471 * SetConsoleIcon
3472 *
3473 * @implemented
3474 */
3475 BOOL STDCALL SetConsoleIcon(HICON hicon)
3476 {
3477 CSR_API_MESSAGE Request; ULONG CsrRequest;
3478
3479 NTSTATUS Status;
3480
3481 CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
3482 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3483 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3484 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3485 {
3486 SetLastErrorByStatus (Status);
3487 return FALSE;
3488 }
3489 return NT_SUCCESS(Status);
3490 }
3491
3492
3493 /*--------------------------------------------------------------
3494 * SetConsoleInputExeNameW
3495 *
3496 * @implemented
3497 */
3498 BOOL STDCALL
3499 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
3500 {
3501 BOOL Ret = FALSE;
3502 int lenName = lstrlenW(lpInputExeName);
3503
3504 if(lenName < 1 ||
3505 lenName > (int)(sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
3506 {
3507 /* Fail if string is empty or too long */
3508 SetLastError(ERROR_INVALID_PARAMETER);
3509 return FALSE;
3510 }
3511
3512 RtlEnterCriticalSection(&ConsoleLock);
3513 /* wrap copying into SEH as we may copy from invalid buffer and in case of an
3514 exception the console lock would've never been released, which would cause
3515 further calls (if the exception was handled by the caller) to recursively
3516 acquire the lock... */
3517 _SEH_TRY
3518 {
3519 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
3520 InputExeName[lenName] = L'\0';
3521 Ret = TRUE;
3522 }
3523 _SEH_HANDLE
3524 {
3525 lenName = 0;
3526 SetLastErrorByStatus(_SEH_GetExceptionCode());
3527 }
3528 _SEH_END;
3529 RtlLeaveCriticalSection(&ConsoleLock);
3530
3531 return Ret;
3532 }
3533
3534
3535 /*--------------------------------------------------------------
3536 * SetConsoleInputExeNameA
3537 *
3538 * @implemented
3539 */
3540 BOOL STDCALL
3541 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
3542 {
3543 ANSI_STRING InputExeNameA;
3544 UNICODE_STRING InputExeNameU;
3545 NTSTATUS Status;
3546 BOOL Ret;
3547
3548 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
3549
3550 if(InputExeNameA.Length < sizeof(InputExeNameA.Buffer[0]) ||
3551 InputExeNameA.Length >= (sizeof(InputExeName) / sizeof(InputExeName[0])) - 1)
3552 {
3553 /* Fail if string is empty or too long */
3554 SetLastError(ERROR_INVALID_PARAMETER);
3555 return FALSE;
3556 }
3557
3558 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, TRUE);
3559 if(NT_SUCCESS(Status))
3560 {
3561 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
3562 RtlFreeUnicodeString(&InputExeNameU);
3563 }
3564 else
3565 {
3566 SetLastErrorByStatus(Status);
3567 Ret = FALSE;
3568 }
3569
3570 return Ret;
3571 }
3572
3573
3574 /*--------------------------------------------------------------
3575 * GetConsoleInputExeNameW
3576 *
3577 * @implemented
3578 */
3579 DWORD STDCALL
3580 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
3581 {
3582 int lenName;
3583
3584 RtlEnterCriticalSection(&ConsoleLock);
3585
3586 lenName = lstrlenW(InputExeName);
3587 if(lenName >= (int)nBufferLength)
3588 {
3589 /* buffer is not large enough, return the required size */
3590 RtlLeaveCriticalSection(&ConsoleLock);
3591 return lenName + 1;
3592 }
3593
3594 /* wrap copying into SEH as we may copy to invalid buffer and in case of an
3595 exception the console lock would've never been released, which would cause
3596 further calls (if the exception was handled by the caller) to recursively
3597 acquire the lock... */
3598 _SEH_TRY
3599 {
3600 RtlCopyMemory(lpBuffer, InputExeName, (lenName + 1) * sizeof(WCHAR));
3601 }
3602 _SEH_HANDLE
3603 {
3604 lenName = 0;
3605 SetLastErrorByStatus(_SEH_GetExceptionCode());
3606 }
3607 _SEH_END;
3608
3609 RtlLeaveCriticalSection(&ConsoleLock);
3610
3611 return lenName;
3612 }
3613
3614
3615 /*--------------------------------------------------------------
3616 * GetConsoleInputExeNameA
3617 *
3618 * @implemented
3619 */
3620 DWORD STDCALL
3621 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
3622 {
3623 WCHAR *Buffer;
3624 DWORD Ret;
3625
3626 if(nBufferLength > 0)
3627 {
3628 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, nBufferLength * sizeof(WCHAR));
3629 if(Buffer == NULL)
3630 {
3631 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3632 return 0;
3633 }
3634 }
3635 else
3636 {
3637 Buffer = NULL;
3638 }
3639
3640 Ret = GetConsoleInputExeNameW(nBufferLength, Buffer);
3641 if(nBufferLength > 0)
3642 {
3643 if(Ret > 0)
3644 {
3645 UNICODE_STRING BufferU;
3646 ANSI_STRING BufferA;
3647
3648 RtlInitUnicodeString(&BufferU, Buffer);
3649
3650 BufferA.Length = 0;
3651 BufferA.MaximumLength = (USHORT)nBufferLength;
3652 BufferA.Buffer = lpBuffer;
3653
3654 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
3655 }
3656
3657 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
3658 }
3659
3660 return Ret;
3661 }
3662
3663
3664 /*--------------------------------------------------------------
3665 * GetConsoleHistoryInfo
3666 *
3667 * @unimplemented
3668 */
3669 BOOL STDCALL
3670 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
3671 {
3672 DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
3673 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3674 return FALSE;
3675 }
3676
3677
3678 /*--------------------------------------------------------------
3679 * SetConsoleHistoryInfo
3680 *
3681 * @unimplemented
3682 */
3683 BOOL STDCALL
3684 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
3685 {
3686 DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
3687 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3688 return FALSE;
3689 }
3690
3691
3692 /*--------------------------------------------------------------
3693 * GetConsoleOriginalTitleW
3694 *
3695 * @unimplemented
3696 */
3697 DWORD STDCALL
3698 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
3699 IN DWORD nSize)
3700 {
3701 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
3702 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3703 return 0;
3704 }
3705
3706
3707 /*--------------------------------------------------------------
3708 * GetConsoleOriginalTitleA
3709 *
3710 * @unimplemented
3711 */
3712 DWORD STDCALL
3713 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
3714 IN DWORD nSize)
3715 {
3716 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
3717 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3718 return 0;
3719 }
3720
3721
3722 /*--------------------------------------------------------------
3723 * GetConsoleScreenBufferInfoEx
3724 *
3725 * @unimplemented
3726 */
3727 BOOL STDCALL
3728 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
3729 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
3730 {
3731 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
3732 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3733 return FALSE;
3734 }
3735
3736
3737 /*--------------------------------------------------------------
3738 * SetConsoleScreenBufferInfoEx
3739 *
3740 * @unimplemented
3741 */
3742 BOOL STDCALL
3743 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
3744 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
3745 {
3746 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
3747 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3748 return FALSE;
3749 }
3750
3751
3752 /*--------------------------------------------------------------
3753 * GetCurrentConsoleFontEx
3754 *
3755 * @unimplemented
3756 */
3757 BOOL STDCALL
3758 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
3759 IN BOOL bMaximumWindow,
3760 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
3761 {
3762 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
3763 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3764 return FALSE;
3765 }
3766
3767 /* EOF */