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