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