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