KERNEL32.OpenConsoleW interface changed a proposed by KJK:Hyperion.
[reactos.git] / reactos / lib / kernel32 / misc / console.c
1 /* $Id: console.c,v 1.57 2003/05/16 20:33:15 ea Exp $
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: ???
8 * UPDATE HISTORY:
9 * 199901?? ?? Created
10 * 19990204 EA SetConsoleTitleA
11 * 19990306 EA Stubs
12 */
13
14 /* INCLUDES ******************************************************************/
15
16 #include <k32.h>
17
18 #define NDEBUG
19 #include <kernel32/kernel32.h>
20
21 /* GLOBALS *******************************************************************/
22
23 static BOOL IgnoreCtrlEvents = FALSE;
24 static ULONG NrCtrlHandlers = 0;
25 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
26
27 /* FUNCTIONS *****************************************************************/
28
29 BOOL STDCALL
30 AddConsoleAliasA (LPSTR Source,
31 LPSTR Target,
32 LPSTR ExeName)
33 {
34 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
35 return FALSE;
36 }
37
38 BOOL STDCALL
39 AddConsoleAliasW (LPWSTR Source,
40 LPWSTR Target,
41 LPWSTR ExeName)
42 {
43 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
44 return FALSE;
45 }
46
47 BOOL STDCALL
48 ConsoleMenuControl (HANDLE hConsole,
49 DWORD Unknown1,
50 DWORD Unknown2)
51 /*
52 * Undocumented
53 */
54 {
55 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
56 return FALSE;
57 }
58
59 HANDLE STDCALL
60 DuplicateConsoleHandle (HANDLE hConsole,
61 DWORD dwDesiredAccess,
62 BOOL bInheritHandle,
63 DWORD dwOptions)
64 {
65 CSRSS_API_REQUEST Request;
66 CSRSS_API_REPLY Reply;
67 NTSTATUS Status;
68
69 if (IsConsoleHandle (hConsole) == FALSE)
70 {
71 SetLastError (ERROR_INVALID_PARAMETER);
72 return INVALID_HANDLE_VALUE;
73 }
74
75 Request.Type = CSRSS_DUPLICATE_HANDLE;
76 Request.Data.DuplicateHandleRequest.Handle = hConsole;
77 Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
78 Status = CsrClientCallServer(&Request,
79 &Reply,
80 sizeof(CSRSS_API_REQUEST),
81 sizeof(CSRSS_API_REPLY));
82 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
83 {
84 SetLastErrorByStatus(Status);
85 return INVALID_HANDLE_VALUE;
86 }
87 return Reply.Data.DuplicateHandleReply.Handle;
88 }
89
90 DWORD STDCALL
91 ExpungeConsoleCommandHistoryW (DWORD Unknown0)
92 /*
93 * Undocumented
94 */
95 {
96 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
97 return 0;
98 }
99
100
101 DWORD STDCALL
102 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
103 /*
104 * Undocumented
105 */
106 {
107 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
108 return 0;
109 }
110
111 DWORD STDCALL
112 GetConsoleAliasW (DWORD Unknown0,
113 DWORD Unknown1,
114 DWORD Unknown2,
115 DWORD Unknown3)
116 /*
117 * Undocumented
118 */
119 {
120 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
121 return 0;
122 }
123
124
125 DWORD STDCALL
126 GetConsoleAliasA (DWORD Unknown0,
127 DWORD Unknown1,
128 DWORD Unknown2,
129 DWORD Unknown3)
130 /*
131 * Undocumented
132 */
133 {
134 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
135 return 0;
136 }
137
138 DWORD STDCALL
139 GetConsoleAliasExesW (DWORD Unknown0,
140 DWORD Unknown1)
141 /*
142 * Undocumented
143 */
144 {
145 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
146 return 0;
147 }
148
149
150
151 DWORD STDCALL
152 GetConsoleAliasExesA (DWORD Unknown0,
153 DWORD Unknown1)
154 /*
155 * Undocumented
156 */
157 {
158 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
159 return 0;
160 }
161
162
163
164 DWORD STDCALL
165 GetConsoleAliasExesLengthA (VOID)
166 /*
167 * Undocumented
168 */
169 {
170 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
171 return 0;
172 }
173
174 DWORD STDCALL
175 GetConsoleAliasExesLengthW (VOID)
176 /*
177 * Undocumented
178 */
179 {
180 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
181 return 0;
182 }
183
184 DWORD STDCALL
185 GetConsoleAliasesW (DWORD Unknown0,
186 DWORD Unknown1,
187 DWORD Unknown2)
188 /*
189 * Undocumented
190 */
191 {
192 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
193 return 0;
194 }
195
196 DWORD STDCALL
197 GetConsoleAliasesA (DWORD Unknown0,
198 DWORD Unknown1,
199 DWORD Unknown2)
200 /*
201 * Undocumented
202 */
203 {
204 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
205 return 0;
206 }
207
208 DWORD STDCALL
209 GetConsoleAliasesLengthW (DWORD Unknown0)
210 /*
211 * Undocumented
212 */
213 {
214 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
215 return 0;
216 }
217
218 DWORD STDCALL
219 GetConsoleAliasesLengthA (DWORD Unknown0)
220 /*
221 * Undocumented
222 */
223 {
224 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
225 return 0;
226 }
227
228 DWORD STDCALL
229 GetConsoleCommandHistoryW (DWORD Unknown0,
230 DWORD Unknown1,
231 DWORD Unknown2)
232 /*
233 * Undocumented
234 */
235 {
236 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
237 return 0;
238 }
239
240 DWORD STDCALL
241 GetConsoleCommandHistoryA (DWORD Unknown0,
242 DWORD Unknown1,
243 DWORD Unknown2)
244 /*
245 * Undocumented
246 */
247 {
248 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
249 return 0;
250 }
251
252 DWORD STDCALL
253 GetConsoleCommandHistoryLengthW (DWORD Unknown0)
254 /*
255 * Undocumented
256 */
257 {
258 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
259 return 0;
260 }
261
262 DWORD STDCALL
263 GetConsoleCommandHistoryLengthA (DWORD Unknown0)
264 /*
265 * Undocumented
266 */
267 {
268 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
269 return 0;
270 }
271
272 DWORD STDCALL
273 GetConsoleDisplayMode (LPDWORD lpdwMode)
274 /*
275 * FUNCTION: Get the console display mode
276 * ARGUMENTS:
277 * lpdwMode - Address of variable that receives the current value
278 * of display mode
279 * STATUS: Undocumented
280 */
281 {
282 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
283 return 0;
284 }
285
286 DWORD STDCALL
287 GetConsoleFontInfo (DWORD Unknown0,
288 DWORD Unknown1,
289 DWORD Unknown2,
290 DWORD Unknown3)
291 /*
292 * Undocumented
293 */
294 {
295 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
296 return 0;
297 }
298
299 DWORD STDCALL
300 GetConsoleFontSize(HANDLE hConsoleOutput,
301 DWORD nFont)
302 {
303 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
304 return 0;
305 }
306
307 DWORD STDCALL
308 GetConsoleHardwareState (DWORD Unknown0,
309 DWORD Unknown1,
310 DWORD Unknown2)
311 /*
312 * Undocumented
313 */
314 {
315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316 return 0;
317 }
318
319 DWORD STDCALL
320 GetConsoleInputWaitHandle (VOID)
321 /*
322 * Undocumented
323 */
324 {
325 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
326 return FALSE;
327 }
328
329 DWORD STDCALL
330 GetCurrentConsoleFont(HANDLE hConsoleOutput,
331 BOOL bMaximumWindow,
332 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
333 {
334 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
335 return 0;
336 }
337
338 ULONG STDCALL
339 GetNumberOfConsoleFonts (VOID)
340 /*
341 * Undocumented
342 */
343 {
344 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
345 return 1; /* FIXME: call csrss.exe */
346 }
347
348 DWORD STDCALL
349 InvalidateConsoleDIBits (DWORD Unknown0,
350 DWORD Unknown1)
351 /*
352 * Undocumented
353 */
354 {
355 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
356 return 0;
357 }
358
359 HANDLE STDCALL
360 OpenConsoleW (LPWSTR wsName,
361 DWORD dwDesiredAccess,
362 BOOL bInheritHandle,
363 DWORD dwCreationDistribution)
364 /*
365 * Undocumented
366 */
367 {
368 CSRSS_API_REQUEST Request;
369 CSRSS_API_REPLY Reply;
370 PHANDLE phConsole = NULL;
371 NTSTATUS Status = STATUS_SUCCESS;
372
373
374 if(0 == _wcsicmp(wsName, L"CONIN$"))
375 {
376 Request.Type = CSRSS_GET_INPUT_HANDLE;
377 phConsole = & Reply.Data.GetInputHandleReply.InputHandle;
378 }
379 else if (0 == _wcsicmp(wsName, L"CONOUT$"))
380 {
381 Request.Type = CSRSS_GET_OUTPUT_HANDLE;
382 phConsole = & Reply.Data.GetOutputHandleReply.OutputHandle;
383 }
384 else
385 {
386 SetLastError(ERROR_INVALID_PARAMETER);
387 return(INVALID_HANDLE_VALUE);
388 }
389 if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess)
390 {
391 SetLastError(ERROR_INVALID_PARAMETER);
392 return(INVALID_HANDLE_VALUE);
393 }
394 if (OPEN_EXISTING != dwCreationDistribution)
395 {
396 SetLastError(ERROR_INVALID_PARAMETER);
397 return(INVALID_HANDLE_VALUE);
398 }
399 Status = CsrClientCallServer(& Request,
400 & Reply,
401 sizeof(CSRSS_API_REQUEST),
402 sizeof(CSRSS_API_REPLY));
403 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
404 {
405 SetLastErrorByStatus(Status);
406 return INVALID_HANDLE_VALUE;
407 }
408 return(*phConsole);
409 }
410
411 WINBOOL STDCALL
412 SetConsoleCommandHistoryMode (DWORD dwMode)
413 /*
414 * Undocumented
415 */
416 {
417 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
418 return FALSE;
419 }
420
421 WINBOOL STDCALL
422 SetConsoleCursor (DWORD Unknown0,
423 DWORD Unknown1)
424 /*
425 * Undocumented
426 */
427 {
428 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
429 return FALSE;
430 }
431
432 WINBOOL STDCALL
433 SetConsoleDisplayMode (HANDLE hOut,
434 DWORD dwNewMode,
435 LPDWORD lpdwOldMode)
436 /*
437 * FUNCTION: Set the console display mode.
438 * ARGUMENTS:
439 * hOut - Standard output handle.
440 * dwNewMode - New mode.
441 * lpdwOldMode - Address of a variable that receives the old mode.
442 */
443 {
444 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
445 return FALSE;
446 }
447
448 WINBOOL STDCALL
449 SetConsoleFont (DWORD Unknown0,
450 DWORD Unknown1)
451 /*
452 * Undocumented
453 */
454 {
455 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
456 return FALSE;
457 }
458
459 WINBOOL STDCALL
460 SetConsoleHardwareState (DWORD Unknown0,
461 DWORD Unknown1,
462 DWORD Unknown2)
463 /*
464 * Undocumented
465 */
466 {
467 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
468 return FALSE;
469 }
470
471 WINBOOL STDCALL
472 SetConsoleKeyShortcuts (DWORD Unknown0,
473 DWORD Unknown1,
474 DWORD Unknown2,
475 DWORD Unknown3)
476 /*
477 * Undocumented
478 */
479 {
480 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
481 return FALSE;
482 }
483
484 WINBOOL STDCALL
485 SetConsoleMaximumWindowSize (DWORD Unknown0,
486 DWORD Unknown1)
487 /*
488 * Undocumented
489 */
490 {
491 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
492 return FALSE;
493 }
494
495 WINBOOL STDCALL
496 SetConsoleMenuClose (DWORD Unknown0)
497 /*
498 * Undocumented
499 */
500 {
501 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
502 return FALSE;
503 }
504
505 WINBOOL STDCALL
506 SetConsoleNumberOfCommandsA (DWORD Unknown0,
507 DWORD Unknown1)
508 /*
509 * Undocumented
510 */
511 {
512 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
513 return FALSE;
514 }
515
516 WINBOOL STDCALL
517 SetConsoleNumberOfCommandsW (DWORD Unknown0,
518 DWORD Unknown1)
519 /*
520 * Undocumented
521 */
522 {
523 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
524 return FALSE;
525 }
526
527 WINBOOL STDCALL
528 SetConsolePalette (DWORD Unknown0,
529 DWORD Unknown1,
530 DWORD Unknown2)
531 /*
532 * Undocumented
533 */
534 {
535 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
536 return FALSE;
537 }
538
539 WINBOOL STDCALL
540 SetLastConsoleEventActive (VOID)
541 /*
542 * Undocumented
543 */
544 {
545 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
546 return FALSE;
547 }
548
549 DWORD STDCALL
550 ShowConsoleCursor (DWORD Unknown0,
551 DWORD Unknown1)
552 /*
553 * Undocumented
554 */
555 {
556 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
557 return 0;
558 }
559
560
561 /*
562 * FUNCTION: Checks whether the given handle is a valid console handle.
563 * ARGUMENTS:
564 * Handle - Handle to be checked
565 * RETURNS:
566 * TRUE: Handle is a valid console handle
567 * FALSE: Handle is not a valid console handle.
568 * STATUS: Officially undocumented
569 */
570 BOOL STDCALL
571 VerifyConsoleIoHandle(HANDLE Handle)
572 {
573 CSRSS_API_REQUEST Request;
574 CSRSS_API_REPLY Reply;
575 NTSTATUS Status;
576
577 Request.Type = CSRSS_VERIFY_HANDLE;
578 Request.Data.VerifyHandleRequest.Handle = Handle;
579 Status = CsrClientCallServer(&Request,
580 &Reply,
581 sizeof(CSRSS_API_REQUEST),
582 sizeof(CSRSS_API_REPLY));
583 if (!NT_SUCCESS(Status))
584 {
585 SetLastErrorByStatus(Status);
586 return FALSE;
587 }
588
589 return (BOOL)NT_SUCCESS(Reply.Status);
590 }
591
592
593 DWORD STDCALL
594 WriteConsoleInputVDMA (DWORD Unknown0,
595 DWORD Unknown1,
596 DWORD Unknown2,
597 DWORD Unknown3)
598 {
599 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
600 return 0;
601 }
602
603 DWORD STDCALL
604 WriteConsoleInputVDMW (DWORD Unknown0,
605 DWORD Unknown1,
606 DWORD Unknown2,
607 DWORD Unknown3)
608 {
609 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
610 return 0;
611 }
612
613 WINBOOL STDCALL
614 CloseConsoleHandle(HANDLE Handle)
615 /*
616 * Undocumented
617 */
618 {
619 CSRSS_API_REQUEST Request;
620 CSRSS_API_REPLY Reply;
621 NTSTATUS Status;
622
623 if (IsConsoleHandle (Handle) == FALSE)
624 {
625 SetLastError (ERROR_INVALID_PARAMETER);
626 return FALSE;
627 }
628
629 Request.Type = CSRSS_CLOSE_HANDLE;
630 Request.Data.CloseHandleRequest.Handle = Handle;
631 Status = CsrClientCallServer(&Request,
632 &Reply,
633 sizeof(CSRSS_API_REQUEST),
634 sizeof(CSRSS_API_REPLY));
635 if (!NT_SUCCESS(Status))
636 {
637 SetLastErrorByStatus(Status);
638 return FALSE;
639 }
640
641 return TRUE;
642 }
643
644
645 BOOLEAN STDCALL
646 IsConsoleHandle(HANDLE Handle)
647 {
648 if ((((ULONG)Handle) & 0x10000003) == 0x3)
649 {
650 return(TRUE);
651 }
652 return(FALSE);
653 }
654
655 HANDLE STDCALL
656 GetStdHandle(DWORD nStdHandle)
657 /*
658 * FUNCTION: Get a handle for the standard input, standard output
659 * and a standard error device.
660 * ARGUMENTS:
661 * nStdHandle - Specifies the device for which to return the handle.
662 * RETURNS: If the function succeeds, the return value is the handle
663 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
664 */
665 {
666 PRTL_USER_PROCESS_PARAMETERS Ppb;
667
668 Ppb = NtCurrentPeb()->ProcessParameters;
669 switch (nStdHandle)
670 {
671 case STD_INPUT_HANDLE:
672 return Ppb->hStdInput;
673
674 case STD_OUTPUT_HANDLE:
675 return Ppb->hStdOutput;
676
677 case STD_ERROR_HANDLE:
678 return Ppb->hStdError;
679 }
680
681 SetLastError (ERROR_INVALID_PARAMETER);
682 return INVALID_HANDLE_VALUE;
683 }
684
685 WINBASEAPI BOOL WINAPI
686 SetStdHandle(DWORD nStdHandle,
687 HANDLE hHandle)
688 /*
689 * FUNCTION: Set the handle for the standard input, standard output or
690 * the standard error device.
691 * ARGUMENTS:
692 * nStdHandle - Specifies the handle to be set.
693 * hHandle - The handle to set.
694 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
695 */
696 {
697 PRTL_USER_PROCESS_PARAMETERS Ppb;
698
699 Ppb = NtCurrentPeb()->ProcessParameters;
700
701 /* More checking needed? */
702 if (hHandle == INVALID_HANDLE_VALUE)
703 {
704 SetLastError (ERROR_INVALID_HANDLE);
705 return FALSE;
706 }
707
708 SetLastError(ERROR_SUCCESS); /* OK */
709
710 switch (nStdHandle)
711 {
712 case STD_INPUT_HANDLE:
713 Ppb->hStdInput = hHandle;
714 return TRUE;
715
716 case STD_OUTPUT_HANDLE:
717 Ppb->hStdOutput = hHandle;
718 return TRUE;
719
720 case STD_ERROR_HANDLE:
721 Ppb->hStdError = hHandle;
722 return TRUE;
723 }
724
725 SetLastError (ERROR_INVALID_PARAMETER);
726 return FALSE;
727 }
728
729
730 /*--------------------------------------------------------------
731 * WriteConsoleA
732 */
733 WINBOOL STDCALL
734 WriteConsoleA(HANDLE hConsoleOutput,
735 CONST VOID *lpBuffer,
736 DWORD nNumberOfCharsToWrite,
737 LPDWORD lpNumberOfCharsWritten,
738 LPVOID lpReserved)
739 {
740 PCSRSS_API_REQUEST Request;
741 CSRSS_API_REPLY Reply;
742 NTSTATUS Status;
743 USHORT Size;
744 ULONG MessageSize;
745
746 Request = RtlAllocateHeap(GetProcessHeap(),
747 HEAP_ZERO_MEMORY,
748 sizeof(CSRSS_API_REQUEST) +
749 CSRSS_MAX_WRITE_CONSOLE_REQUEST);
750 if (Request == NULL)
751 {
752 SetLastError(ERROR_OUTOFMEMORY);
753 return(FALSE);
754 }
755
756 Request->Type = CSRSS_WRITE_CONSOLE;
757 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
758 if (lpNumberOfCharsWritten != NULL)
759 *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
760 while (nNumberOfCharsToWrite)
761 {
762 if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
763 {
764 Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
765 }
766 else
767 {
768 Size = nNumberOfCharsToWrite;
769 }
770 Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
771
772 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
773
774 MessageSize = CSRSS_REQUEST_HEADER_SIZE +
775 sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
776 Status = CsrClientCallServer(Request,
777 &Reply,
778 MessageSize,
779 sizeof(CSRSS_API_REPLY));
780
781 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
782 {
783 RtlFreeHeap(GetProcessHeap(), 0, Request);
784 SetLastErrorByStatus(Status);
785 return(FALSE);
786 }
787 nNumberOfCharsToWrite -= Size;
788 lpBuffer += Size;
789 }
790
791 RtlFreeHeap(GetProcessHeap(), 0, Request);
792
793 return TRUE;
794 }
795
796
797 /*--------------------------------------------------------------
798 * ReadConsoleA
799 */
800 WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
801 LPVOID lpBuffer,
802 DWORD nNumberOfCharsToRead,
803 LPDWORD lpNumberOfCharsRead,
804 LPVOID lpReserved)
805 {
806 CSRSS_API_REQUEST Request;
807 PCSRSS_API_REPLY Reply;
808 NTSTATUS Status;
809 ULONG CharsRead = 0;
810
811 Reply = RtlAllocateHeap(GetProcessHeap(),
812 HEAP_ZERO_MEMORY,
813 sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
814 if (Reply == NULL)
815 {
816 SetLastError(ERROR_OUTOFMEMORY);
817 return(FALSE);
818 }
819
820 Request.Type = CSRSS_READ_CONSOLE;
821 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
822 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
823 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
824 Status = CsrClientCallServer(&Request,
825 Reply,
826 sizeof(CSRSS_API_REQUEST),
827 sizeof(CSRSS_API_REPLY) +
828 Request.Data.ReadConsoleRequest.NrCharactersToRead);
829 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
830 {
831 DbgPrint( "CSR returned error in ReadConsole\n" );
832 SetLastErrorByStatus ( Status );
833 RtlFreeHeap( GetProcessHeap(), 0, Reply );
834 return(FALSE);
835 }
836 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
837 Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
838 /* There may not be any chars or lines to read yet, so wait */
839 while( Reply->Status == STATUS_PENDING )
840 {
841 /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
842 nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
843 /* don't overflow caller's buffer, even if you still don't have a complete line */
844 if( !nNumberOfCharsToRead )
845 break;
846 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
847 /* copy any chars already read to buffer */
848 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
849 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
850 /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
851 Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
852 if( !NT_SUCCESS( Status ) )
853 {
854 DbgPrint( "Wait for console input failed!\n" );
855 RtlFreeHeap( GetProcessHeap(), 0, Reply );
856 return FALSE;
857 }
858 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
859 Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
860 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
861 {
862 SetLastErrorByStatus ( Status );
863 RtlFreeHeap( GetProcessHeap(), 0, Reply );
864 return FALSE;
865 }
866 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
867 {
868 // delete last char
869 if( CharsRead )
870 {
871 CharsRead--;
872 nNumberOfCharsToRead++;
873 }
874 Reply->Status = STATUS_PENDING; // retry
875 }
876 }
877 /* copy data to buffer, count total returned, and return */
878 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
879 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
880 if (lpNumberOfCharsRead != NULL)
881 *lpNumberOfCharsRead = CharsRead;
882 RtlFreeHeap(GetProcessHeap(),
883 0,
884 Reply);
885
886 return(TRUE);
887 }
888
889
890 /*--------------------------------------------------------------
891 * AllocConsole
892 */
893 WINBOOL STDCALL AllocConsole(VOID)
894 {
895 CSRSS_API_REQUEST Request;
896 CSRSS_API_REPLY Reply;
897 NTSTATUS Status;
898 HANDLE hStdError;
899
900 Request.Type = CSRSS_ALLOC_CONSOLE;
901 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
902 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
903 {
904 SetLastErrorByStatus ( Status );
905 return FALSE;
906 }
907 SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
908 SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
909 hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
910 0,
911 TRUE,
912 DUPLICATE_SAME_ACCESS);
913 SetStdHandle( STD_ERROR_HANDLE, hStdError );
914 return TRUE;
915 }
916
917
918 /*--------------------------------------------------------------
919 * FreeConsole
920 */
921 WINBOOL STDCALL FreeConsole(VOID)
922 {
923 DbgPrint("FreeConsole() is unimplemented\n");
924 return FALSE;
925 }
926
927
928 /*--------------------------------------------------------------
929 * GetConsoleScreenBufferInfo
930 */
931 WINBOOL
932 STDCALL
933 GetConsoleScreenBufferInfo(
934 HANDLE hConsoleOutput,
935 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
936 )
937 {
938 CSRSS_API_REQUEST Request;
939 CSRSS_API_REPLY Reply;
940 NTSTATUS Status;
941
942 Request.Type = CSRSS_SCREEN_BUFFER_INFO;
943 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
944 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
945 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
946 {
947 SetLastErrorByStatus ( Status );
948 return FALSE;
949 }
950 *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
951 return TRUE;
952 }
953
954
955 /*--------------------------------------------------------------
956 * SetConsoleCursorPosition
957 */
958 WINBOOL
959 STDCALL
960 SetConsoleCursorPosition(
961 HANDLE hConsoleOutput,
962 COORD dwCursorPosition
963 )
964 {
965 CSRSS_API_REQUEST Request;
966 CSRSS_API_REPLY Reply;
967 NTSTATUS Status;
968
969 Request.Type = CSRSS_SET_CURSOR;
970 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
971 Request.Data.SetCursorRequest.Position = dwCursorPosition;
972 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
973 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
974 {
975 SetLastErrorByStatus ( Status );
976 return FALSE;
977 }
978 return TRUE;
979 }
980
981
982 /*--------------------------------------------------------------
983 * FillConsoleOutputCharacterA
984 */
985 WINBOOL STDCALL
986 FillConsoleOutputCharacterA(
987 HANDLE hConsoleOutput,
988 CHAR cCharacter,
989 DWORD nLength,
990 COORD dwWriteCoord,
991 LPDWORD lpNumberOfCharsWritten
992 )
993 {
994 CSRSS_API_REQUEST Request;
995 CSRSS_API_REPLY Reply;
996 NTSTATUS Status;
997
998 Request.Type = CSRSS_FILL_OUTPUT;
999 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1000 Request.Data.FillOutputRequest.Char = cCharacter;
1001 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1002 Request.Data.FillOutputRequest.Length = nLength;
1003 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1004 if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1005 {
1006 SetLastErrorByStatus(Status);
1007 return(FALSE);
1008 }
1009 if (lpNumberOfCharsWritten != NULL)
1010 *lpNumberOfCharsWritten = nLength;
1011 return(TRUE);
1012 }
1013
1014
1015 /*--------------------------------------------------------------
1016 * FillConsoleOutputCharacterW
1017 */
1018 WINBOOL
1019 STDCALL
1020 FillConsoleOutputCharacterW(
1021 HANDLE hConsoleOutput,
1022 WCHAR cCharacter,
1023 DWORD nLength,
1024 COORD dwWriteCoord,
1025 LPDWORD lpNumberOfCharsWritten
1026 )
1027 {
1028 /* TO DO */
1029 return FALSE;
1030 }
1031
1032
1033 /*--------------------------------------------------------------
1034 * PeekConsoleInputA
1035 */
1036 WINBASEAPI
1037 BOOL
1038 WINAPI
1039 PeekConsoleInputA(
1040 HANDLE hConsoleInput,
1041 PINPUT_RECORD lpBuffer,
1042 DWORD nLength,
1043 LPDWORD lpNumberOfEventsRead
1044 )
1045 {
1046 PCSRSS_API_REQUEST Request;
1047 CSRSS_API_REPLY Reply;
1048 NTSTATUS Status;
1049 PVOID BufferBase;
1050 PVOID BufferTargetBase;
1051 DWORD Size;
1052
1053 if(lpBuffer == NULL)
1054 {
1055 SetLastError(ERROR_INVALID_PARAMETER);
1056 return FALSE;
1057 }
1058
1059 Size = nLength * sizeof(INPUT_RECORD);
1060
1061 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1062 if(!NT_SUCCESS(Status))
1063 {
1064 SetLastErrorByStatus(Status);
1065 return FALSE;
1066 }
1067
1068 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1069 if(Request == NULL)
1070 {
1071 CsrReleaseParameterBuffer(BufferBase);
1072 SetLastError(ERROR_OUTOFMEMORY);
1073 return FALSE;
1074 }
1075
1076 Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
1077 Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1078 Request->Data.PeekConsoleInputRequest.Length = nLength;
1079 Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
1080
1081 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1082
1083 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1084 {
1085 RtlFreeHeap(GetProcessHeap(), 0, Request);
1086 CsrReleaseParameterBuffer(BufferBase);
1087 return FALSE;
1088 }
1089
1090 memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
1091
1092 if(lpNumberOfEventsRead != NULL)
1093 *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
1094
1095 RtlFreeHeap(GetProcessHeap(), 0, Request);
1096 CsrReleaseParameterBuffer(BufferBase);
1097
1098 return TRUE;
1099 }
1100
1101
1102 /*--------------------------------------------------------------
1103 * PeekConsoleInputW
1104 */
1105 WINBASEAPI
1106 BOOL
1107 WINAPI
1108 PeekConsoleInputW(
1109 HANDLE hConsoleInput,
1110 PINPUT_RECORD lpBuffer,
1111 DWORD nLength,
1112 LPDWORD lpNumberOfEventsRead
1113 )
1114 {
1115 /* TO DO */
1116 return FALSE;
1117 }
1118
1119
1120 /*--------------------------------------------------------------
1121 * ReadConsoleInputA
1122 */
1123 WINBASEAPI BOOL WINAPI
1124 ReadConsoleInputA(HANDLE hConsoleInput,
1125 PINPUT_RECORD lpBuffer,
1126 DWORD nLength,
1127 LPDWORD lpNumberOfEventsRead)
1128 {
1129 CSRSS_API_REQUEST Request;
1130 CSRSS_API_REPLY Reply;
1131 DWORD NumEventsRead;
1132 NTSTATUS Status;
1133
1134 Request.Type = CSRSS_READ_INPUT;
1135 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1136 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1137 sizeof(CSRSS_API_REPLY));
1138 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1139 {
1140 SetLastErrorByStatus(Status);
1141 return(FALSE);
1142 }
1143
1144 while (Status == STATUS_PENDING)
1145 {
1146 Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE,
1147 0);
1148 if(!NT_SUCCESS(Status))
1149 {
1150 SetLastErrorByStatus(Status);
1151 return FALSE;
1152 }
1153
1154 Request.Type = CSRSS_READ_INPUT;
1155 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1156 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1157 sizeof(CSRSS_API_REPLY));
1158 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1159 {
1160 SetLastErrorByStatus(Status);
1161 return(FALSE);
1162 }
1163 }
1164
1165 NumEventsRead = 0;
1166 *lpBuffer = Reply.Data.ReadInputReply.Input;
1167 lpBuffer++;
1168 NumEventsRead++;
1169
1170 while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
1171 {
1172 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1173 sizeof(CSRSS_API_REPLY));
1174 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1175 {
1176 SetLastErrorByStatus(Status);
1177 return(FALSE);
1178 }
1179
1180 if (Status == STATUS_PENDING)
1181 {
1182 break;
1183 }
1184
1185 *lpBuffer = Reply.Data.ReadInputReply.Input;
1186 lpBuffer++;
1187 NumEventsRead++;
1188
1189 }
1190 *lpNumberOfEventsRead = NumEventsRead;
1191
1192 return TRUE;
1193 }
1194
1195
1196 /*--------------------------------------------------------------
1197 * ReadConsoleInputW
1198 */
1199 WINBASEAPI
1200 BOOL
1201 WINAPI
1202 ReadConsoleInputW(
1203 HANDLE hConsoleInput,
1204 PINPUT_RECORD lpBuffer,
1205 DWORD nLength,
1206 LPDWORD lpNumberOfEventsRead
1207 )
1208 {
1209 /* TO DO */
1210 return FALSE;
1211 }
1212
1213
1214 /*--------------------------------------------------------------
1215 * WriteConsoleInputA
1216 */
1217 WINBASEAPI
1218 BOOL
1219 WINAPI
1220 WriteConsoleInputA(
1221 HANDLE hConsoleInput,
1222 CONST INPUT_RECORD *lpBuffer,
1223 DWORD nLength,
1224 LPDWORD lpNumberOfEventsWritten
1225 )
1226 {
1227 PCSRSS_API_REQUEST Request;
1228 CSRSS_API_REPLY Reply;
1229 PVOID BufferBase, BufferTargetBase;
1230 NTSTATUS Status;
1231 DWORD Size;
1232
1233 if(lpBuffer == NULL)
1234 {
1235 SetLastError(ERROR_INVALID_PARAMETER);
1236 return FALSE;
1237 }
1238
1239 Size = nLength * sizeof(INPUT_RECORD);
1240
1241 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1242 if(!NT_SUCCESS(Status))
1243 {
1244 SetLastErrorByStatus(Status);
1245 return FALSE;
1246 }
1247
1248 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1249 if(Request == NULL)
1250 {
1251 SetLastError(ERROR_OUTOFMEMORY);
1252 CsrReleaseParameterBuffer(BufferBase);
1253 return FALSE;
1254 }
1255
1256 Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
1257 Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
1258 Request->Data.WriteConsoleInputRequest.Length = nLength;
1259 Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
1260
1261 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1262 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1263 {
1264 RtlFreeHeap(GetProcessHeap(), 0, Request);
1265 CsrReleaseParameterBuffer(BufferBase);
1266 return FALSE;
1267 }
1268
1269 if(lpNumberOfEventsWritten != NULL)
1270 *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
1271
1272 RtlFreeHeap(GetProcessHeap(), 0, Request);
1273 CsrReleaseParameterBuffer(BufferBase);
1274
1275 return TRUE;
1276 }
1277
1278
1279 /*--------------------------------------------------------------
1280 * WriteConsoleInputW
1281 */
1282 WINBASEAPI
1283 BOOL
1284 WINAPI
1285 WriteConsoleInputW(
1286 HANDLE hConsoleInput,
1287 CONST INPUT_RECORD *lpBuffer,
1288 DWORD nLength,
1289 LPDWORD lpNumberOfEventsWritten
1290 )
1291 {
1292 /* TO DO */
1293 return FALSE;
1294 }
1295
1296
1297 /*--------------------------------------------------------------
1298 * ReadConsoleOutputA
1299 */
1300 WINBASEAPI
1301 BOOL
1302 WINAPI
1303 ReadConsoleOutputA(
1304 HANDLE hConsoleOutput,
1305 PCHAR_INFO lpBuffer,
1306 COORD dwBufferSize,
1307 COORD dwBufferCoord,
1308 PSMALL_RECT lpReadRegion
1309 )
1310 {
1311 PCSRSS_API_REQUEST Request;
1312 CSRSS_API_REPLY Reply;
1313 PVOID BufferBase;
1314 PVOID BufferTargetBase;
1315 NTSTATUS Status;
1316 DWORD Size, SizeX, SizeY;
1317
1318 if(lpBuffer == NULL)
1319 {
1320 SetLastError(ERROR_INVALID_PARAMETER);
1321 return FALSE;
1322 }
1323
1324 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
1325
1326 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1327 if(!NT_SUCCESS(Status))
1328 {
1329 SetLastErrorByStatus(Status);
1330 return FALSE;
1331 }
1332
1333 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1334 if(Request == NULL)
1335 {
1336 SetLastError(ERROR_OUTOFMEMORY);
1337 CsrReleaseParameterBuffer(BufferBase);
1338 return FALSE;
1339 }
1340
1341 Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
1342 Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1343 Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
1344 Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
1345 Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
1346 Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
1347
1348 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1349 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1350 {
1351 SetLastErrorByStatus(Status);
1352 RtlFreeHeap(GetProcessHeap(), 0, Request);
1353 CsrReleaseParameterBuffer(BufferBase);
1354 return FALSE;
1355 }
1356
1357 SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
1358 SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
1359
1360 memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
1361 *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
1362
1363 RtlFreeHeap(GetProcessHeap(), 0, Request);
1364 CsrReleaseParameterBuffer(BufferBase);
1365
1366 return TRUE;
1367 }
1368
1369
1370 /*--------------------------------------------------------------
1371 * ReadConsoleOutputW
1372 */
1373 WINBASEAPI
1374 BOOL
1375 WINAPI
1376 ReadConsoleOutputW(
1377 HANDLE hConsoleOutput,
1378 PCHAR_INFO lpBuffer,
1379 COORD dwBufferSize,
1380 COORD dwBufferCoord,
1381 PSMALL_RECT lpReadRegion
1382 )
1383 {
1384 /* TO DO */
1385 return FALSE;
1386 }
1387
1388 /*--------------------------------------------------------------
1389 * WriteConsoleOutputA
1390 */
1391 WINBASEAPI BOOL WINAPI
1392 WriteConsoleOutputA(HANDLE hConsoleOutput,
1393 CONST CHAR_INFO *lpBuffer,
1394 COORD dwBufferSize,
1395 COORD dwBufferCoord,
1396 PSMALL_RECT lpWriteRegion)
1397 {
1398 PCSRSS_API_REQUEST Request;
1399 CSRSS_API_REPLY Reply;
1400 NTSTATUS Status;
1401 ULONG Size;
1402 BOOLEAN Result;
1403 ULONG i, j;
1404 PVOID BufferBase;
1405 PVOID BufferTargetBase;
1406
1407 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
1408
1409 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
1410 Size,
1411 &BufferBase,
1412 &BufferTargetBase);
1413 if (!NT_SUCCESS(Status))
1414 {
1415 SetLastErrorByStatus(Status);
1416 return(FALSE);
1417 }
1418
1419 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY,
1420 sizeof(CSRSS_API_REQUEST));
1421 if (Request == NULL)
1422 {
1423 CsrReleaseParameterBuffer(BufferBase);
1424 SetLastError(ERROR_OUTOFMEMORY);
1425 return FALSE;
1426 }
1427 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
1428 Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1429 Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
1430 Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
1431 Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
1432 Request->Data.WriteConsoleOutputRequest.CharInfo =
1433 (CHAR_INFO*)BufferTargetBase;
1434
1435 Status = CsrClientCallServer(Request, &Reply,
1436 sizeof(CSRSS_API_REQUEST),
1437 sizeof(CSRSS_API_REPLY));
1438 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1439 {
1440 CsrReleaseParameterBuffer(BufferBase);
1441 RtlFreeHeap(GetProcessHeap(), 0, Request);
1442 SetLastErrorByStatus(Status);
1443 return FALSE;
1444 }
1445
1446 *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
1447 RtlFreeHeap(GetProcessHeap(), 0, Request);
1448 CsrReleaseParameterBuffer(BufferBase);
1449 return(TRUE);
1450 }
1451
1452
1453 /*--------------------------------------------------------------
1454 * WriteConsoleOutputW
1455 */
1456 WINBASEAPI
1457 BOOL
1458 WINAPI
1459 WriteConsoleOutputW(
1460 HANDLE hConsoleOutput,
1461 CONST CHAR_INFO *lpBuffer,
1462 COORD dwBufferSize,
1463 COORD dwBufferCoord,
1464 PSMALL_RECT lpWriteRegion
1465 )
1466 {
1467 /* TO DO */
1468 return FALSE;
1469 }
1470
1471
1472 /*--------------------------------------------------------------
1473 * ReadConsoleOutputCharacterA
1474 */
1475 WINBASEAPI
1476 BOOL
1477 WINAPI
1478 ReadConsoleOutputCharacterA(
1479 HANDLE hConsoleOutput,
1480 LPSTR lpCharacter,
1481 DWORD nLength,
1482 COORD dwReadCoord,
1483 LPDWORD lpNumberOfCharsRead
1484 )
1485 {
1486 CSRSS_API_REQUEST Request;
1487 PCSRSS_API_REPLY Reply;
1488 NTSTATUS Status;
1489 DWORD Size;
1490
1491 Reply = RtlAllocateHeap(GetProcessHeap(),
1492 HEAP_ZERO_MEMORY,
1493 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR);
1494 if (Reply == NULL)
1495 {
1496 SetLastError(ERROR_OUTOFMEMORY);
1497 return(FALSE);
1498 }
1499
1500 if (lpNumberOfCharsRead != NULL)
1501 *lpNumberOfCharsRead = nLength;
1502
1503 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
1504 Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1505 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
1506
1507 while (nLength != 0)
1508 {
1509 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
1510 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
1511 else
1512 Size = nLength;
1513
1514 Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
1515
1516 Status = CsrClientCallServer(&Request,
1517 Reply,
1518 sizeof(CSRSS_API_REQUEST),
1519 sizeof(CSRSS_API_REPLY) + Size);
1520 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1521 {
1522 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1523 SetLastErrorByStatus(Status);
1524 return(FALSE);
1525 }
1526
1527 memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
1528 lpCharacter += Size;
1529 nLength -= Size;
1530 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
1531 }
1532
1533 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1534
1535 return(TRUE);
1536 }
1537
1538
1539 /*--------------------------------------------------------------
1540 * ReadConsoleOutputCharacterW
1541 */
1542 WINBASEAPI
1543 BOOL
1544 WINAPI
1545 ReadConsoleOutputCharacterW(
1546 HANDLE hConsoleOutput,
1547 LPWSTR lpCharacter,
1548 DWORD nLength,
1549 COORD dwReadCoord,
1550 LPDWORD lpNumberOfCharsRead
1551 )
1552 {
1553 /* TO DO */
1554 return FALSE;
1555 }
1556
1557
1558 /*--------------------------------------------------------------
1559 * ReadConsoleOutputAttribute
1560 */
1561 WINBASEAPI
1562 BOOL
1563 WINAPI
1564 ReadConsoleOutputAttribute(
1565 HANDLE hConsoleOutput,
1566 LPWORD lpAttribute,
1567 DWORD nLength,
1568 COORD dwReadCoord,
1569 LPDWORD lpNumberOfAttrsRead
1570 )
1571 {
1572 CSRSS_API_REQUEST Request;
1573 PCSRSS_API_REPLY Reply;
1574 NTSTATUS Status;
1575 DWORD Size, i;
1576
1577 Reply = RtlAllocateHeap(GetProcessHeap(),
1578 HEAP_ZERO_MEMORY,
1579 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
1580 if (Reply == NULL)
1581 {
1582 SetLastError(ERROR_OUTOFMEMORY);
1583 return(FALSE);
1584 }
1585
1586 if (lpNumberOfAttrsRead != NULL)
1587 *lpNumberOfAttrsRead = nLength;
1588
1589 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
1590 Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1591 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
1592
1593 while (nLength != 0)
1594 {
1595 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
1596 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
1597 else
1598 Size = nLength;
1599
1600 Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
1601
1602 Status = CsrClientCallServer(&Request,
1603 Reply,
1604 sizeof(CSRSS_API_REQUEST),
1605 sizeof(CSRSS_API_REPLY) + Size);
1606 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1607 {
1608 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1609 SetLastErrorByStatus(Status);
1610 return(FALSE);
1611 }
1612
1613 // Convert CHARs to WORDs
1614 for(i = 0; i < Size; ++i)
1615 *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
1616
1617 nLength -= Size;
1618 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
1619 }
1620
1621 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1622
1623 return(TRUE);
1624 }
1625
1626
1627 /*--------------------------------------------------------------
1628 * WriteConsoleOutputCharacterA
1629 */
1630 WINBASEAPI BOOL WINAPI
1631 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
1632 LPCSTR lpCharacter,
1633 DWORD nLength,
1634 COORD dwWriteCoord,
1635 LPDWORD lpNumberOfCharsWritten)
1636 {
1637 PCSRSS_API_REQUEST Request;
1638 CSRSS_API_REPLY Reply;
1639 NTSTATUS Status;
1640 WORD Size;
1641
1642 Request = RtlAllocateHeap(GetProcessHeap(),
1643 HEAP_ZERO_MEMORY,
1644 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR);
1645 if( !Request )
1646 {
1647 SetLastError( ERROR_OUTOFMEMORY );
1648 return FALSE;
1649 }
1650 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
1651 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1652 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
1653 if( lpNumberOfCharsWritten )
1654 *lpNumberOfCharsWritten = nLength;
1655 while( nLength )
1656 {
1657 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
1658 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
1659 memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
1660 lpCharacter,
1661 Size );
1662 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
1663 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1664 {
1665 RtlFreeHeap( GetProcessHeap(), 0, Request );
1666 SetLastErrorByStatus ( Status );
1667 return FALSE;
1668 }
1669 nLength -= Size;
1670 lpCharacter += Size;
1671 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
1672 }
1673
1674 RtlFreeHeap( GetProcessHeap(), 0, Request );
1675 return TRUE;
1676 }
1677
1678
1679 /*--------------------------------------------------------------
1680 * WriteConsoleOutputCharacterW
1681 */
1682 WINBASEAPI
1683 BOOL
1684 WINAPI
1685 WriteConsoleOutputCharacterW(
1686 HANDLE hConsoleOutput,
1687 LPCWSTR lpCharacter,
1688 DWORD nLength,
1689 COORD dwWriteCoord,
1690 LPDWORD lpNumberOfCharsWritten
1691 )
1692 {
1693 /* TO DO */
1694 return FALSE;
1695 }
1696
1697
1698
1699 /*--------------------------------------------------------------
1700 * WriteConsoleOutputAttribute
1701 */
1702 WINBASEAPI
1703 BOOL
1704 WINAPI
1705 WriteConsoleOutputAttribute(
1706 HANDLE hConsoleOutput,
1707 CONST WORD *lpAttribute,
1708 DWORD nLength,
1709 COORD dwWriteCoord,
1710 LPDWORD lpNumberOfAttrsWritten
1711 )
1712 {
1713 PCSRSS_API_REQUEST Request;
1714 CSRSS_API_REPLY Reply;
1715 NTSTATUS Status;
1716 WORD Size;
1717 int c;
1718
1719 Request = RtlAllocateHeap(GetProcessHeap(),
1720 HEAP_ZERO_MEMORY,
1721 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
1722 if( !Request )
1723 {
1724 SetLastError( ERROR_OUTOFMEMORY );
1725 return FALSE;
1726 }
1727 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
1728 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1729 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
1730 if( lpNumberOfAttrsWritten )
1731 *lpNumberOfAttrsWritten = nLength;
1732 while( nLength )
1733 {
1734 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
1735 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
1736 for( c = 0; c < ( Size * 2 ); c++ )
1737 Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
1738 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
1739 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1740 {
1741 RtlFreeHeap( GetProcessHeap(), 0, Request );
1742 SetLastErrorByStatus ( Status );
1743 return FALSE;
1744 }
1745 nLength -= Size;
1746 lpAttribute += Size;
1747 Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
1748 }
1749
1750 RtlFreeHeap( GetProcessHeap(), 0, Request );
1751 return TRUE;
1752 }
1753
1754
1755 /*--------------------------------------------------------------
1756 * FillConsoleOutputAttribute
1757 */
1758 WINBASEAPI
1759 BOOL
1760 WINAPI
1761 FillConsoleOutputAttribute(
1762 HANDLE hConsoleOutput,
1763 WORD wAttribute,
1764 DWORD nLength,
1765 COORD dwWriteCoord,
1766 LPDWORD lpNumberOfAttrsWritten
1767 )
1768 {
1769 CSRSS_API_REQUEST Request;
1770 CSRSS_API_REPLY Reply;
1771 NTSTATUS Status;
1772
1773 Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
1774 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1775 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
1776 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
1777 Request.Data.FillOutputAttribRequest.Length = nLength;
1778 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1779 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1780 {
1781 SetLastErrorByStatus ( Status );
1782 return FALSE;
1783 }
1784 if( lpNumberOfAttrsWritten )
1785 *lpNumberOfAttrsWritten = nLength;
1786 return TRUE;
1787 }
1788
1789
1790 /*--------------------------------------------------------------
1791 * GetConsoleMode
1792 */
1793 WINBASEAPI
1794 BOOL
1795 WINAPI
1796 GetConsoleMode(
1797 HANDLE hConsoleHandle,
1798 LPDWORD lpMode
1799 )
1800 {
1801 CSRSS_API_REQUEST Request;
1802 CSRSS_API_REPLY Reply;
1803 NTSTATUS Status;
1804
1805 Request.Type = CSRSS_GET_MODE;
1806 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
1807 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1808 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1809 {
1810 SetLastErrorByStatus ( Status );
1811 return FALSE;
1812 }
1813 *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
1814 return TRUE;
1815 }
1816
1817
1818 /*--------------------------------------------------------------
1819 * GetNumberOfConsoleInputEvents
1820 */
1821 WINBASEAPI
1822 BOOL
1823 WINAPI
1824 GetNumberOfConsoleInputEvents(
1825 HANDLE hConsoleInput,
1826 LPDWORD lpNumberOfEvents
1827 )
1828 {
1829 CSRSS_API_REQUEST Request;
1830 CSRSS_API_REPLY Reply;
1831 NTSTATUS Status;
1832
1833 if(lpNumberOfEvents == NULL)
1834 {
1835 SetLastError(ERROR_INVALID_PARAMETER);
1836 return FALSE;
1837 }
1838
1839 Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
1840 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
1841 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1842 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1843 {
1844 SetLastErrorByStatus(Status);
1845 return FALSE;
1846 }
1847
1848 *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
1849
1850 return TRUE;
1851 }
1852
1853
1854 /*--------------------------------------------------------------
1855 * GetLargestConsoleWindowSize
1856 */
1857 WINBASEAPI
1858 COORD
1859 WINAPI
1860 GetLargestConsoleWindowSize(
1861 HANDLE hConsoleOutput
1862 )
1863 {
1864 #if 1 /* FIXME: */
1865 COORD Coord = {80,25};
1866
1867 /* TO DO */
1868 return Coord;
1869 #endif
1870 }
1871
1872
1873 /*--------------------------------------------------------------
1874 * GetConsoleCursorInfo
1875 */
1876 WINBASEAPI
1877 BOOL
1878 WINAPI
1879 GetConsoleCursorInfo(
1880 HANDLE hConsoleOutput,
1881 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
1882 )
1883 {
1884 CSRSS_API_REQUEST Request;
1885 CSRSS_API_REPLY Reply;
1886 NTSTATUS Status;
1887
1888 Request.Type = CSRSS_GET_CURSOR_INFO;
1889 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
1890 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1891
1892 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1893 {
1894 SetLastErrorByStatus ( Status );
1895 return FALSE;
1896 }
1897 *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
1898 return TRUE;
1899 }
1900
1901
1902 /*--------------------------------------------------------------
1903 * GetNumberOfConsoleMouseButtons
1904 */
1905 WINBASEAPI
1906 BOOL
1907 WINAPI
1908 GetNumberOfConsoleMouseButtons(
1909 LPDWORD lpNumberOfMouseButtons
1910 )
1911 {
1912 /* TO DO */
1913 return FALSE;
1914 }
1915
1916
1917 /*--------------------------------------------------------------
1918 * SetConsoleMode
1919 */
1920 WINBASEAPI
1921 BOOL
1922 WINAPI
1923 SetConsoleMode(
1924 HANDLE hConsoleHandle,
1925 DWORD dwMode
1926 )
1927 {
1928 CSRSS_API_REQUEST Request;
1929 CSRSS_API_REPLY Reply;
1930 NTSTATUS Status;
1931
1932 Request.Type = CSRSS_SET_MODE;
1933 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
1934 Request.Data.SetConsoleModeRequest.Mode = dwMode;
1935 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1936 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1937 {
1938 SetLastErrorByStatus ( Status );
1939 return FALSE;
1940 }
1941 return TRUE;
1942 }
1943
1944
1945 /*--------------------------------------------------------------
1946 * SetConsoleActiveScreenBuffer
1947 */
1948 WINBASEAPI
1949 BOOL
1950 WINAPI
1951 SetConsoleActiveScreenBuffer(
1952 HANDLE hConsoleOutput
1953 )
1954 {
1955 CSRSS_API_REQUEST Request;
1956 CSRSS_API_REPLY Reply;
1957 NTSTATUS Status;
1958
1959 Request.Type = CSRSS_SET_SCREEN_BUFFER;
1960 Request.Data.SetActiveScreenBufferRequest.OutputHandle = hConsoleOutput;
1961 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1962 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1963 {
1964 SetLastErrorByStatus ( Status );
1965 return FALSE;
1966 }
1967 return TRUE;
1968 }
1969
1970
1971 /*--------------------------------------------------------------
1972 * FlushConsoleInputBuffer
1973 */
1974 WINBASEAPI
1975 BOOL
1976 WINAPI
1977 FlushConsoleInputBuffer(
1978 HANDLE hConsoleInput
1979 )
1980 {
1981 CSRSS_API_REQUEST Request;
1982 CSRSS_API_REPLY Reply;
1983 NTSTATUS Status;
1984
1985 Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
1986 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
1987 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1988 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1989 {
1990 SetLastErrorByStatus ( Status );
1991 return FALSE;
1992 }
1993 return TRUE;
1994 }
1995
1996
1997 /*--------------------------------------------------------------
1998 * SetConsoleScreenBufferSize
1999 */
2000 WINBASEAPI
2001 BOOL
2002 WINAPI
2003 SetConsoleScreenBufferSize(
2004 HANDLE hConsoleOutput,
2005 COORD dwSize
2006 )
2007 {
2008 /* TO DO */
2009 return FALSE;
2010 }
2011
2012 /*--------------------------------------------------------------
2013 * SetConsoleCursorInfo
2014 */
2015 WINBASEAPI
2016 BOOL
2017 WINAPI
2018 SetConsoleCursorInfo(
2019 HANDLE hConsoleOutput,
2020 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
2021 )
2022 {
2023 CSRSS_API_REQUEST Request;
2024 CSRSS_API_REPLY Reply;
2025 NTSTATUS Status;
2026
2027 Request.Type = CSRSS_SET_CURSOR_INFO;
2028 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2029 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
2030 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2031
2032 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2033 {
2034 SetLastErrorByStatus ( Status );
2035 return FALSE;
2036 }
2037 return TRUE;
2038 }
2039
2040
2041 /*--------------------------------------------------------------
2042 * ScrollConsoleScreenBufferA
2043 */
2044 WINBASEAPI
2045 BOOL
2046 WINAPI
2047 ScrollConsoleScreenBufferA(
2048 HANDLE hConsoleOutput,
2049 CONST SMALL_RECT *lpScrollRectangle,
2050 CONST SMALL_RECT *lpClipRectangle,
2051 COORD dwDestinationOrigin,
2052 CONST CHAR_INFO *lpFill
2053 )
2054 {
2055 CSRSS_API_REQUEST Request;
2056 CSRSS_API_REPLY Reply;
2057 NTSTATUS Status;
2058
2059 Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
2060 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
2061 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
2062
2063 if (lpClipRectangle != NULL)
2064 {
2065 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
2066 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
2067 }
2068 else
2069 {
2070 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
2071 }
2072
2073 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
2074 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
2075 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2076
2077 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2078 {
2079 SetLastErrorByStatus ( Status );
2080 return FALSE;
2081 }
2082 return TRUE;
2083 }
2084
2085
2086 /*--------------------------------------------------------------
2087 * ScrollConsoleScreenBufferW
2088 */
2089 WINBASEAPI
2090 BOOL
2091 WINAPI
2092 ScrollConsoleScreenBufferW(
2093 HANDLE hConsoleOutput,
2094 CONST SMALL_RECT *lpScrollRectangle,
2095 CONST SMALL_RECT *lpClipRectangle,
2096 COORD dwDestinationOrigin,
2097 CONST CHAR_INFO *lpFill
2098 )
2099 {
2100 /* TO DO */
2101 return FALSE;
2102 }
2103
2104
2105 /*--------------------------------------------------------------
2106 * SetConsoleWindowInfo
2107 */
2108 WINBASEAPI
2109 BOOL
2110 WINAPI
2111 SetConsoleWindowInfo(
2112 HANDLE hConsoleOutput,
2113 BOOL bAbsolute,
2114 CONST SMALL_RECT *lpConsoleWindow
2115 )
2116 {
2117 /* TO DO */
2118 return FALSE;
2119 }
2120
2121
2122 /*--------------------------------------------------------------
2123 * SetConsoleTextAttribute
2124 */
2125 WINBASEAPI
2126 BOOL
2127 WINAPI
2128 SetConsoleTextAttribute(
2129 HANDLE hConsoleOutput,
2130 WORD wAttributes
2131 )
2132 {
2133 CSRSS_API_REQUEST Request;
2134 CSRSS_API_REPLY Reply;
2135 NTSTATUS Status;
2136
2137 Request.Type = CSRSS_SET_ATTRIB;
2138 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2139 Request.Data.SetAttribRequest.Attrib = wAttributes;
2140 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2141 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2142 {
2143 SetLastErrorByStatus ( Status );
2144 return FALSE;
2145 }
2146 return TRUE;
2147 }
2148
2149 BOOL STATIC
2150 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2151 {
2152 if (HandlerRoutine == NULL)
2153 {
2154 IgnoreCtrlEvents = TRUE;
2155 return(TRUE);
2156 }
2157 else
2158 {
2159 NrCtrlHandlers++;
2160 CtrlHandlers =
2161 RtlReAllocateHeap(RtlGetProcessHeap(),
2162 HEAP_ZERO_MEMORY,
2163 (PVOID)CtrlHandlers,
2164 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2165 if (CtrlHandlers == NULL)
2166 {
2167 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2168 return(FALSE);
2169 }
2170 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2171 return(TRUE);
2172 }
2173 }
2174
2175 BOOL STATIC
2176 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2177 {
2178 ULONG i;
2179
2180 if (HandlerRoutine == NULL)
2181 {
2182 IgnoreCtrlEvents = FALSE;
2183 return(TRUE);
2184 }
2185 else
2186 {
2187 for (i = 0; i < NrCtrlHandlers; i++)
2188 {
2189 if (CtrlHandlers[i] == HandlerRoutine)
2190 {
2191 CtrlHandlers[i] = CtrlHandlers[NrCtrlHandlers - 1];
2192 NrCtrlHandlers--;
2193 CtrlHandlers =
2194 RtlReAllocateHeap(RtlGetProcessHeap(),
2195 HEAP_ZERO_MEMORY,
2196 (PVOID)CtrlHandlers,
2197 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2198 return(TRUE);
2199 }
2200 }
2201 }
2202 return(FALSE);
2203 }
2204
2205 WINBASEAPI BOOL WINAPI
2206 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2207 BOOL Add)
2208 {
2209 BOOLEAN Ret;
2210
2211 RtlEnterCriticalSection(&DllLock);
2212 if (Add)
2213 {
2214 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2215 }
2216 else
2217 {
2218 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2219 }
2220 RtlLeaveCriticalSection(&DllLock);
2221 return(Ret);
2222 }
2223
2224
2225 /*--------------------------------------------------------------
2226 * GenerateConsoleCtrlEvent
2227 */
2228 WINBASEAPI BOOL WINAPI
2229 GenerateConsoleCtrlEvent(
2230 DWORD dwCtrlEvent,
2231 DWORD dwProcessGroupId
2232 )
2233 {
2234 /* TO DO */
2235 return FALSE;
2236 }
2237
2238
2239 /*--------------------------------------------------------------
2240 * GetConsoleTitleW
2241 */
2242
2243 WINBASEAPI
2244 DWORD
2245 WINAPI
2246 GetConsoleTitleW(
2247 LPWSTR lpConsoleTitle,
2248 DWORD nSize
2249 )
2250 {
2251 CSRSS_API_REQUEST Request;
2252 PCSRSS_API_REPLY Reply;
2253 NTSTATUS Status;
2254 HANDLE hConsole;
2255
2256 hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2257 if (hConsole == INVALID_HANDLE_VALUE)
2258 {
2259 return 0;
2260 }
2261
2262 Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2263 if(Reply == NULL)
2264 {
2265 CloseHandle(hConsole);
2266 SetLastError(ERROR_OUTOFMEMORY);
2267 return 0;
2268 }
2269
2270 Request.Type = CSRSS_GET_TITLE;
2271 Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
2272
2273 Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2274 CloseHandle(hConsole);
2275 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
2276 {
2277 SetLastErrorByStatus(Status);
2278 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2279 return 0;
2280 }
2281
2282 if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
2283 {
2284 wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
2285 lpConsoleTitle[nSize--] = L'\0';
2286 }
2287 else
2288 {
2289 nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
2290 wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
2291 lpConsoleTitle[nSize] = L'\0';
2292 }
2293
2294 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2295 return nSize;
2296 }
2297
2298
2299 /*--------------------------------------------------------------
2300 * GetConsoleTitleA
2301 *
2302 * 19990306 EA
2303 */
2304 WINBASEAPI
2305 DWORD
2306 WINAPI
2307 GetConsoleTitleA(
2308 LPSTR lpConsoleTitle,
2309 DWORD nSize
2310 )
2311 {
2312 wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
2313 DWORD nWideTitle = sizeof WideTitle;
2314 DWORD nWritten;
2315
2316 if (!lpConsoleTitle || !nSize) return 0;
2317 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
2318 if (!nWideTitle) return 0;
2319
2320 if ( (nWritten = WideCharToMultiByte(
2321 CP_ACP, // ANSI code page
2322 0, // performance and mapping flags
2323 (LPWSTR) WideTitle, // address of wide-character string
2324 nWideTitle, // number of characters in string
2325 lpConsoleTitle, // address of buffer for new string
2326 nSize, // size of buffer
2327 NULL, // FAST
2328 NULL // FAST
2329 )))
2330 {
2331 lpConsoleTitle[nWritten] = '\0';
2332 return nWritten;
2333 }
2334
2335 return 0;
2336 }
2337
2338
2339 /*--------------------------------------------------------------
2340 * SetConsoleTitleW
2341 */
2342 WINBASEAPI
2343 BOOL
2344 WINAPI
2345 SetConsoleTitleW(
2346 LPCWSTR lpConsoleTitle
2347 )
2348 {
2349 PCSRSS_API_REQUEST Request;
2350 CSRSS_API_REPLY Reply;
2351 NTSTATUS Status;
2352 unsigned int c;
2353 HANDLE hConsole;
2354
2355 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2356 if (hConsole == INVALID_HANDLE_VALUE)
2357 {
2358 return FALSE;
2359 }
2360
2361 Request = RtlAllocateHeap(GetProcessHeap(),
2362 HEAP_ZERO_MEMORY,
2363 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2364 if (Request == NULL)
2365 {
2366 CloseHandle(hConsole);
2367 SetLastError(ERROR_OUTOFMEMORY);
2368 return(FALSE);
2369 }
2370
2371 Request->Type = CSRSS_SET_TITLE;
2372 Request->Data.SetTitleRequest.Console = hConsole;
2373
2374 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2375 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2376 // add null
2377 Request->Data.SetTitleRequest.Title[c] = 0;
2378 Request->Data.SetTitleRequest.Length = c;
2379 Status = CsrClientCallServer(Request,
2380 &Reply,
2381 sizeof(CSRSS_API_REQUEST) +
2382 c * sizeof(WCHAR),
2383 sizeof(CSRSS_API_REPLY));
2384 CloseHandle(hConsole);
2385 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2386 {
2387 RtlFreeHeap( GetProcessHeap(), 0, Request );
2388 SetLastErrorByStatus (Status);
2389 return(FALSE);
2390 }
2391 RtlFreeHeap( GetProcessHeap(), 0, Request );
2392 return TRUE;
2393 }
2394
2395
2396 /*--------------------------------------------------------------
2397 * SetConsoleTitleA
2398 *
2399 * 19990204 EA Added
2400 */
2401 WINBASEAPI
2402 BOOL
2403 WINAPI
2404 SetConsoleTitleA(
2405 LPCSTR lpConsoleTitle
2406 )
2407 {
2408 PCSRSS_API_REQUEST Request;
2409 CSRSS_API_REPLY Reply;
2410 NTSTATUS Status;
2411 unsigned int c;
2412 HANDLE hConsole;
2413
2414 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2415 if (hConsole == INVALID_HANDLE_VALUE)
2416 {
2417 return FALSE;
2418 }
2419
2420 Request = RtlAllocateHeap(GetProcessHeap(),
2421 HEAP_ZERO_MEMORY,
2422 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2423 if (Request == NULL)
2424 {
2425 CloseHandle(hConsole);
2426 SetLastError(ERROR_OUTOFMEMORY);
2427 return(FALSE);
2428 }
2429
2430 Request->Type = CSRSS_SET_TITLE;
2431 Request->Data.SetTitleRequest.Console = hConsole;
2432
2433 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2434 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2435 // add null
2436 Request->Data.SetTitleRequest.Title[c] = 0;
2437 Request->Data.SetTitleRequest.Length = c;
2438 Status = CsrClientCallServer(Request,
2439 &Reply,
2440 sizeof(CSRSS_API_REQUEST) +
2441 c * sizeof(WCHAR),
2442 sizeof(CSRSS_API_REPLY));
2443 CloseHandle(hConsole);
2444 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2445 {
2446 RtlFreeHeap( GetProcessHeap(), 0, Request );
2447 SetLastErrorByStatus (Status);
2448 return(FALSE);
2449 }
2450 RtlFreeHeap( GetProcessHeap(), 0, Request );
2451 return TRUE;
2452 }
2453
2454
2455 /*--------------------------------------------------------------
2456 * ReadConsoleW
2457 */
2458 WINBASEAPI
2459 BOOL
2460 WINAPI
2461 ReadConsoleW(
2462 HANDLE hConsoleInput,
2463 LPVOID lpBuffer,
2464 DWORD nNumberOfCharsToRead,
2465 LPDWORD lpNumberOfCharsRead,
2466 LPVOID lpReserved
2467 )
2468 {
2469 /* --- TO DO --- */
2470 return FALSE;
2471 }
2472
2473
2474 /*--------------------------------------------------------------
2475 * WriteConsoleW
2476 */
2477 WINBASEAPI
2478 BOOL
2479 WINAPI
2480 WriteConsoleW(
2481 HANDLE hConsoleOutput,
2482 CONST VOID *lpBuffer,
2483 DWORD nNumberOfCharsToWrite,
2484 LPDWORD lpNumberOfCharsWritten,
2485 LPVOID lpReserved
2486 )
2487 {
2488 #if 0
2489 PCSRSS_API_REQUEST Request;
2490 CSRSS_API_REPLY Reply;
2491 NTSTATUS Status;
2492
2493 Request = RtlAllocateHeap(GetProcessHeap(),
2494 HEAP_ZERO_MEMORY,
2495 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
2496 if (Request == NULL)
2497 {
2498 SetLastError(ERROR_OUTOFMEMORY);
2499 return(FALSE);
2500 }
2501
2502 Request->Type = CSRSS_WRITE_CONSOLE;
2503 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
2504 Request->Data.WriteConsoleRequest.NrCharactersToWrite =
2505 nNumberOfCharsToWrite;
2506 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
2507 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
2508 memcpy(Request->Data.WriteConsoleRequest.Buffer,
2509 lpBuffer,
2510 nNumberOfCharsToWrite * sizeof(WCHAR));
2511
2512 Status = CsrClientCallServer(Request,
2513 &Reply,
2514 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
2515 sizeof(CSRSS_API_REPLY));
2516
2517 RtlFreeHeap(GetProcessHeap(),
2518 0,
2519 Request);
2520
2521 if (!NT_SUCCESS(Status))
2522 {
2523 return(FALSE);
2524 }
2525
2526 if (lpNumberOfCharsWritten != NULL)
2527 {
2528 *lpNumberOfCharsWritten =
2529 Reply.Data.WriteConsoleReply.NrCharactersWritten;
2530 }
2531
2532 return(TRUE);
2533 #endif
2534 return(FALSE);
2535 }
2536
2537
2538 /*--------------------------------------------------------------
2539 * CreateConsoleScreenBuffer
2540 */
2541 WINBASEAPI
2542 HANDLE
2543 WINAPI
2544 CreateConsoleScreenBuffer(
2545 DWORD dwDesiredAccess,
2546 DWORD dwShareMode,
2547 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
2548 DWORD dwFlags,
2549 LPVOID lpScreenBufferData
2550 )
2551 {
2552 // FIXME: don't ignore access, share mode, and security
2553 CSRSS_API_REQUEST Request;
2554 CSRSS_API_REPLY Reply;
2555 NTSTATUS Status;
2556
2557 Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
2558 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2559 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2560 {
2561 SetLastErrorByStatus ( Status );
2562 return FALSE;
2563 }
2564 return Reply.Data.CreateScreenBufferReply.OutputHandle;
2565 }
2566
2567
2568 /*--------------------------------------------------------------
2569 * GetConsoleCP
2570 */
2571 WINBASEAPI
2572 UINT
2573 WINAPI
2574 GetConsoleCP( VOID )
2575 {
2576 /* --- TO DO --- */
2577 return CP_OEMCP; /* FIXME */
2578 }
2579
2580
2581 /*--------------------------------------------------------------
2582 * SetConsoleCP
2583 */
2584 WINBASEAPI
2585 BOOL
2586 WINAPI
2587 SetConsoleCP(
2588 UINT wCodePageID
2589 )
2590 {
2591 /* --- TO DO --- */
2592 return FALSE;
2593 }
2594
2595
2596 /*--------------------------------------------------------------
2597 * GetConsoleOutputCP
2598 */
2599 WINBASEAPI
2600 UINT
2601 WINAPI
2602 GetConsoleOutputCP( VOID )
2603 {
2604 /* --- TO DO --- */
2605 return 0; /* FIXME */
2606 }
2607
2608
2609 /*--------------------------------------------------------------
2610 * SetConsoleOutputCP
2611 */
2612 WINBASEAPI
2613 BOOL
2614 WINAPI
2615 SetConsoleOutputCP(
2616 UINT wCodePageID
2617 )
2618 {
2619 /* --- TO DO --- */
2620 return FALSE;
2621 }
2622
2623
2624 /*--------------------------------------------------------------
2625 * GetConsoleProcessList
2626 */
2627 DWORD STDCALL
2628 GetConsoleProcessList(LPDWORD lpdwProcessList,
2629 DWORD dwProcessCount)
2630 {
2631 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2632 return 0;
2633 }
2634
2635
2636
2637 /*--------------------------------------------------------------
2638 * GetConsoleSelectionInfo
2639 */
2640 BOOL STDCALL
2641 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2642 {
2643 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2644 return FALSE;
2645 }
2646
2647
2648
2649 /*--------------------------------------------------------------
2650 * AttachConsole
2651 */
2652 BOOL STDCALL
2653 AttachConsole(DWORD dwProcessId)
2654 {
2655 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2656 return FALSE;
2657 }
2658
2659 /* EOF */