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