New console client support
[reactos.git] / reactos / lib / kernel32 / misc / console.c
1 /* $Id: console.c,v 1.26 2001/01/21 00:07:03 phreak 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 <ddk/ntddk.h>
17 #include <ddk/ntddblue.h>
18 #include <windows.h>
19 #include <assert.h>
20 #include <wchar.h>
21
22 #include <csrss/csrss.h>
23 #include <ntdll/csr.h>
24
25 #define NDEBUG
26 #include <kernel32/kernel32.h>
27 #include <kernel32/error.h>
28
29 /* FUNCTIONS *****************************************************************/
30
31 /*--------------------------------------------------------------
32 * CloseConsoleHandle
33 */
34 WINBOOL STDCALL CloseConsoleHandle(HANDLE Handle)
35 {
36 if (FALSE == IsConsoleHandle (Handle))
37 {
38 SetLastError (ERROR_INVALID_PARAMETER);
39 return FALSE;
40 }
41 /* FIXME: call CSRSS */
42 return FALSE;
43 }
44
45 /*--------------------------------------------------------------
46 * IsConsoleHandle
47 */
48 BOOLEAN STDCALL IsConsoleHandle(HANDLE Handle)
49 {
50 if ((((ULONG)Handle) & 0x10000003) == 0x3)
51 {
52 return(TRUE);
53 }
54 return(FALSE);
55 }
56
57
58 /*--------------------------------------------------------------
59 * GetStdHandle
60 */
61 HANDLE STDCALL GetStdHandle(DWORD nStdHandle)
62 {
63 PRTL_USER_PROCESS_PARAMETERS Ppb;
64
65 Ppb = NtCurrentPeb()->ProcessParameters;
66 switch (nStdHandle)
67 {
68 case STD_INPUT_HANDLE: return Ppb->InputHandle;
69 case STD_OUTPUT_HANDLE: return Ppb->OutputHandle;
70 case STD_ERROR_HANDLE: return Ppb->ErrorHandle;
71 }
72 SetLastError( ERROR_INVALID_PARAMETER );
73 return INVALID_HANDLE_VALUE;
74 }
75
76
77 /*--------------------------------------------------------------
78 * SetStdHandle
79 */
80 WINBASEAPI BOOL WINAPI SetStdHandle(DWORD nStdHandle,
81 HANDLE hHandle)
82 {
83 PRTL_USER_PROCESS_PARAMETERS Ppb;
84
85 Ppb = NtCurrentPeb()->ProcessParameters;
86
87 /* More checking needed? */
88 if (hHandle == INVALID_HANDLE_VALUE)
89 {
90 SetLastError( ERROR_INVALID_HANDLE );
91 return FALSE;
92 }
93
94 SetLastError(ERROR_SUCCESS); /* OK */
95 switch (nStdHandle)
96 {
97 case STD_INPUT_HANDLE:
98 Ppb->InputHandle = hHandle;
99 return TRUE;
100 case STD_OUTPUT_HANDLE:
101 Ppb->OutputHandle = hHandle;
102 return TRUE;
103 case STD_ERROR_HANDLE:
104 Ppb->ErrorHandle = hHandle;
105 return TRUE;
106 }
107 SetLastError( ERROR_INVALID_PARAMETER );
108 return FALSE;
109 }
110
111
112 /*--------------------------------------------------------------
113 * WriteConsoleA
114 */
115 WINBOOL STDCALL WriteConsoleA(HANDLE hConsoleOutput,
116 CONST VOID *lpBuffer,
117 DWORD nNumberOfCharsToWrite,
118 LPDWORD lpNumberOfCharsWritten,
119 LPVOID lpReserved)
120 {
121 PCSRSS_API_REQUEST Request;
122 CSRSS_API_REPLY Reply;
123 NTSTATUS Status;
124 WORD Size;
125
126 Request = HeapAlloc(GetProcessHeap(),
127 HEAP_ZERO_MEMORY,
128 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_REQUEST);
129 if (Request == NULL)
130 {
131 return(FALSE);
132 }
133
134 Request->Type = CSRSS_WRITE_CONSOLE;
135 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
136 if (lpNumberOfCharsWritten != NULL)
137 *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
138 while( nNumberOfCharsToWrite )
139 {
140 Size = nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST ? CSRSS_MAX_WRITE_CONSOLE_REQUEST : nNumberOfCharsToWrite;
141
142 Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
143
144 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
145 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
146
147 memcpy( Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size );
148
149 Status = CsrClientCallServer(Request,
150 &Reply,
151 sizeof(CSRSS_WRITE_CONSOLE_REQUEST) +
152 Size,
153 sizeof(CSRSS_API_REPLY));
154
155 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
156 {
157 HeapFree( GetProcessHeap(), 0, Request );
158 SetLastErrorByStatus (Status);
159 return(FALSE);
160 }
161 nNumberOfCharsToWrite -= Size;
162 lpBuffer += Size;
163 }
164 HeapFree( GetProcessHeap(), 0, Request );
165 return TRUE;
166 }
167
168
169 /*--------------------------------------------------------------
170 * ReadConsoleA
171 */
172 WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
173 LPVOID lpBuffer,
174 DWORD nNumberOfCharsToRead,
175 LPDWORD lpNumberOfCharsRead,
176 LPVOID lpReserved)
177 {
178 CSRSS_API_REQUEST Request;
179 PCSRSS_API_REPLY Reply;
180 NTSTATUS Status;
181 ULONG CharsRead = 0;
182
183 Reply = HeapAlloc(GetProcessHeap(),
184 HEAP_ZERO_MEMORY,
185 sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
186 if (Reply == NULL)
187 {
188 return(FALSE);
189 }
190
191 Request.Type = CSRSS_READ_CONSOLE;
192 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
193 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
194 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
195 Status = CsrClientCallServer(&Request,
196 Reply,
197 sizeof(CSRSS_API_REQUEST),
198 sizeof(CSRSS_API_REPLY) +
199 Request.Data.ReadConsoleRequest.NrCharactersToRead);
200 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
201 {
202 DbgPrint( "CSR returned error in ReadConsole\n" );
203 SetLastErrorByStatus ( Status );
204 HeapFree( GetProcessHeap(), 0, Reply );
205 return(FALSE);
206 }
207 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
208 Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
209 /* There may not be any chars or lines to read yet, so wait */
210 while( Reply->Status == STATUS_PENDING )
211 {
212 /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
213 nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
214 /* don't overflow caller's buffer, even if you still don't have a complete line */
215 if( !nNumberOfCharsToRead )
216 break;
217 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
218 /* copy any chars already read to buffer */
219 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
220 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
221 /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
222 Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
223 if( !NT_SUCCESS( Status ) )
224 {
225 DbgPrint( "Wait for console input failed!\n" );
226 HeapFree( GetProcessHeap(), 0, Reply );
227 return FALSE;
228 }
229 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
230 Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
231 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
232 {
233 SetLastErrorByStatus ( Status );
234 HeapFree( GetProcessHeap(), 0, Reply );
235 return FALSE;
236 }
237 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
238 {
239 // delete last char
240 if( CharsRead )
241 {
242 CharsRead--;
243 nNumberOfCharsToRead++;
244 }
245 Reply->Status = STATUS_PENDING; // retry
246 }
247 }
248 /* copy data to buffer, count total returned, and return */
249 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
250 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
251 if (lpNumberOfCharsRead != NULL)
252 *lpNumberOfCharsRead = CharsRead;
253 HeapFree(GetProcessHeap(),
254 0,
255 Reply);
256
257 return(TRUE);
258 }
259
260
261 /*--------------------------------------------------------------
262 * AllocConsole
263 */
264 WINBOOL STDCALL AllocConsole(VOID)
265 {
266 CSRSS_API_REQUEST Request;
267 CSRSS_API_REPLY Reply;
268 NTSTATUS Status;
269
270 Request.Type = CSRSS_ALLOC_CONSOLE;
271 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
272 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
273 {
274 SetLastErrorByStatus ( Status );
275 return FALSE;
276 }
277 SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
278 SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
279 SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
280 return TRUE;
281 }
282
283
284 /*--------------------------------------------------------------
285 * FreeConsole
286 */
287 WINBOOL STDCALL FreeConsole(VOID)
288 {
289 DbgPrint("FreeConsole() is unimplemented");
290 return FALSE;
291 }
292
293
294 /*--------------------------------------------------------------
295 * GetConsoleScreenBufferInfo
296 */
297 WINBOOL
298 STDCALL
299 GetConsoleScreenBufferInfo(
300 HANDLE hConsoleOutput,
301 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
302 )
303 {
304 CSRSS_API_REQUEST Request;
305 CSRSS_API_REPLY Reply;
306 NTSTATUS Status;
307
308 Request.Type = CSRSS_SCREEN_BUFFER_INFO;
309 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
310 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
311 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
312 {
313 SetLastErrorByStatus ( Status );
314 return FALSE;
315 }
316 *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
317 return TRUE;
318 }
319
320
321 /*--------------------------------------------------------------
322 * SetConsoleCursorPosition
323 */
324 WINBOOL
325 STDCALL
326 SetConsoleCursorPosition(
327 HANDLE hConsoleOutput,
328 COORD dwCursorPosition
329 )
330 {
331 CSRSS_API_REQUEST Request;
332 CSRSS_API_REPLY Reply;
333 NTSTATUS Status;
334
335 Request.Type = CSRSS_SET_CURSOR;
336 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
337 Request.Data.SetCursorRequest.Position = dwCursorPosition;
338 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
339 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
340 {
341 SetLastErrorByStatus ( Status );
342 return FALSE;
343 }
344 return TRUE;
345 }
346
347
348 /*--------------------------------------------------------------
349 * FillConsoleOutputCharacterA
350 */
351 WINBOOL
352 STDCALL
353 FillConsoleOutputCharacterA(
354 HANDLE hConsoleOutput,
355 CHAR cCharacter,
356 DWORD nLength,
357 COORD dwWriteCoord,
358 LPDWORD lpNumberOfCharsWritten
359 )
360 {
361 CSRSS_API_REQUEST Request;
362 CSRSS_API_REPLY Reply;
363 NTSTATUS Status;
364
365 Request.Type = CSRSS_FILL_OUTPUT;
366 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
367 Request.Data.FillOutputRequest.Char = cCharacter;
368 Request.Data.FillOutputRequest.Position = dwWriteCoord;
369 Request.Data.FillOutputRequest.Length = nLength;
370 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
371 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
372 {
373 SetLastErrorByStatus ( Status );
374 return FALSE;
375 }
376 *lpNumberOfCharsWritten = nLength;
377 return TRUE;
378 }
379
380
381 /*--------------------------------------------------------------
382 * FillConsoleOutputCharacterW
383 */
384 WINBOOL
385 STDCALL
386 FillConsoleOutputCharacterW(
387 HANDLE hConsoleOutput,
388 WCHAR cCharacter,
389 DWORD nLength,
390 COORD dwWriteCoord,
391 LPDWORD lpNumberOfCharsWritten
392 )
393 {
394 /* TO DO */
395 return FALSE;
396 }
397
398
399 /*--------------------------------------------------------------
400 * PeekConsoleInputA
401 */
402 WINBASEAPI
403 BOOL
404 WINAPI
405 PeekConsoleInputA(
406 HANDLE hConsoleInput,
407 PINPUT_RECORD lpBuffer,
408 DWORD nLength,
409 LPDWORD lpNumberOfEventsRead
410 )
411 {
412 /* TO DO */
413 return FALSE;
414 }
415
416
417 /*--------------------------------------------------------------
418 * PeekConsoleInputW
419 */
420 WINBASEAPI
421 BOOL
422 WINAPI
423 PeekConsoleInputW(
424 HANDLE hConsoleInput,
425 PINPUT_RECORD lpBuffer,
426 DWORD nLength,
427 LPDWORD lpNumberOfEventsRead
428 )
429 {
430 /* TO DO */
431 return FALSE;
432 }
433
434
435 /*--------------------------------------------------------------
436 * ReadConsoleInputA
437 */
438 WINBASEAPI
439 BOOL
440 WINAPI
441 ReadConsoleInputA(
442 HANDLE hConsoleInput,
443 PINPUT_RECORD lpBuffer,
444 DWORD nLength,
445 LPDWORD lpNumberOfEventsRead
446 )
447 {
448 CSRSS_API_REQUEST Request;
449 CSRSS_API_REPLY Reply;
450 NTSTATUS Status;
451
452 Request.Type = CSRSS_READ_INPUT;
453 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
454 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
455 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
456 {
457 SetLastErrorByStatus ( Status );
458 return FALSE;
459 }
460 while( Status == STATUS_PENDING )
461 {
462 Status = NtWaitForSingleObject( Reply.Data.ReadInputReply.Event, FALSE, 0 );
463 if( !NT_SUCCESS( Status ) )
464 {
465 SetLastErrorByStatus ( Status );
466 return FALSE;
467 }
468 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
469 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
470 {
471 SetLastErrorByStatus ( Status );
472 return FALSE;
473 }
474 }
475 *lpNumberOfEventsRead = 1;
476 *lpBuffer = Reply.Data.ReadInputReply.Input;
477 return TRUE;
478 }
479
480
481 /*--------------------------------------------------------------
482 * ReadConsoleInputW
483 */
484 WINBASEAPI
485 BOOL
486 WINAPI
487 ReadConsoleInputW(
488 HANDLE hConsoleInput,
489 PINPUT_RECORD lpBuffer,
490 DWORD nLength,
491 LPDWORD lpNumberOfEventsRead
492 )
493 {
494 /* TO DO */
495 return FALSE;
496 }
497
498
499 /*--------------------------------------------------------------
500 * WriteConsoleInputA
501 */
502 WINBASEAPI
503 BOOL
504 WINAPI
505 WriteConsoleInputA(
506 HANDLE hConsoleInput,
507 CONST INPUT_RECORD *lpBuffer,
508 DWORD nLength,
509 LPDWORD lpNumberOfEventsWritten
510 )
511 {
512 /* TO DO */
513 return FALSE;
514 }
515
516
517 /*--------------------------------------------------------------
518 * WriteConsoleInputW
519 */
520 WINBASEAPI
521 BOOL
522 WINAPI
523 WriteConsoleInputW(
524 HANDLE hConsoleInput,
525 CONST INPUT_RECORD *lpBuffer,
526 DWORD nLength,
527 LPDWORD lpNumberOfEventsWritten
528 )
529 {
530 /* TO DO */
531 return FALSE;
532 }
533
534
535 /*--------------------------------------------------------------
536 * ReadConsoleOutputA
537 */
538 WINBASEAPI
539 BOOL
540 WINAPI
541 ReadConsoleOutputA(
542 HANDLE hConsoleOutput,
543 PCHAR_INFO lpBuffer,
544 COORD dwBufferSize,
545 COORD dwBufferCoord,
546 PSMALL_RECT lpReadRegion
547 )
548 {
549 /* TO DO */
550 return FALSE;
551 }
552
553
554 /*--------------------------------------------------------------
555 * ReadConsoleOutputW
556 */
557 WINBASEAPI
558 BOOL
559 WINAPI
560 ReadConsoleOutputW(
561 HANDLE hConsoleOutput,
562 PCHAR_INFO lpBuffer,
563 COORD dwBufferSize,
564 COORD dwBufferCoord,
565 PSMALL_RECT lpReadRegion
566 )
567 {
568 /* TO DO */
569 return FALSE;
570 }
571
572 /*--------------------------------------------------------------
573 * WriteConsoleOutputA
574 */
575 WINBASEAPI
576 BOOL
577 WINAPI
578 WriteConsoleOutputA(
579 HANDLE hConsoleOutput,
580 CONST CHAR_INFO *lpBuffer,
581 COORD dwBufferSize,
582 COORD dwBufferCoord,
583 PSMALL_RECT lpWriteRegion
584 )
585 {
586 /* TO DO */
587 return FALSE;
588 }
589
590
591 /*--------------------------------------------------------------
592 * WriteConsoleOutputW
593 */
594 WINBASEAPI
595 BOOL
596 WINAPI
597 WriteConsoleOutputW(
598 HANDLE hConsoleOutput,
599 CONST CHAR_INFO *lpBuffer,
600 COORD dwBufferSize,
601 COORD dwBufferCoord,
602 PSMALL_RECT lpWriteRegion
603 )
604 {
605 /* TO DO */
606 return FALSE;
607 }
608
609
610 /*--------------------------------------------------------------
611 * ReadConsoleOutputCharacterA
612 */
613 WINBASEAPI
614 BOOL
615 WINAPI
616 ReadConsoleOutputCharacterA(
617 HANDLE hConsoleOutput,
618 LPSTR lpCharacter,
619 DWORD nLength,
620 COORD dwReadCoord,
621 LPDWORD lpNumberOfCharsRead
622 )
623 {
624 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
625 return FALSE;
626 }
627
628
629 /*--------------------------------------------------------------
630 * ReadConsoleOutputCharacterW
631 */
632 WINBASEAPI
633 BOOL
634 WINAPI
635 ReadConsoleOutputCharacterW(
636 HANDLE hConsoleOutput,
637 LPWSTR lpCharacter,
638 DWORD nLength,
639 COORD dwReadCoord,
640 LPDWORD lpNumberOfCharsRead
641 )
642 {
643 /* TO DO */
644 return FALSE;
645 }
646
647
648 /*--------------------------------------------------------------
649 * ReadConsoleOutputAttribute
650 */
651 WINBASEAPI
652 BOOL
653 WINAPI
654 ReadConsoleOutputAttribute(
655 HANDLE hConsoleOutput,
656 LPWORD lpAttribute,
657 DWORD nLength,
658 COORD dwReadCoord,
659 LPDWORD lpNumberOfAttrsRead
660 )
661 {
662 SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
663 return FALSE;
664 }
665
666
667 /*--------------------------------------------------------------
668 * WriteConsoleOutputCharacterA
669 */
670 WINBASEAPI
671 BOOL
672 WINAPI
673 WriteConsoleOutputCharacterA(
674 HANDLE hConsoleOutput,
675 LPCSTR lpCharacter,
676 DWORD nLength,
677 COORD dwWriteCoord,
678 LPDWORD lpNumberOfCharsWritten
679 )
680 {
681 CSRSS_API_REQUEST Request;
682 CSRSS_API_REPLY Reply;
683 NTSTATUS Status;
684 WORD Size;
685
686 Request.Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
687 Request.Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
688 Request.Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
689 if( lpNumberOfCharsWritten )
690 *lpNumberOfCharsWritten = nLength;
691 while( nLength )
692 {
693 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
694 Request.Data.WriteConsoleOutputCharRequest.Length = Size;
695
696 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
697 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
698 {
699 SetLastErrorByStatus ( Status );
700 return FALSE;
701 }
702 nLength -= Size;
703 lpCharacter += Size;
704 Request.Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
705 }
706 return TRUE;
707 }
708
709
710 /*--------------------------------------------------------------
711 * WriteConsoleOutputCharacterW
712 */
713 WINBASEAPI
714 BOOL
715 WINAPI
716 WriteConsoleOutputCharacterW(
717 HANDLE hConsoleOutput,
718 LPCWSTR lpCharacter,
719 DWORD nLength,
720 COORD dwWriteCoord,
721 LPDWORD lpNumberOfCharsWritten
722 )
723 {
724 /* TO DO */
725 return FALSE;
726 }
727
728
729
730 /*--------------------------------------------------------------
731 * WriteConsoleOutputAttribute
732 */
733 WINBASEAPI
734 BOOL
735 WINAPI
736 WriteConsoleOutputAttribute(
737 HANDLE hConsoleOutput,
738 CONST WORD *lpAttribute,
739 DWORD nLength,
740 COORD dwWriteCoord,
741 LPDWORD lpNumberOfAttrsWritten
742 )
743 {
744 CSRSS_API_REQUEST Request;
745 CSRSS_API_REPLY Reply;
746 NTSTATUS Status;
747 WORD Size;
748 int c;
749
750 Request.Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
751 Request.Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
752 Request.Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
753 if( lpNumberOfAttrsWritten )
754 *lpNumberOfAttrsWritten = nLength;
755 while( nLength )
756 {
757 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
758 Request.Data.WriteConsoleOutputAttribRequest.Length = Size;
759 for( c = 0; c < Size; c++ )
760 Request.Data.WriteConsoleOutputAttribRequest.String[c] = lpAttribute[c];
761 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
762 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
763 {
764 SetLastErrorByStatus ( Status );
765 return FALSE;
766 }
767 nLength -= Size;
768 lpAttribute += Size;
769 Request.Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
770 }
771 return TRUE;
772 }
773
774
775 /*--------------------------------------------------------------
776 * FillConsoleOutputAttribute
777 */
778 WINBASEAPI
779 BOOL
780 WINAPI
781 FillConsoleOutputAttribute(
782 HANDLE hConsoleOutput,
783 WORD wAttribute,
784 DWORD nLength,
785 COORD dwWriteCoord,
786 LPDWORD lpNumberOfAttrsWritten
787 )
788 {
789 CSRSS_API_REQUEST Request;
790 CSRSS_API_REPLY Reply;
791 NTSTATUS Status;
792
793 Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
794 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
795 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
796 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
797 Request.Data.FillOutputAttribRequest.Length = nLength;
798 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
799 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
800 {
801 SetLastErrorByStatus ( Status );
802 return FALSE;
803 }
804 if( lpNumberOfAttrsWritten )
805 *lpNumberOfAttrsWritten = nLength;
806 return TRUE;
807 }
808
809
810 /*--------------------------------------------------------------
811 * GetConsoleMode
812 */
813 WINBASEAPI
814 BOOL
815 WINAPI
816 GetConsoleMode(
817 HANDLE hConsoleHandle,
818 LPDWORD lpMode
819 )
820 {
821 CSRSS_API_REQUEST Request;
822 CSRSS_API_REPLY Reply;
823 NTSTATUS Status;
824
825 Request.Type = CSRSS_GET_MODE;
826 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
827 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
828 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
829 {
830 SetLastErrorByStatus ( Status );
831 return FALSE;
832 }
833 *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
834 return TRUE;
835 }
836
837
838 /*--------------------------------------------------------------
839 * GetNumberOfConsoleInputEvents
840 */
841 WINBASEAPI
842 BOOL
843 WINAPI
844 GetNumberOfConsoleInputEvents(
845 HANDLE hConsoleInput,
846 LPDWORD lpNumberOfEvents
847 )
848 {
849 /* TO DO */
850 return FALSE;
851 }
852
853
854 /*--------------------------------------------------------------
855 * GetLargestConsoleWindowSize
856 */
857 WINBASEAPI
858 COORD
859 WINAPI
860 GetLargestConsoleWindowSize(
861 HANDLE hConsoleOutput
862 )
863 {
864 #if 1 /* FIXME: */
865 COORD Coord = {80,25};
866
867 /* TO DO */
868 return Coord;
869 #endif
870 }
871
872
873 /*--------------------------------------------------------------
874 * GetConsoleCursorInfo
875 */
876 WINBASEAPI
877 BOOL
878 WINAPI
879 GetConsoleCursorInfo(
880 HANDLE hConsoleOutput,
881 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
882 )
883 {
884 CSRSS_API_REQUEST Request;
885 CSRSS_API_REPLY Reply;
886 NTSTATUS Status;
887
888 Request.Type = CSRSS_GET_CURSOR_INFO;
889 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
890 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
891 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
892 {
893 SetLastErrorByStatus ( Status );
894 return FALSE;
895 }
896 *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
897 return TRUE;
898 }
899
900
901 /*--------------------------------------------------------------
902 * GetNumberOfConsoleMouseButtons
903 */
904 WINBASEAPI
905 BOOL
906 WINAPI
907 GetNumberOfConsoleMouseButtons(
908 LPDWORD lpNumberOfMouseButtons
909 )
910 {
911 /* TO DO */
912 return FALSE;
913 }
914
915
916 /*--------------------------------------------------------------
917 * SetConsoleMode
918 */
919 WINBASEAPI
920 BOOL
921 WINAPI
922 SetConsoleMode(
923 HANDLE hConsoleHandle,
924 DWORD dwMode
925 )
926 {
927 CSRSS_API_REQUEST Request;
928 CSRSS_API_REPLY Reply;
929 NTSTATUS Status;
930
931 Request.Type = CSRSS_SET_MODE;
932 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
933 Request.Data.SetConsoleModeRequest.Mode = dwMode;
934 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
935 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
936 {
937 SetLastErrorByStatus ( Status );
938 return FALSE;
939 }
940 return TRUE;
941 }
942
943
944 /*--------------------------------------------------------------
945 * SetConsoleActiveScreenBuffer
946 */
947 WINBASEAPI
948 BOOL
949 WINAPI
950 SetConsoleActiveScreenBuffer(
951 HANDLE hConsoleOutput
952 )
953 {
954 CSRSS_API_REQUEST Request;
955 CSRSS_API_REPLY Reply;
956 NTSTATUS Status;
957
958 Request.Type = CSRSS_SET_SCREEN_BUFFER;
959 Request.Data.SetActiveScreenBufferRequest.OutputHandle = hConsoleOutput;
960 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
961 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
962 {
963 SetLastErrorByStatus ( Status );
964 return FALSE;
965 }
966 return TRUE;
967 }
968
969
970 /*--------------------------------------------------------------
971 * FlushConsoleInputBuffer
972 */
973 WINBASEAPI
974 BOOL
975 WINAPI
976 FlushConsoleInputBuffer(
977 HANDLE hConsoleInput
978 )
979 {
980 /* TO DO */
981 return FALSE;
982 }
983
984
985 /*--------------------------------------------------------------
986 * SetConsoleScreenBufferSize
987 */
988 WINBASEAPI
989 BOOL
990 WINAPI
991 SetConsoleScreenBufferSize(
992 HANDLE hConsoleOutput,
993 COORD dwSize
994 )
995 {
996 /* TO DO */
997 return FALSE;
998 }
999
1000 /*--------------------------------------------------------------
1001 * SetConsoleCursorInfo
1002 */
1003 WINBASEAPI
1004 BOOL
1005 WINAPI
1006 SetConsoleCursorInfo(
1007 HANDLE hConsoleOutput,
1008 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
1009 )
1010 {
1011 CSRSS_API_REQUEST Request;
1012 CSRSS_API_REPLY Reply;
1013 NTSTATUS Status;
1014
1015 Request.Type = CSRSS_SET_CURSOR_INFO;
1016 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
1017 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
1018 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1019 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1020 {
1021 SetLastErrorByStatus ( Status );
1022 return FALSE;
1023 }
1024 return TRUE;
1025 }
1026
1027
1028 /*--------------------------------------------------------------
1029 * ScrollConsoleScreenBufferA
1030 */
1031 WINBASEAPI
1032 BOOL
1033 WINAPI
1034 ScrollConsoleScreenBufferA(
1035 HANDLE hConsoleOutput,
1036 CONST SMALL_RECT *lpScrollRectangle,
1037 CONST SMALL_RECT *lpClipRectangle,
1038 COORD dwDestinationOrigin,
1039 CONST CHAR_INFO *lpFill
1040 )
1041 {
1042 /* TO DO */
1043 return FALSE;
1044 }
1045
1046
1047 /*--------------------------------------------------------------
1048 * ScrollConsoleScreenBufferW
1049 */
1050 WINBASEAPI
1051 BOOL
1052 WINAPI
1053 ScrollConsoleScreenBufferW(
1054 HANDLE hConsoleOutput,
1055 CONST SMALL_RECT *lpScrollRectangle,
1056 CONST SMALL_RECT *lpClipRectangle,
1057 COORD dwDestinationOrigin,
1058 CONST CHAR_INFO *lpFill
1059 )
1060 {
1061 /* TO DO */
1062 return FALSE;
1063 }
1064
1065
1066 /*--------------------------------------------------------------
1067 * SetConsoleWindowInfo
1068 */
1069 WINBASEAPI
1070 BOOL
1071 WINAPI
1072 SetConsoleWindowInfo(
1073 HANDLE hConsoleOutput,
1074 BOOL bAbsolute,
1075 CONST SMALL_RECT *lpConsoleWindow
1076 )
1077 {
1078 /* TO DO */
1079 return FALSE;
1080 }
1081
1082
1083 /*--------------------------------------------------------------
1084 * SetConsoleTextAttribute
1085 */
1086 WINBASEAPI
1087 BOOL
1088 WINAPI
1089 SetConsoleTextAttribute(
1090 HANDLE hConsoleOutput,
1091 WORD wAttributes
1092 )
1093 {
1094 CSRSS_API_REQUEST Request;
1095 CSRSS_API_REPLY Reply;
1096 NTSTATUS Status;
1097
1098 Request.Type = CSRSS_SET_ATTRIB;
1099 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
1100 Request.Data.SetAttribRequest.Attrib = wAttributes;
1101 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1102 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1103 {
1104 SetLastErrorByStatus ( Status );
1105 return FALSE;
1106 }
1107 return TRUE;
1108 }
1109
1110
1111 /*--------------------------------------------------------------
1112 * SetConsoleCtrlHandler
1113 */
1114 WINBASEAPI
1115 BOOL
1116 WINAPI
1117 SetConsoleCtrlHandler(
1118 PHANDLER_ROUTINE HandlerRoutine,
1119 BOOL Add
1120 )
1121 {
1122 /* TO DO */
1123 return FALSE;
1124 }
1125
1126
1127 /*--------------------------------------------------------------
1128 * GenerateConsoleCtrlEvent
1129 */
1130 WINBASEAPI
1131 BOOL
1132 WINAPI
1133 GenerateConsoleCtrlEvent(
1134 DWORD dwCtrlEvent,
1135 DWORD dwProcessGroupId
1136 )
1137 {
1138 /* TO DO */
1139 return FALSE;
1140 }
1141
1142
1143 /*--------------------------------------------------------------
1144 * GetConsoleTitleW
1145 */
1146 #define MAX_CONSOLE_TITLE_LENGTH 80
1147
1148 WINBASEAPI
1149 DWORD
1150 WINAPI
1151 GetConsoleTitleW(
1152 LPWSTR lpConsoleTitle,
1153 DWORD nSize
1154 )
1155 {
1156 /* TO DO */
1157 return 0;
1158 }
1159
1160
1161 /*--------------------------------------------------------------
1162 * GetConsoleTitleA
1163 *
1164 * 19990306 EA
1165 */
1166 WINBASEAPI
1167 DWORD
1168 WINAPI
1169 GetConsoleTitleA(
1170 LPSTR lpConsoleTitle,
1171 DWORD nSize
1172 )
1173 {
1174 wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
1175 DWORD nWideTitle = sizeof WideTitle;
1176 // DWORD nWritten;
1177
1178 if (!lpConsoleTitle || !nSize) return 0;
1179 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
1180 if (!nWideTitle) return 0;
1181 #if 0
1182 if ( (nWritten = WideCharToMultiByte(
1183 CP_ACP, // ANSI code page
1184 0, // performance and mapping flags
1185 (LPWSTR) WideTitle, // address of wide-character string
1186 nWideTitle, // number of characters in string
1187 lpConsoleTitle, // address of buffer for new string
1188 nSize, // size of buffer
1189 NULL, // FAST
1190 NULL // FAST
1191 )))
1192 {
1193 lpConsoleTitle[nWritten] = '\0';
1194 return nWritten;
1195 }
1196 #endif
1197 return 0;
1198 }
1199
1200
1201 /*--------------------------------------------------------------
1202 * SetConsoleTitleW
1203 */
1204 WINBASEAPI
1205 BOOL
1206 WINAPI
1207 SetConsoleTitleW(
1208 LPCWSTR lpConsoleTitle
1209 )
1210 {
1211 /* --- TO DO --- */
1212 return FALSE;
1213 }
1214
1215
1216 /*--------------------------------------------------------------
1217 * SetConsoleTitleA
1218 *
1219 * 19990204 EA Added
1220 */
1221 WINBASEAPI
1222 BOOL
1223 WINAPI
1224 SetConsoleTitleA(
1225 LPCSTR lpConsoleTitle
1226 )
1227 {
1228 wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
1229 char AnsiTitle [MAX_CONSOLE_TITLE_LENGTH];
1230 INT nWideTitle;
1231
1232 if (!lpConsoleTitle) return FALSE;
1233 ZeroMemory( WideTitle, sizeof WideTitle );
1234 nWideTitle = lstrlenA(lpConsoleTitle);
1235 if (!lstrcpynA(
1236 AnsiTitle,
1237 lpConsoleTitle,
1238 nWideTitle
1239 ))
1240 {
1241 return FALSE;
1242 }
1243 AnsiTitle[nWideTitle] = '\0';
1244 #if 0
1245 if ( MultiByteToWideChar(
1246 CP_ACP, // ANSI code page
1247 MB_PRECOMPOSED, // character-type options
1248 AnsiTitle, // address of string to map
1249 nWideTitle, // number of characters in string
1250 (LPWSTR) WideTitle, // address of wide-character buffer
1251 (-1) // size of buffer: -1=...\0
1252 ))
1253 {
1254 return SetConsoleTitleW( (LPWSTR) WideTitle );
1255 }
1256 #endif
1257 return FALSE;
1258 }
1259
1260
1261 /*--------------------------------------------------------------
1262 * ReadConsoleW
1263 */
1264 WINBASEAPI
1265 BOOL
1266 WINAPI
1267 ReadConsoleW(
1268 HANDLE hConsoleInput,
1269 LPVOID lpBuffer,
1270 DWORD nNumberOfCharsToRead,
1271 LPDWORD lpNumberOfCharsRead,
1272 LPVOID lpReserved
1273 )
1274 {
1275 /* --- TO DO --- */
1276 return FALSE;
1277 }
1278
1279
1280 /*--------------------------------------------------------------
1281 * WriteConsoleW
1282 */
1283 WINBASEAPI
1284 BOOL
1285 WINAPI
1286 WriteConsoleW(
1287 HANDLE hConsoleOutput,
1288 CONST VOID *lpBuffer,
1289 DWORD nNumberOfCharsToWrite,
1290 LPDWORD lpNumberOfCharsWritten,
1291 LPVOID lpReserved
1292 )
1293 {
1294 #if 0
1295 PCSRSS_API_REQUEST Request;
1296 CSRSS_API_REPLY Reply;
1297 NTSTATUS Status;
1298
1299 Request = HeapAlloc(GetProcessHeap(),
1300 HEAP_ZERO_MEMORY,
1301 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
1302 if (Request == NULL)
1303 {
1304 return(FALSE);
1305 }
1306
1307 Request->Type = CSRSS_WRITE_CONSOLE;
1308 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1309 Request->Data.WriteConsoleRequest.NrCharactersToWrite =
1310 nNumberOfCharsToWrite;
1311 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
1312 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
1313 memcpy(Request->Data.WriteConsoleRequest.Buffer,
1314 lpBuffer,
1315 nNumberOfCharsToWrite * sizeof(WCHAR));
1316
1317 Status = CsrClientCallServer(Request,
1318 &Reply,
1319 sizeof(CSRSS_API_REQUEST) +
1320 nNumberOfCharsToWrite,
1321 sizeof(CSRSS_API_REPLY));
1322
1323 HeapFree(GetProcessHeap(),
1324 0,
1325 Request);
1326
1327 if (!NT_SUCCESS(Status))
1328 {
1329 return(FALSE);
1330 }
1331
1332 if (lpNumberOfCharsWritten != NULL)
1333 {
1334 *lpNumberOfCharsWritten =
1335 Reply.Data.WriteConsoleReply.NrCharactersWritten;
1336 }
1337
1338 return(TRUE);
1339 #endif
1340 return FALSE;
1341 }
1342
1343
1344 /*--------------------------------------------------------------
1345 * CreateConsoleScreenBuffer
1346 */
1347 WINBASEAPI
1348 HANDLE
1349 WINAPI
1350 CreateConsoleScreenBuffer(
1351 DWORD dwDesiredAccess,
1352 DWORD dwShareMode,
1353 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1354 DWORD dwFlags,
1355 LPVOID lpScreenBufferData
1356 )
1357 {
1358 // FIXME: don't ignore access, share mode, and security
1359 CSRSS_API_REQUEST Request;
1360 CSRSS_API_REPLY Reply;
1361 NTSTATUS Status;
1362
1363 Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
1364 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1365 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1366 {
1367 SetLastErrorByStatus ( Status );
1368 return FALSE;
1369 }
1370 return Reply.Data.CreateScreenBufferReply.OutputHandle;
1371 }
1372
1373
1374 /*--------------------------------------------------------------
1375 * GetConsoleCP
1376 */
1377 WINBASEAPI
1378 UINT
1379 WINAPI
1380 GetConsoleCP( VOID )
1381 {
1382 /* --- TO DO --- */
1383 return CP_OEMCP; /* FIXME */
1384 }
1385
1386
1387 /*--------------------------------------------------------------
1388 * SetConsoleCP
1389 */
1390 WINBASEAPI
1391 BOOL
1392 WINAPI
1393 SetConsoleCP(
1394 UINT wCodePageID
1395 )
1396 {
1397 /* --- TO DO --- */
1398 return FALSE;
1399 }
1400
1401
1402 /*--------------------------------------------------------------
1403 * GetConsoleOutputCP
1404 */
1405 WINBASEAPI
1406 UINT
1407 WINAPI
1408 GetConsoleOutputCP( VOID )
1409 {
1410 /* --- TO DO --- */
1411 return 0; /* FIXME */
1412 }
1413
1414
1415 /*--------------------------------------------------------------
1416 * SetConsoleOutputCP
1417 */
1418 WINBASEAPI
1419 BOOL
1420 WINAPI
1421 SetConsoleOutputCP(
1422 UINT wCodePageID
1423 )
1424 {
1425 /* --- TO DO --- */
1426 return FALSE;
1427 }
1428
1429
1430 /* EOF */