657196dca34a060a928e981c11db231f908e51c1
[reactos.git] / reactos / 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 * PROGRAMMERS: James Tabor
7 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <k32.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17
18 /* GLOBALS ********************************************************************/
19
20 extern RTL_CRITICAL_SECTION ConsoleLock;
21 extern BOOL ConsoleInitialized;
22 extern BOOL WINAPI IsDebuggerPresent(VOID);
23
24 /* Console reserved "file" names */
25 static LPCWSTR BaseConFileName = CONSOLE_FILE_NAME;
26 static LPCWSTR BaseConInputFileName = CONSOLE_INPUT_FILE_NAME;
27 static LPCWSTR BaseConOutputFileName = CONSOLE_OUTPUT_FILE_NAME;
28
29 PHANDLER_ROUTINE InitialHandler[1];
30 PHANDLER_ROUTINE* CtrlHandlers;
31 ULONG NrCtrlHandlers;
32 ULONG NrAllocatedHandlers;
33
34 HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
35
36 #define INPUTEXENAME_BUFLEN 256
37 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
38
39
40 /* Default Console Control Handler ********************************************/
41
42 BOOL
43 WINAPI
44 DefaultConsoleCtrlHandler(DWORD Event)
45 {
46 DPRINT("Default handler called: %lx\n", Event);
47 switch(Event)
48 {
49 case CTRL_C_EVENT:
50 DPRINT("Ctrl-C Event\n");
51 break;
52
53 case CTRL_BREAK_EVENT:
54 DPRINT("Ctrl-Break Event\n");
55 break;
56
57 case CTRL_CLOSE_EVENT:
58 DPRINT("Ctrl Close Event\n");
59 break;
60
61 case CTRL_LOGOFF_EVENT:
62 DPRINT("Ctrl Logoff Event\n");
63 break;
64
65 case CTRL_SHUTDOWN_EVENT:
66 DPRINT("Ctrl Shutdown Event\n");
67 break;
68 }
69
70 ExitProcess(CONTROL_C_EXIT);
71 return TRUE;
72 }
73
74 DWORD
75 WINAPI
76 ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
77 {
78 DWORD nExitCode = 0;
79 DWORD CodeAndFlag = PtrToUlong(lpThreadParameter);
80 DWORD nCode = CodeAndFlag & MAXLONG;
81 UINT i;
82 EXCEPTION_RECORD erException;
83
84 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
85 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
86
87 switch(nCode)
88 {
89 case CTRL_C_EVENT:
90 case CTRL_BREAK_EVENT:
91 {
92 if (IsDebuggerPresent())
93 {
94 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
95 DBG_CONTROL_C : DBG_CONTROL_BREAK);
96 erException.ExceptionFlags = 0;
97 erException.ExceptionRecord = NULL;
98 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
99 erException.NumberParameters = 0;
100
101 _SEH2_TRY
102 {
103 RtlRaiseException(&erException);
104 }
105 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
106 {
107 RtlEnterCriticalSection(&ConsoleLock);
108
109 if ((nCode != CTRL_C_EVENT) ||
110 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
111 {
112 for (i = NrCtrlHandlers; i > 0; i--)
113 {
114 if (CtrlHandlers[i - 1](nCode)) break;
115 }
116 }
117
118 RtlLeaveCriticalSection(&ConsoleLock);
119 }
120 _SEH2_END;
121
122 ExitThread(0);
123 }
124 break;
125 }
126
127 case CTRL_CLOSE_EVENT:
128 case CTRL_LOGOFF_EVENT:
129 case CTRL_SHUTDOWN_EVENT:
130 break;
131
132 case 3:
133 ExitThread(0);
134 break;
135
136 case 4:
137 ExitProcess(CONTROL_C_EXIT);
138 break;
139
140 default:
141 ASSERT(FALSE);
142 break;
143 }
144
145 ASSERT(ConsoleInitialized);
146
147 RtlEnterCriticalSection(&ConsoleLock);
148
149 nExitCode = 0;
150 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
151 {
152 for (i = NrCtrlHandlers; i > 0; i--)
153 {
154 if ((i == 1) &&
155 (CodeAndFlag & MINLONG) &&
156 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
157 {
158 DPRINT("Skipping system/service apps\n");
159 break;
160 }
161
162 if (CtrlHandlers[i - 1](nCode))
163 {
164 switch(nCode)
165 {
166 case CTRL_CLOSE_EVENT:
167 case CTRL_LOGOFF_EVENT:
168 case CTRL_SHUTDOWN_EVENT:
169 case 3:
170 nExitCode = CodeAndFlag;
171 break;
172 }
173 break;
174 }
175 }
176 }
177
178 RtlLeaveCriticalSection(&ConsoleLock);
179
180 ExitThread(nExitCode);
181 return STATUS_SUCCESS;
182 }
183
184 VOID
185 WINAPI
186 InitConsoleCtrlHandling(VOID)
187 {
188 /* Initialize Console Ctrl Handler */
189 NrAllocatedHandlers = NrCtrlHandlers = 1;
190 CtrlHandlers = InitialHandler;
191 CtrlHandlers[0] = DefaultConsoleCtrlHandler;
192 }
193
194
195 /* FUNCTIONS ******************************************************************/
196
197 LPCWSTR
198 IntCheckForConsoleFileName(IN LPCWSTR pszName,
199 IN DWORD dwDesiredAccess)
200 {
201 LPCWSTR ConsoleName = pszName;
202 ULONG DeviceNameInfo;
203
204 /*
205 * Check whether we deal with a DOS device, and if so,
206 * strip the path till the file name.
207 * Therefore, things like \\.\CON or C:\some_path\CONIN$
208 * are transformed into CON or CONIN$, for example.
209 */
210 DeviceNameInfo = RtlIsDosDeviceName_U(pszName);
211 if (DeviceNameInfo != 0)
212 {
213 ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF));
214 }
215
216 /* Return a standard console "file" name according to what we passed in parameters */
217 if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0)
218 {
219 return BaseConInputFileName;
220 }
221 else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0)
222 {
223 return BaseConOutputFileName;
224 }
225 else if (_wcsicmp(ConsoleName, BaseConFileName) == 0)
226 {
227 if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ)
228 {
229 return BaseConInputFileName;
230 }
231 else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE)
232 {
233 return BaseConOutputFileName;
234 }
235 }
236
237 /* If we are there, that means that either the file name or the desired access are wrong */
238 return NULL;
239 }
240
241
242 /*
243 * @unimplemented (Undocumented)
244 */
245 BOOL
246 WINAPI
247 ConsoleMenuControl(HANDLE hConsole,
248 DWORD Unknown1,
249 DWORD Unknown2)
250 {
251 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
252 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
253 return FALSE;
254 }
255
256
257 /*
258 * @implemented
259 */
260 HANDLE
261 WINAPI
262 DuplicateConsoleHandle(HANDLE hConsole,
263 DWORD dwDesiredAccess,
264 BOOL bInheritHandle,
265 DWORD dwOptions)
266 {
267 NTSTATUS Status;
268 CONSOLE_API_MESSAGE ApiMessage;
269 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest;
270
271 if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) ||
272 (!(dwOptions & DUPLICATE_SAME_ACCESS) &&
273 (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) )
274 {
275 SetLastError (ERROR_INVALID_PARAMETER);
276 return INVALID_HANDLE_VALUE;
277 }
278
279 DuplicateHandleRequest->ConsoleHandle = hConsole;
280 DuplicateHandleRequest->Access = dwDesiredAccess;
281 DuplicateHandleRequest->Inheritable = bInheritHandle;
282 DuplicateHandleRequest->Options = dwOptions;
283
284 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
285 NULL,
286 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle),
287 sizeof(CONSOLE_DUPLICATEHANDLE));
288 if (!NT_SUCCESS(Status))
289 {
290 BaseSetLastNTError(Status);
291 return INVALID_HANDLE_VALUE;
292 }
293
294 return DuplicateHandleRequest->ConsoleHandle;
295 }
296
297
298 /*
299 * @implemented
300 */
301 BOOL
302 WINAPI
303 GetConsoleDisplayMode(LPDWORD lpModeFlags)
304 {
305 NTSTATUS Status;
306 CONSOLE_API_MESSAGE ApiMessage;
307 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest;
308
309 if (lpModeFlags == NULL)
310 {
311 SetLastError(ERROR_INVALID_PARAMETER);
312 return FALSE;
313 }
314
315 // GetDisplayModeRequest->OutputHandle = hConsoleOutput;
316
317 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
318 NULL,
319 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode),
320 sizeof(CONSOLE_GETDISPLAYMODE));
321 if (!NT_SUCCESS(Status))
322 {
323 BaseSetLastNTError(Status);
324 return FALSE;
325 }
326
327 *lpModeFlags = GetDisplayModeRequest->DisplayMode;
328 return TRUE;
329 }
330
331
332 /*
333 * @unimplemented (Undocumented)
334 */
335 DWORD
336 WINAPI
337 GetConsoleFontInfo(DWORD Unknown0,
338 DWORD Unknown1,
339 DWORD Unknown2,
340 DWORD Unknown3)
341 {
342 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
343 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
344 return 0;
345 }
346
347
348 /*
349 * @unimplemented
350 */
351 COORD
352 WINAPI
353 GetConsoleFontSize(HANDLE hConsoleOutput,
354 DWORD nFont)
355 {
356 COORD Empty = {0, 0};
357 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
358 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
359 return Empty;
360 }
361
362
363 /*
364 * @implemented (Undocumented)
365 */
366 BOOL
367 WINAPI
368 GetConsoleHardwareState(HANDLE hConsoleOutput,
369 DWORD Flags,
370 PDWORD State)
371 {
372 NTSTATUS Status;
373 CONSOLE_API_MESSAGE ApiMessage;
374 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
375
376 DPRINT1("GetConsoleHardwareState(%d, 0x%p) UNIMPLEMENTED!\n", Flags, State);
377
378 if (State == NULL)
379 {
380 SetLastError(ERROR_INVALID_PARAMETER);
381 return FALSE;
382 }
383
384 HardwareStateRequest->OutputHandle = hConsoleOutput;
385
386 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
387 NULL,
388 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState),
389 sizeof(CONSOLE_GETSETHWSTATE));
390 if (!NT_SUCCESS(Status))
391 {
392 BaseSetLastNTError(Status);
393 return FALSE;
394 }
395
396 *State = HardwareStateRequest->State;
397 return TRUE;
398 }
399
400
401 /*
402 * @implemented (Undocumented)
403 */
404 HANDLE
405 WINAPI
406 GetConsoleInputWaitHandle(VOID)
407 {
408 return InputWaitHandle;
409 }
410
411
412 /*
413 * @unimplemented
414 */
415 INT
416 WINAPI
417 GetCurrentConsoleFont(HANDLE hConsoleOutput,
418 BOOL bMaximumWindow,
419 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
420 {
421 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
422 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
423 return 0;
424 }
425
426
427 /*
428 * @unimplemented (Undocumented)
429 */
430 ULONG
431 WINAPI
432 GetNumberOfConsoleFonts(VOID)
433 {
434 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
435 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
436 return 1;
437 }
438
439
440 /*
441 * @implemented (Undocumented)
442 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
443 */
444 BOOL
445 WINAPI
446 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
447 IN PSMALL_RECT lpRect)
448 {
449 NTSTATUS Status;
450 CONSOLE_API_MESSAGE ApiMessage;
451 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest;
452
453 if (lpRect == NULL)
454 {
455 SetLastError(ERROR_INVALID_PARAMETER);
456 return FALSE;
457 }
458
459 InvalidateDIBitsRequest->OutputHandle = hConsoleOutput;
460 InvalidateDIBitsRequest->Region = *lpRect;
461
462 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
463 NULL,
464 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect),
465 sizeof(CONSOLE_INVALIDATEDIBITS));
466 if (!NT_SUCCESS(Status))
467 {
468 BaseSetLastNTError(Status);
469 return FALSE;
470 }
471
472 return TRUE;
473 }
474
475
476 /*
477 * @unimplemented (Undocumented)
478 */
479 HANDLE
480 WINAPI
481 OpenConsoleW(LPCWSTR wsName,
482 DWORD dwDesiredAccess,
483 BOOL bInheritHandle,
484 DWORD dwShareMode)
485 {
486 NTSTATUS Status = STATUS_SUCCESS;
487 CONSOLE_API_MESSAGE ApiMessage;
488 PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest;
489 CONSOLE_HANDLE_TYPE HandleType;
490
491 if (wsName && 0 == _wcsicmp(wsName, BaseConInputFileName))
492 {
493 HandleType = HANDLE_INPUT;
494 }
495 else if (wsName && 0 == _wcsicmp(wsName, BaseConOutputFileName))
496 {
497 HandleType = HANDLE_OUTPUT;
498 }
499 else
500 {
501 SetLastError(ERROR_INVALID_PARAMETER);
502 return INVALID_HANDLE_VALUE;
503 }
504
505 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
506 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) )
507 {
508 SetLastError(ERROR_INVALID_PARAMETER);
509 return INVALID_HANDLE_VALUE;
510 }
511
512 OpenConsoleRequest->HandleType = HandleType;
513 OpenConsoleRequest->Access = dwDesiredAccess;
514 OpenConsoleRequest->Inheritable = bInheritHandle;
515 OpenConsoleRequest->ShareMode = dwShareMode;
516
517 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
518 NULL,
519 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole),
520 sizeof(CONSOLE_OPENCONSOLE));
521 if (!NT_SUCCESS(Status))
522 {
523 BaseSetLastNTError(Status);
524 return INVALID_HANDLE_VALUE;
525 }
526
527 return OpenConsoleRequest->ConsoleHandle;
528 }
529
530
531 /*
532 * @unimplemented (Undocumented)
533 */
534 BOOL
535 WINAPI
536 SetConsoleCursor(DWORD Unknown0,
537 DWORD Unknown1)
538 {
539 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
540 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
541 return FALSE;
542 }
543
544
545 /*
546 * @implemented
547 */
548 BOOL
549 WINAPI
550 SetConsoleDisplayMode(HANDLE hConsoleOutput,
551 DWORD dwFlags,
552 PCOORD lpNewScreenBufferDimensions)
553 {
554 NTSTATUS Status;
555 CONSOLE_API_MESSAGE ApiMessage;
556 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest;
557
558 SetDisplayModeRequest->OutputHandle = hConsoleOutput;
559 SetDisplayModeRequest->DisplayMode = dwFlags;
560 SetDisplayModeRequest->NewSBDim.X = 0;
561 SetDisplayModeRequest->NewSBDim.Y = 0;
562
563 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
564 NULL,
565 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode),
566 sizeof(CONSOLE_SETDISPLAYMODE));
567 if (!NT_SUCCESS(Status))
568 {
569 BaseSetLastNTError(Status);
570 return FALSE;
571 }
572
573 if (lpNewScreenBufferDimensions)
574 *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim;
575
576 return TRUE;
577 }
578
579
580 /*
581 * @unimplemented (Undocumented)
582 */
583 BOOL
584 WINAPI
585 SetConsoleFont(DWORD Unknown0,
586 DWORD Unknown1)
587 {
588 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
589 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
590 return FALSE;
591 }
592
593
594 /*
595 * @implemented (Undocumented)
596 */
597 BOOL
598 WINAPI
599 SetConsoleHardwareState(HANDLE hConsoleOutput,
600 DWORD Flags,
601 DWORD State)
602 {
603 NTSTATUS Status;
604 CONSOLE_API_MESSAGE ApiMessage;
605 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
606
607 DPRINT1("SetConsoleHardwareState(%d, %d) UNIMPLEMENTED!\n", Flags, State);
608
609 HardwareStateRequest->OutputHandle = hConsoleOutput;
610 HardwareStateRequest->State = State;
611
612 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
613 NULL,
614 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState),
615 sizeof(CONSOLE_GETSETHWSTATE));
616 if (!NT_SUCCESS(Status))
617 {
618 BaseSetLastNTError(Status);
619 return FALSE;
620 }
621
622 return TRUE;
623 }
624
625
626 /*
627 * @unimplemented (Undocumented)
628 */
629 BOOL
630 WINAPI
631 SetConsoleKeyShortcuts(DWORD Unknown0,
632 DWORD Unknown1,
633 DWORD Unknown2,
634 DWORD Unknown3)
635 {
636 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
637 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
638 return FALSE;
639 }
640
641
642 /*
643 * @unimplemented (Undocumented)
644 */
645 BOOL
646 WINAPI
647 SetConsoleMaximumWindowSize(DWORD Unknown0,
648 DWORD Unknown1)
649 {
650 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
651 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
652 return FALSE;
653 }
654
655
656 /*
657 * @unimplemented (Undocumented)
658 */
659 BOOL
660 WINAPI
661 SetConsoleMenuClose(DWORD Unknown0)
662 {
663 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
664 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
665 return FALSE;
666 }
667
668
669 /*
670 * @unimplemented (Undocumented)
671 */
672 BOOL
673 WINAPI
674 SetConsolePalette(DWORD Unknown0,
675 DWORD Unknown1,
676 DWORD Unknown2)
677 {
678 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
679 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
680 return FALSE;
681 }
682
683 /*
684 * @unimplemented (Undocumented)
685 */
686 DWORD
687 WINAPI
688 ShowConsoleCursor(DWORD Unknown0,
689 DWORD Unknown1)
690 {
691 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
692 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
693 return 0;
694 }
695
696
697 /*
698 * FUNCTION: Checks whether the given handle is a valid console handle.
699 *
700 * ARGUMENTS:
701 * Handle - Handle to be checked
702 *
703 * RETURNS:
704 * TRUE: Handle is a valid console handle
705 * FALSE: Handle is not a valid console handle.
706 *
707 * STATUS: Officially undocumented
708 *
709 * @implemented
710 */
711 BOOL
712 WINAPI
713 VerifyConsoleIoHandle(HANDLE Handle)
714 {
715 NTSTATUS Status;
716 CONSOLE_API_MESSAGE ApiMessage;
717
718 ApiMessage.Data.VerifyHandleRequest.ConsoleHandle = Handle;
719
720 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
721 NULL,
722 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle),
723 sizeof(CONSOLE_VERIFYHANDLE));
724 if (!NT_SUCCESS(Status))
725 {
726 BaseSetLastNTError(Status);
727 return FALSE;
728 }
729
730 return TRUE;
731 }
732
733
734 /*
735 * @unimplemented
736 */
737 DWORD
738 WINAPI
739 WriteConsoleInputVDMA(DWORD Unknown0,
740 DWORD Unknown1,
741 DWORD Unknown2,
742 DWORD Unknown3)
743 {
744 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
745 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
746 return 0;
747 }
748
749
750 /*
751 * @unimplemented
752 */
753 DWORD
754 WINAPI
755 WriteConsoleInputVDMW(DWORD Unknown0,
756 DWORD Unknown1,
757 DWORD Unknown2,
758 DWORD Unknown3)
759 {
760 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
761 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
762 return 0;
763 }
764
765
766 /*
767 * @implemented (Undocumented)
768 */
769 BOOL
770 WINAPI
771 CloseConsoleHandle(HANDLE Handle)
772 {
773 NTSTATUS Status;
774 CONSOLE_API_MESSAGE ApiMessage;
775
776 ApiMessage.Data.CloseHandleRequest.ConsoleHandle = Handle;
777
778 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
779 NULL,
780 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle),
781 sizeof(CONSOLE_CLOSEHANDLE));
782 if (!NT_SUCCESS(Status))
783 {
784 BaseSetLastNTError(Status);
785 return FALSE;
786 }
787
788 return TRUE;
789 }
790
791
792 /*
793 * @implemented
794 */
795 HANDLE
796 WINAPI
797 GetStdHandle(DWORD nStdHandle)
798 /*
799 * FUNCTION: Get a handle for the standard input, standard output
800 * and a standard error device.
801 *
802 * ARGUMENTS:
803 * nStdHandle - Specifies the device for which to return the handle.
804 *
805 * RETURNS: If the function succeeds, the return value is the handle
806 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
807 */
808 {
809 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
810
811 switch (nStdHandle)
812 {
813 case STD_INPUT_HANDLE:
814 return Ppb->StandardInput;
815
816 case STD_OUTPUT_HANDLE:
817 return Ppb->StandardOutput;
818
819 case STD_ERROR_HANDLE:
820 return Ppb->StandardError;
821 }
822
823 SetLastError(ERROR_INVALID_HANDLE);
824 return INVALID_HANDLE_VALUE;
825 }
826
827
828 /*
829 * @implemented
830 */
831 BOOL
832 WINAPI
833 SetStdHandle(DWORD nStdHandle,
834 HANDLE hHandle)
835 /*
836 * FUNCTION: Set the handle for the standard input, standard output or
837 * the standard error device.
838 *
839 * ARGUMENTS:
840 * nStdHandle - Specifies the handle to be set.
841 * hHandle - The handle to set.
842 *
843 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
844 */
845 {
846 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
847
848 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
849
850 switch (nStdHandle)
851 {
852 case STD_INPUT_HANDLE:
853 Ppb->StandardInput = hHandle;
854 return TRUE;
855
856 case STD_OUTPUT_HANDLE:
857 Ppb->StandardOutput = hHandle;
858 return TRUE;
859
860 case STD_ERROR_HANDLE:
861 Ppb->StandardError = hHandle;
862 return TRUE;
863 }
864
865 /* Windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
866 SetLastError(ERROR_INVALID_HANDLE);
867 return FALSE;
868 }
869
870
871 /*--------------------------------------------------------------
872 * AllocConsole
873 *
874 * @implemented
875 */
876 BOOL
877 WINAPI
878 AllocConsole(VOID)
879 {
880 NTSTATUS Status;
881 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
882 CONSOLE_API_MESSAGE ApiMessage;
883 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
884 PCSR_CAPTURE_BUFFER CaptureBuffer;
885 LPWSTR AppPath = NULL;
886 SIZE_T Length = 0;
887
888 if (Parameters->ConsoleHandle)
889 {
890 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
891 SetLastError(ERROR_ACCESS_DENIED);
892 return FALSE;
893 }
894
895 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
896 if (CaptureBuffer == NULL)
897 {
898 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
899 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
900 return FALSE;
901 }
902
903 CsrAllocateMessagePointer(CaptureBuffer,
904 sizeof(CONSOLE_START_INFO),
905 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
906
907 /** Copied from BasepInitConsole **********************************************/
908 InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo);
909
910 AppPath = AllocConsoleRequest->ConsoleStartInfo->AppPath;
911 Length = min(MAX_PATH, Parameters->ImagePathName.Length / sizeof(WCHAR));
912 wcsncpy(AppPath, Parameters->ImagePathName.Buffer, Length);
913 AppPath[Length] = L'\0';
914 /******************************************************************************/
915
916 AllocConsoleRequest->Console = NULL;
917 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
918 AllocConsoleRequest->PropDispatcher = PropDialogHandler;
919
920 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
921 CaptureBuffer,
922 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
923 sizeof(CONSOLE_ALLOCCONSOLE));
924
925 CsrFreeCaptureBuffer(CaptureBuffer);
926
927 if (!NT_SUCCESS(Status))
928 {
929 BaseSetLastNTError(Status);
930 return FALSE;
931 }
932
933 Parameters->ConsoleHandle = AllocConsoleRequest->Console;
934 SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
935 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
936 SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
937
938 /* Initialize Console Ctrl Handler */
939 InitConsoleCtrlHandling();
940
941 InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
942
943 return TRUE;
944 }
945
946
947 /*--------------------------------------------------------------
948 * FreeConsole
949 *
950 * @implemented
951 */
952 BOOL
953 WINAPI
954 FreeConsole(VOID)
955 {
956 // AG: I'm not sure if this is correct (what happens to std handles?)
957 // but I just tried to reverse what AllocConsole() does...
958
959 NTSTATUS Status;
960 CONSOLE_API_MESSAGE ApiMessage;
961
962 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
963 NULL,
964 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
965 sizeof(CONSOLE_FREECONSOLE));
966 if (!NT_SUCCESS(Status))
967 {
968 BaseSetLastNTError(Status);
969 return FALSE;
970 }
971
972 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
973
974 CloseHandle(InputWaitHandle);
975 InputWaitHandle = INVALID_HANDLE_VALUE;
976
977 return TRUE;
978 }
979
980
981 /*--------------------------------------------------------------
982 * GetConsoleScreenBufferInfo
983 *
984 * @implemented
985 */
986 BOOL
987 WINAPI
988 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
989 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
990 {
991 NTSTATUS Status;
992 CONSOLE_API_MESSAGE ApiMessage;
993
994 if (lpConsoleScreenBufferInfo == NULL)
995 {
996 SetLastError(ERROR_INVALID_PARAMETER);
997 return FALSE;
998 }
999
1000 ApiMessage.Data.ScreenBufferInfoRequest.OutputHandle = hConsoleOutput;
1001
1002 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1003 NULL,
1004 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1005 sizeof(CONSOLE_GETSCREENBUFFERINFO));
1006 if (!NT_SUCCESS(Status))
1007 {
1008 BaseSetLastNTError(Status);
1009 return FALSE;
1010 }
1011
1012 *lpConsoleScreenBufferInfo = ApiMessage.Data.ScreenBufferInfoRequest.Info;
1013
1014 return TRUE;
1015 }
1016
1017
1018 /*--------------------------------------------------------------
1019 * SetConsoleCursorPosition
1020 *
1021 * @implemented
1022 */
1023 BOOL
1024 WINAPI
1025 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1026 COORD dwCursorPosition)
1027 {
1028 NTSTATUS Status;
1029 CONSOLE_API_MESSAGE ApiMessage;
1030
1031 ApiMessage.Data.SetCursorPositionRequest.OutputHandle = hConsoleOutput;
1032 ApiMessage.Data.SetCursorPositionRequest.Position = dwCursorPosition;
1033
1034 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1035 NULL,
1036 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1037 sizeof(CONSOLE_SETCURSORPOSITION));
1038 if (!NT_SUCCESS(Status))
1039 {
1040 BaseSetLastNTError(Status);
1041 return FALSE;
1042 }
1043
1044 return TRUE;
1045 }
1046
1047
1048 /*--------------------------------------------------------------
1049 * GetConsoleMode
1050 *
1051 * @implemented
1052 */
1053 BOOL
1054 WINAPI
1055 GetConsoleMode(HANDLE hConsoleHandle,
1056 LPDWORD lpMode)
1057 {
1058 NTSTATUS Status;
1059 CONSOLE_API_MESSAGE ApiMessage;
1060 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1061
1062 if (lpMode == NULL)
1063 {
1064 SetLastError(ERROR_INVALID_PARAMETER);
1065 return FALSE;
1066 }
1067
1068 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1069
1070 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1071 NULL,
1072 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1073 sizeof(CONSOLE_GETSETCONSOLEMODE));
1074 if (!NT_SUCCESS(Status))
1075 {
1076 BaseSetLastNTError(Status);
1077 return FALSE;
1078 }
1079
1080 *lpMode = ConsoleModeRequest->ConsoleMode;
1081
1082 return TRUE;
1083 }
1084
1085
1086 /*--------------------------------------------------------------
1087 * GetNumberOfConsoleInputEvents
1088 *
1089 * @implemented
1090 */
1091 BOOL
1092 WINAPI
1093 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1094 LPDWORD lpNumberOfEvents)
1095 {
1096 NTSTATUS Status;
1097 CONSOLE_API_MESSAGE ApiMessage;
1098 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1099
1100 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1101 GetNumInputEventsRequest->NumInputEvents = 0;
1102
1103 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1104 NULL,
1105 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1106 sizeof(CONSOLE_GETNUMINPUTEVENTS));
1107 if (!NT_SUCCESS(Status))
1108 {
1109 BaseSetLastNTError(Status);
1110 return FALSE;
1111 }
1112
1113 if (lpNumberOfEvents == NULL)
1114 {
1115 SetLastError(ERROR_INVALID_ACCESS);
1116 return FALSE;
1117 }
1118
1119 *lpNumberOfEvents = GetNumInputEventsRequest->NumInputEvents;
1120
1121 return TRUE;
1122 }
1123
1124
1125 /*--------------------------------------------------------------
1126 * GetLargestConsoleWindowSize
1127 *
1128 * @implemented
1129 */
1130 COORD
1131 WINAPI
1132 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1133 {
1134 NTSTATUS Status;
1135 CONSOLE_API_MESSAGE ApiMessage;
1136 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1137
1138 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1139 GetLargestWindowSizeRequest->Size.X = 0;
1140 GetLargestWindowSizeRequest->Size.Y = 0;
1141
1142 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1143 NULL,
1144 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1145 sizeof(CONSOLE_GETLARGESTWINDOWSIZE));
1146 if (!NT_SUCCESS(Status))
1147 {
1148 BaseSetLastNTError(Status);
1149 }
1150
1151 DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1152 return GetLargestWindowSizeRequest->Size;
1153 }
1154
1155
1156 /*--------------------------------------------------------------
1157 * GetConsoleCursorInfo
1158 *
1159 * @implemented
1160 */
1161 BOOL
1162 WINAPI
1163 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1164 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1165 {
1166 NTSTATUS Status;
1167 CONSOLE_API_MESSAGE ApiMessage;
1168
1169 if (!lpConsoleCursorInfo)
1170 {
1171 if (!hConsoleOutput)
1172 SetLastError(ERROR_INVALID_HANDLE);
1173 else
1174 SetLastError(ERROR_INVALID_ACCESS);
1175
1176 return FALSE;
1177 }
1178
1179 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1180
1181 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1182 NULL,
1183 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1184 sizeof(CONSOLE_GETSETCURSORINFO));
1185 if (!NT_SUCCESS(Status))
1186 {
1187 BaseSetLastNTError(Status);
1188 return FALSE;
1189 }
1190
1191 *lpConsoleCursorInfo = ApiMessage.Data.CursorInfoRequest.Info;
1192
1193 return TRUE;
1194 }
1195
1196
1197 /*--------------------------------------------------------------
1198 * GetNumberOfConsoleMouseButtons
1199 *
1200 * @unimplemented
1201 */
1202 BOOL
1203 WINAPI
1204 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1205 {
1206 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
1207 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1208 return FALSE;
1209 }
1210
1211
1212 /*--------------------------------------------------------------
1213 * SetConsoleMode
1214 *
1215 * @implemented
1216 */
1217 BOOL
1218 WINAPI
1219 SetConsoleMode(HANDLE hConsoleHandle,
1220 DWORD dwMode)
1221 {
1222 NTSTATUS Status;
1223 CONSOLE_API_MESSAGE ApiMessage;
1224 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1225
1226 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1227 ConsoleModeRequest->ConsoleMode = dwMode;
1228
1229 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1230 NULL,
1231 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1232 sizeof(CONSOLE_GETSETCONSOLEMODE));
1233 if (!NT_SUCCESS(Status))
1234 {
1235 BaseSetLastNTError(Status);
1236 return FALSE;
1237 }
1238
1239 return TRUE;
1240 }
1241
1242
1243 /*--------------------------------------------------------------
1244 * SetConsoleActiveScreenBuffer
1245 *
1246 * @implemented
1247 */
1248 BOOL
1249 WINAPI
1250 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1251 {
1252 NTSTATUS Status;
1253 CONSOLE_API_MESSAGE ApiMessage;
1254
1255 ApiMessage.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
1256
1257 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1258 NULL,
1259 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1260 sizeof(CONSOLE_SETACTIVESCREENBUFFER));
1261 if (!NT_SUCCESS(Status))
1262 {
1263 BaseSetLastNTError(Status);
1264 return FALSE;
1265 }
1266
1267 return TRUE;
1268 }
1269
1270
1271 /*--------------------------------------------------------------
1272 * FlushConsoleInputBuffer
1273 *
1274 * @implemented
1275 */
1276 BOOL
1277 WINAPI
1278 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1279 {
1280 NTSTATUS Status;
1281 CONSOLE_API_MESSAGE ApiMessage;
1282
1283 ApiMessage.Data.FlushInputBufferRequest.InputHandle = hConsoleInput;
1284
1285 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1286 NULL,
1287 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1288 sizeof(CONSOLE_FLUSHINPUTBUFFER));
1289 if (!NT_SUCCESS(Status))
1290 {
1291 BaseSetLastNTError(Status);
1292 return FALSE;
1293 }
1294
1295 return TRUE;
1296 }
1297
1298
1299 /*--------------------------------------------------------------
1300 * SetConsoleScreenBufferSize
1301 *
1302 * @implemented
1303 */
1304 BOOL
1305 WINAPI
1306 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1307 COORD dwSize)
1308 {
1309 NTSTATUS Status;
1310 CONSOLE_API_MESSAGE ApiMessage;
1311
1312 ApiMessage.Data.SetScreenBufferSizeRequest.OutputHandle = hConsoleOutput;
1313 ApiMessage.Data.SetScreenBufferSizeRequest.Size = dwSize;
1314
1315 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1316 NULL,
1317 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1318 sizeof(CONSOLE_SETSCREENBUFFERSIZE));
1319 if (!NT_SUCCESS(Status))
1320 {
1321 BaseSetLastNTError(Status);
1322 return FALSE;
1323 }
1324
1325 return TRUE;
1326 }
1327
1328
1329 /*--------------------------------------------------------------
1330 * SetConsoleCursorInfo
1331 *
1332 * @implemented
1333 */
1334 BOOL
1335 WINAPI
1336 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1337 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1338 {
1339 NTSTATUS Status;
1340 CONSOLE_API_MESSAGE ApiMessage;
1341
1342 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1343 ApiMessage.Data.CursorInfoRequest.Info = *lpConsoleCursorInfo;
1344
1345 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1346 NULL,
1347 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1348 sizeof(CONSOLE_GETSETCURSORINFO));
1349 if (!NT_SUCCESS(Status))
1350 {
1351 BaseSetLastNTError(Status);
1352 return FALSE;
1353 }
1354
1355 return TRUE;
1356 }
1357
1358
1359 static
1360 BOOL
1361 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1362 const SMALL_RECT *lpScrollRectangle,
1363 const SMALL_RECT *lpClipRectangle,
1364 COORD dwDestinationOrigin,
1365 const CHAR_INFO *lpFill,
1366 BOOL bUnicode)
1367 {
1368 NTSTATUS Status;
1369 CONSOLE_API_MESSAGE ApiMessage;
1370 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1371
1372 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1373 ScrollScreenBufferRequest->Unicode = bUnicode;
1374 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1375
1376 if (lpClipRectangle != NULL)
1377 {
1378 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1379 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1380 }
1381 else
1382 {
1383 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1384 }
1385
1386 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1387 ScrollScreenBufferRequest->Fill = *lpFill;
1388
1389 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1390 NULL,
1391 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1392 sizeof(CONSOLE_SCROLLSCREENBUFFER));
1393
1394 if (!NT_SUCCESS(Status))
1395 {
1396 BaseSetLastNTError(Status);
1397 return FALSE;
1398 }
1399
1400 return TRUE;
1401 }
1402
1403
1404 /*--------------------------------------------------------------
1405 * ScrollConsoleScreenBufferA
1406 *
1407 * @implemented
1408 */
1409 BOOL
1410 WINAPI
1411 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1412 CONST SMALL_RECT *lpScrollRectangle,
1413 CONST SMALL_RECT *lpClipRectangle,
1414 COORD dwDestinationOrigin,
1415 CONST CHAR_INFO *lpFill)
1416 {
1417 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1418 (PSMALL_RECT)lpScrollRectangle,
1419 (PSMALL_RECT)lpClipRectangle,
1420 dwDestinationOrigin,
1421 (PCHAR_INFO)lpFill,
1422 FALSE);
1423 }
1424
1425
1426 /*--------------------------------------------------------------
1427 * ScrollConsoleScreenBufferW
1428 *
1429 * @implemented
1430 */
1431 BOOL
1432 WINAPI
1433 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1434 CONST SMALL_RECT *lpScrollRectangle,
1435 CONST SMALL_RECT *lpClipRectangle,
1436 COORD dwDestinationOrigin,
1437 CONST CHAR_INFO *lpFill)
1438 {
1439 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1440 lpScrollRectangle,
1441 lpClipRectangle,
1442 dwDestinationOrigin,
1443 lpFill,
1444 TRUE);
1445 }
1446
1447
1448 /*--------------------------------------------------------------
1449 * SetConsoleWindowInfo
1450 *
1451 * @implemented
1452 */
1453 BOOL
1454 WINAPI
1455 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1456 BOOL bAbsolute,
1457 CONST SMALL_RECT *lpConsoleWindow)
1458 {
1459 NTSTATUS Status;
1460 CONSOLE_API_MESSAGE ApiMessage;
1461 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1462
1463 if (lpConsoleWindow == NULL)
1464 {
1465 SetLastError(ERROR_INVALID_PARAMETER);
1466 return FALSE;
1467 }
1468
1469 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1470 SetWindowInfoRequest->Absolute = bAbsolute;
1471 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1472
1473 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1474 NULL,
1475 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1476 sizeof(CONSOLE_SETWINDOWINFO));
1477 if (!NT_SUCCESS(Status))
1478 {
1479 BaseSetLastNTError(Status);
1480 return FALSE;
1481 }
1482
1483 return TRUE;
1484 }
1485
1486
1487 /*--------------------------------------------------------------
1488 * SetConsoleTextAttribute
1489 *
1490 * @implemented
1491 */
1492 BOOL
1493 WINAPI
1494 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1495 WORD wAttributes)
1496 {
1497 NTSTATUS Status;
1498 CONSOLE_API_MESSAGE ApiMessage;
1499
1500 ApiMessage.Data.SetTextAttribRequest.OutputHandle = hConsoleOutput;
1501 ApiMessage.Data.SetTextAttribRequest.Attrib = wAttributes;
1502
1503 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1504 NULL,
1505 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1506 sizeof(CONSOLE_SETTEXTATTRIB));
1507 if (!NT_SUCCESS(Status))
1508 {
1509 BaseSetLastNTError(Status);
1510 return FALSE;
1511 }
1512
1513 return TRUE;
1514 }
1515
1516
1517 static
1518 BOOL
1519 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1520 {
1521 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1522
1523 if (HandlerRoutine == NULL)
1524 {
1525 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1526 return TRUE;
1527 }
1528
1529 if (NrCtrlHandlers == NrAllocatedHandlers)
1530 {
1531 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1532 0,
1533 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1534 if (NewCtrlHandlers == NULL)
1535 {
1536 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1537 return FALSE;
1538 }
1539
1540 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1541
1542 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1543
1544 CtrlHandlers = NewCtrlHandlers;
1545 NrAllocatedHandlers += 4;
1546 }
1547
1548 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1549
1550 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1551 return TRUE;
1552 }
1553
1554
1555 static
1556 BOOL
1557 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1558 {
1559 ULONG i;
1560
1561 if (HandlerRoutine == NULL)
1562 {
1563 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1564 return TRUE;
1565 }
1566
1567 for (i = 0; i < NrCtrlHandlers; i++)
1568 {
1569 if (CtrlHandlers[i] == HandlerRoutine)
1570 {
1571 if (i < (NrCtrlHandlers - 1))
1572 {
1573 memmove(&CtrlHandlers[i],
1574 &CtrlHandlers[i+1],
1575 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1576 }
1577
1578 NrCtrlHandlers--;
1579 return TRUE;
1580 }
1581 }
1582
1583 SetLastError(ERROR_INVALID_PARAMETER);
1584 return FALSE;
1585 }
1586
1587
1588 /*
1589 * @implemented
1590 */
1591 BOOL
1592 WINAPI
1593 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1594 BOOL Add)
1595 {
1596 BOOL Ret;
1597
1598 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1599 if (Add)
1600 {
1601 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1602 }
1603 else
1604 {
1605 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1606 }
1607
1608 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1609 return(Ret);
1610 }
1611
1612
1613 /*--------------------------------------------------------------
1614 * GenerateConsoleCtrlEvent
1615 *
1616 * @implemented
1617 */
1618 BOOL
1619 WINAPI
1620 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1621 DWORD dwProcessGroupId)
1622 {
1623 NTSTATUS Status;
1624 CONSOLE_API_MESSAGE ApiMessage;
1625
1626 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1627 {
1628 SetLastError(ERROR_INVALID_PARAMETER);
1629 return FALSE;
1630 }
1631
1632 ApiMessage.Data.GenerateCtrlEventRequest.Event = dwCtrlEvent;
1633 ApiMessage.Data.GenerateCtrlEventRequest.ProcessGroup = dwProcessGroupId;
1634
1635 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1636 NULL,
1637 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1638 sizeof(CONSOLE_GENERATECTRLEVENT));
1639 if (!NT_SUCCESS(Status))
1640 {
1641 BaseSetLastNTError(Status);
1642 return FALSE;
1643 }
1644
1645 return TRUE;
1646 }
1647
1648
1649 static DWORD
1650 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
1651 {
1652 NTSTATUS Status;
1653 CONSOLE_API_MESSAGE ApiMessage;
1654 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1655 PCSR_CAPTURE_BUFFER CaptureBuffer;
1656
1657 if (nSize == 0) return 0;
1658
1659 TitleRequest->Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
1660 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1661 if (CaptureBuffer == NULL)
1662 {
1663 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1664 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1665 return 0;
1666 }
1667
1668 CsrAllocateMessagePointer(CaptureBuffer,
1669 TitleRequest->Length,
1670 (PVOID*)&TitleRequest->Title);
1671
1672 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1673 CaptureBuffer,
1674 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1675 sizeof(CONSOLE_GETSETCONSOLETITLE));
1676 if (!NT_SUCCESS(Status))
1677 {
1678 CsrFreeCaptureBuffer(CaptureBuffer);
1679 BaseSetLastNTError(Status);
1680 return 0;
1681 }
1682
1683 if (bUnicode)
1684 {
1685 if (nSize >= sizeof(WCHAR))
1686 wcscpy((LPWSTR)lpConsoleTitle, TitleRequest->Title);
1687 }
1688 else
1689 {
1690 if (nSize < TitleRequest->Length / sizeof(WCHAR) ||
1691 !WideCharToMultiByte(CP_ACP, // ANSI code page
1692 0, // performance and mapping flags
1693 TitleRequest->Title, // address of wide-character string
1694 -1, // number of characters in string
1695 (LPSTR)lpConsoleTitle, // address of buffer for new string
1696 nSize, // size of buffer
1697 NULL, // FAST
1698 NULL))
1699 {
1700 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1701 *(LPSTR)lpConsoleTitle = '\0';
1702 TitleRequest->Length = 0;
1703 }
1704 }
1705 CsrFreeCaptureBuffer(CaptureBuffer);
1706
1707 return TitleRequest->Length / sizeof(WCHAR);
1708 }
1709
1710
1711 /*--------------------------------------------------------------
1712 * GetConsoleTitleW
1713 *
1714 * @implemented
1715 */
1716 DWORD
1717 WINAPI
1718 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1719 DWORD nSize)
1720 {
1721 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1722 }
1723
1724
1725 /*--------------------------------------------------------------
1726 * GetConsoleTitleA
1727 *
1728 * @implemented
1729 */
1730 DWORD
1731 WINAPI
1732 GetConsoleTitleA(LPSTR lpConsoleTitle,
1733 DWORD nSize)
1734 {
1735 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1736 }
1737
1738
1739 /*--------------------------------------------------------------
1740 * SetConsoleTitleW
1741 *
1742 * @implemented
1743 */
1744 BOOL
1745 WINAPI
1746 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1747 {
1748 NTSTATUS Status;
1749 CONSOLE_API_MESSAGE ApiMessage;
1750 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1751 PCSR_CAPTURE_BUFFER CaptureBuffer;
1752
1753 TitleRequest->Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
1754
1755 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1756 if (CaptureBuffer == NULL)
1757 {
1758 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1759 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1760 return FALSE;
1761 }
1762
1763 CsrCaptureMessageBuffer(CaptureBuffer,
1764 (PVOID)lpConsoleTitle,
1765 TitleRequest->Length,
1766 (PVOID*)&TitleRequest->Title);
1767
1768 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1769 CaptureBuffer,
1770 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1771 sizeof(CONSOLE_GETSETCONSOLETITLE));
1772
1773 CsrFreeCaptureBuffer(CaptureBuffer);
1774
1775 if (!NT_SUCCESS(Status))
1776 {
1777 BaseSetLastNTError(Status);
1778 return FALSE;
1779 }
1780
1781 return TRUE;
1782 }
1783
1784
1785 /*--------------------------------------------------------------
1786 * SetConsoleTitleA
1787 *
1788 * @implemented
1789 */
1790 BOOL
1791 WINAPI
1792 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1793 {
1794 BOOL Ret;
1795 ULONG Length = strlen(lpConsoleTitle) + 1;
1796 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1797
1798 if (!WideTitle)
1799 {
1800 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1801 return FALSE;
1802 }
1803
1804 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
1805
1806 Ret = SetConsoleTitleW(WideTitle);
1807
1808 HeapFree(GetProcessHeap(), 0, WideTitle);
1809 return Ret;
1810 }
1811
1812
1813 /*--------------------------------------------------------------
1814 * CreateConsoleScreenBuffer
1815 *
1816 * @implemented
1817 */
1818 HANDLE
1819 WINAPI
1820 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1821 DWORD dwShareMode,
1822 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1823 DWORD dwFlags,
1824 LPVOID lpScreenBufferData)
1825 {
1826 NTSTATUS Status;
1827 CONSOLE_API_MESSAGE ApiMessage;
1828 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1829 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1830 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData;
1831
1832 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1833 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1834 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1835 {
1836 SetLastError(ERROR_INVALID_PARAMETER);
1837 return INVALID_HANDLE_VALUE;
1838 }
1839
1840 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1841 CreateScreenBufferRequest->Access = dwDesiredAccess;
1842 CreateScreenBufferRequest->ShareMode = dwShareMode;
1843 CreateScreenBufferRequest->Inheritable =
1844 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1845
1846 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1847 {
1848 if (CreateScreenBufferRequest->Inheritable || GraphicsBufferInfo == NULL)
1849 {
1850 SetLastError(ERROR_INVALID_PARAMETER);
1851 return INVALID_HANDLE_VALUE;
1852 }
1853
1854 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
1855
1856 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
1857 if (CaptureBuffer == NULL)
1858 {
1859 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1860 return FALSE;
1861 }
1862
1863 CsrCaptureMessageBuffer(CaptureBuffer,
1864 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
1865 GraphicsBufferInfo->dwBitMapInfoLength,
1866 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
1867 }
1868
1869 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1870 CaptureBuffer,
1871 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1872 sizeof(CONSOLE_CREATESCREENBUFFER));
1873
1874 if (CaptureBuffer)
1875 CsrFreeCaptureBuffer(CaptureBuffer);
1876
1877 if (!NT_SUCCESS(Status))
1878 {
1879 BaseSetLastNTError(Status);
1880 return INVALID_HANDLE_VALUE;
1881 }
1882
1883 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
1884 {
1885 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
1886 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
1887 }
1888
1889 return CreateScreenBufferRequest->OutputHandle;
1890 }
1891
1892
1893 /*--------------------------------------------------------------
1894 * GetConsoleCP
1895 *
1896 * @implemented
1897 */
1898 UINT
1899 WINAPI
1900 GetConsoleCP(VOID)
1901 {
1902 NTSTATUS Status;
1903 CONSOLE_API_MESSAGE ApiMessage;
1904
1905 /* Get the Input Code Page */
1906 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1907
1908 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1909 NULL,
1910 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1911 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1912 if (!NT_SUCCESS(Status))
1913 {
1914 BaseSetLastNTError(Status);
1915 return 0;
1916 }
1917
1918 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1919 }
1920
1921
1922 /*--------------------------------------------------------------
1923 * SetConsoleCP
1924 *
1925 * @implemented
1926 */
1927 BOOL
1928 WINAPI
1929 SetConsoleCP(UINT wCodePageID)
1930 {
1931 NTSTATUS Status;
1932 CONSOLE_API_MESSAGE ApiMessage;
1933
1934 /* Set the Input Code Page */
1935 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1936 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1937
1938 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1939 NULL,
1940 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1941 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1942 if (!NT_SUCCESS(Status))
1943 {
1944 BaseSetLastNTError(Status);
1945 }
1946
1947 return NT_SUCCESS(Status);
1948 }
1949
1950
1951 /*--------------------------------------------------------------
1952 * GetConsoleOutputCP
1953 *
1954 * @implemented
1955 */
1956 UINT
1957 WINAPI
1958 GetConsoleOutputCP(VOID)
1959 {
1960 NTSTATUS Status;
1961 CONSOLE_API_MESSAGE ApiMessage;
1962
1963 /* Get the Output Code Page */
1964 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1965
1966 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1967 NULL,
1968 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1969 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1970 if (!NT_SUCCESS(Status))
1971 {
1972 BaseSetLastNTError (Status);
1973 return 0;
1974 }
1975
1976 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1977 }
1978
1979
1980 /*--------------------------------------------------------------
1981 * SetConsoleOutputCP
1982 *
1983 * @implemented
1984 */
1985 BOOL
1986 WINAPI
1987 SetConsoleOutputCP(UINT wCodePageID)
1988 {
1989 NTSTATUS Status;
1990 CONSOLE_API_MESSAGE ApiMessage;
1991
1992 /* Set the Output Code Page */
1993 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1994 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1995
1996 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1997 NULL,
1998 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1999 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2000 if (!NT_SUCCESS(Status))
2001 {
2002 BaseSetLastNTError(Status);
2003 }
2004
2005 return NT_SUCCESS(Status);
2006 }
2007
2008
2009 /*--------------------------------------------------------------
2010 * GetConsoleProcessList
2011 *
2012 * @implemented
2013 */
2014 DWORD
2015 WINAPI
2016 GetConsoleProcessList(LPDWORD lpdwProcessList,
2017 DWORD dwProcessCount)
2018 {
2019 NTSTATUS Status;
2020 CONSOLE_API_MESSAGE ApiMessage;
2021 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2022 PCSR_CAPTURE_BUFFER CaptureBuffer;
2023 ULONG nProcesses;
2024
2025 if (lpdwProcessList == NULL || dwProcessCount == 0)
2026 {
2027 SetLastError(ERROR_INVALID_PARAMETER);
2028 return 0;
2029 }
2030
2031 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2032 if (CaptureBuffer == NULL)
2033 {
2034 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2035 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2036 return FALSE;
2037 }
2038
2039 GetProcessListRequest->nMaxIds = dwProcessCount;
2040
2041 CsrAllocateMessagePointer(CaptureBuffer,
2042 dwProcessCount * sizeof(DWORD),
2043 (PVOID*)&GetProcessListRequest->pProcessIds);
2044
2045 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2046 CaptureBuffer,
2047 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2048 sizeof(CONSOLE_GETPROCESSLIST));
2049 if (!NT_SUCCESS(Status))
2050 {
2051 BaseSetLastNTError (Status);
2052 nProcesses = 0;
2053 }
2054 else
2055 {
2056 nProcesses = GetProcessListRequest->nProcessIdsTotal;
2057 if (dwProcessCount >= nProcesses)
2058 {
2059 memcpy(lpdwProcessList, GetProcessListRequest->pProcessIds, nProcesses * sizeof(DWORD));
2060 }
2061 }
2062
2063 CsrFreeCaptureBuffer(CaptureBuffer);
2064 return nProcesses;
2065 }
2066
2067
2068 /*--------------------------------------------------------------
2069 * GetConsoleSelectionInfo
2070 *
2071 * @implemented
2072 */
2073 BOOL
2074 WINAPI
2075 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2076 {
2077 NTSTATUS Status;
2078 CONSOLE_API_MESSAGE ApiMessage;
2079
2080 if (lpConsoleSelectionInfo == NULL)
2081 {
2082 SetLastError(ERROR_INVALID_PARAMETER);
2083 return FALSE;
2084 }
2085
2086 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2087 NULL,
2088 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2089 sizeof(CONSOLE_GETSELECTIONINFO));
2090 if (!NT_SUCCESS(Status))
2091 {
2092 BaseSetLastNTError(Status);
2093 return FALSE;
2094 }
2095
2096 *lpConsoleSelectionInfo = ApiMessage.Data.GetSelectionInfoRequest.Info;
2097 return TRUE;
2098 }
2099
2100
2101 /*--------------------------------------------------------------
2102 * AttachConsole
2103 *
2104 * @implemented
2105 *
2106 * @note Strongly inspired by AllocConsole.
2107 */
2108 BOOL
2109 WINAPI
2110 AttachConsole(DWORD dwProcessId)
2111 {
2112 NTSTATUS Status;
2113 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2114 CONSOLE_API_MESSAGE ApiMessage;
2115 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2116
2117 if (Parameters->ConsoleHandle)
2118 {
2119 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2120 SetLastError(ERROR_ACCESS_DENIED);
2121 return FALSE;
2122 }
2123
2124 AttachConsoleRequest->ProcessId = dwProcessId;
2125 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2126 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2127
2128 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2129 NULL,
2130 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2131 sizeof(CONSOLE_ATTACHCONSOLE));
2132 if (!NT_SUCCESS(Status))
2133 {
2134 BaseSetLastNTError(Status);
2135 return FALSE;
2136 }
2137
2138 Parameters->ConsoleHandle = AttachConsoleRequest->Console;
2139 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2140 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2141 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2142
2143 /* Initialize Console Ctrl Handler */
2144 InitConsoleCtrlHandling();
2145
2146 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2147
2148 return TRUE;
2149 }
2150
2151
2152 /*--------------------------------------------------------------
2153 * GetConsoleWindow
2154 *
2155 * @implemented
2156 */
2157 HWND
2158 WINAPI
2159 GetConsoleWindow(VOID)
2160 {
2161 NTSTATUS Status;
2162 CONSOLE_API_MESSAGE ApiMessage;
2163
2164 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2165 NULL,
2166 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2167 sizeof(CONSOLE_GETWINDOW));
2168 if (!NT_SUCCESS(Status))
2169 {
2170 BaseSetLastNTError(Status);
2171 return (HWND)NULL;
2172 }
2173
2174 return ApiMessage.Data.GetWindowRequest.WindowHandle;
2175 }
2176
2177
2178 /*--------------------------------------------------------------
2179 * SetConsoleIcon
2180 *
2181 * @implemented
2182 */
2183 BOOL
2184 WINAPI
2185 SetConsoleIcon(HICON hicon)
2186 {
2187 NTSTATUS Status;
2188 CONSOLE_API_MESSAGE ApiMessage;
2189
2190 ApiMessage.Data.SetIconRequest.WindowIcon = hicon;
2191
2192 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2193 NULL,
2194 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2195 sizeof(CONSOLE_SETICON));
2196 if (!NT_SUCCESS(Status))
2197 {
2198 BaseSetLastNTError(Status);
2199 return FALSE;
2200 }
2201
2202 return NT_SUCCESS(Status);
2203 }
2204
2205
2206 /******************************************************************************
2207 * \name SetConsoleInputExeNameW
2208 * \brief Sets the console input file name from a unicode string.
2209 * \param lpInputExeName Pointer to a unicode string with the name.
2210 * \return TRUE if successful, FALSE if unsuccsedful.
2211 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2212 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2213 */
2214 BOOL
2215 WINAPI
2216 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2217 {
2218 int lenName;
2219
2220 if ( !lpInputExeName ||
2221 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2222 lenName > INPUTEXENAME_BUFLEN - 1 )
2223 {
2224 /* Fail if string is empty or too long */
2225 SetLastError(ERROR_INVALID_PARAMETER);
2226 return FALSE;
2227 }
2228
2229 RtlEnterCriticalSection(&ConsoleLock);
2230 _SEH2_TRY
2231 {
2232 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2233 InputExeName[lenName] = L'\0';
2234 }
2235 _SEH2_FINALLY
2236 {
2237 RtlLeaveCriticalSection(&ConsoleLock);
2238 }
2239 _SEH2_END;
2240
2241 return TRUE;
2242 }
2243
2244
2245 /******************************************************************************
2246 * \name SetConsoleInputExeNameA
2247 * \brief Sets the console input file name from an ansi string.
2248 * \param lpInputExeName Pointer to an ansi string with the name.
2249 * \return TRUE if successful, FALSE if unsuccsedful.
2250 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2251 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2252 */
2253 BOOL
2254 WINAPI
2255 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2256 {
2257 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2258 ANSI_STRING InputExeNameA;
2259 UNICODE_STRING InputExeNameU;
2260 NTSTATUS Status;
2261
2262 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2263
2264 if ( InputExeNameA.Length == 0 ||
2265 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2266 {
2267 /* Fail if string is empty or too long */
2268 SetLastError(ERROR_INVALID_PARAMETER);
2269 return FALSE;
2270 }
2271
2272 InputExeNameU.Buffer = Buffer;
2273 InputExeNameU.MaximumLength = sizeof(Buffer);
2274 InputExeNameU.Length = 0;
2275
2276 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2277 if (!NT_SUCCESS(Status))
2278 {
2279 BaseSetLastNTError(Status);
2280 return FALSE;
2281 }
2282
2283 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2284 }
2285
2286
2287 /******************************************************************************
2288 * \name GetConsoleInputExeNameW
2289 * \brief Retrieves the console input file name as unicode string.
2290 * \param nBufferLength Length of the buffer in WCHARs.
2291 * Specify 0 to receive the needed buffer length.
2292 * \param lpBuffer Pointer to a buffer that receives the string.
2293 * \return Needed buffer size if \p nBufferLength is 0.
2294 * Otherwise 1 if successful, 2 if buffer is too small.
2295 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2296 * is not big enough.
2297 */
2298 DWORD
2299 WINAPI
2300 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2301 {
2302 ULONG lenName = lstrlenW(InputExeName);
2303
2304 if (nBufferLength == 0)
2305 {
2306 /* Buffer size is requested, return it */
2307 return lenName + 1;
2308 }
2309
2310 if (lenName + 1 > nBufferLength)
2311 {
2312 /* Buffer is not large enough! */
2313 SetLastError(ERROR_BUFFER_OVERFLOW);
2314 return 2;
2315 }
2316
2317 RtlEnterCriticalSection(&ConsoleLock);
2318 _SEH2_TRY
2319 {
2320 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2321 lpBuffer[lenName] = '\0';
2322 }
2323 _SEH2_FINALLY
2324 {
2325 RtlLeaveCriticalSection(&ConsoleLock);
2326 }
2327 _SEH2_END;
2328
2329 /* Success, return 1 */
2330 return 1;
2331 }
2332
2333
2334 /******************************************************************************
2335 * \name GetConsoleInputExeNameA
2336 * \brief Retrieves the console input file name as ansi string.
2337 * \param nBufferLength Length of the buffer in CHARs.
2338 * \param lpBuffer Pointer to a buffer that receives the string.
2339 * \return 1 if successful, 2 if buffer is too small.
2340 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2341 * is not big enough. The buffer receives as much characters as fit.
2342 */
2343 DWORD
2344 WINAPI
2345 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2346 {
2347 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2348 DWORD Ret;
2349 UNICODE_STRING BufferU;
2350 ANSI_STRING BufferA;
2351
2352 /* Get the unicode name */
2353 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2354
2355 /* Initialize strings for conversion */
2356 RtlInitUnicodeString(&BufferU, Buffer);
2357 BufferA.Length = 0;
2358 BufferA.MaximumLength = (USHORT)nBufferLength;
2359 BufferA.Buffer = lpBuffer;
2360
2361 /* Convert unicode name to ansi, copying as much chars as fit */
2362 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2363
2364 /* Error handling */
2365 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2366 {
2367 SetLastError(ERROR_BUFFER_OVERFLOW);
2368 return 2;
2369 }
2370
2371 return Ret;
2372 }
2373
2374 BOOL
2375 WINAPI
2376 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2377 {
2378 STUB;
2379 return FALSE;
2380 }
2381
2382 BOOL
2383 WINAPI
2384 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2385 {
2386 STUB;
2387 return FALSE;
2388 }
2389
2390 BOOL
2391 WINAPI
2392 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2393 {
2394 STUB;
2395 return FALSE;
2396 }
2397
2398 BOOL
2399 WINAPI
2400 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2401 {
2402 STUB;
2403 return FALSE;
2404 }
2405
2406 BOOL
2407 WINAPI
2408 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2409 {
2410 STUB;
2411 return FALSE;
2412 }
2413
2414 BOOL
2415 WINAPI
2416 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2417 {
2418 STUB;
2419 return FALSE;
2420 }
2421
2422 BOOL
2423 WINAPI
2424 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2425 {
2426 STUB;
2427 return FALSE;
2428 }
2429
2430 BOOL
2431 WINAPI
2432 RegisterConsoleOS2(BOOL bUnknown)
2433 {
2434 STUB;
2435 return FALSE;
2436 }
2437
2438 BOOL
2439 WINAPI
2440 SetConsoleOS2OemFormat(BOOL bUnknown)
2441 {
2442 STUB;
2443 return FALSE;
2444 }
2445
2446 BOOL
2447 WINAPI
2448 UnregisterConsoleIME(VOID)
2449 {
2450 STUB;
2451 return FALSE;
2452 }
2453
2454
2455 /*
2456 * @unimplemented
2457 */
2458 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2459 {
2460 STUB;
2461 return 0;
2462 }
2463
2464 /*
2465 * @unimplemented
2466 */
2467 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2468 {
2469 STUB;
2470 return 0;
2471 }
2472
2473 /*
2474 * @unimplemented
2475 */
2476 BOOL
2477 WINAPI
2478 SetLastConsoleEventActive(VOID)
2479 {
2480 STUB;
2481 return FALSE;
2482 }
2483
2484 /* EOF */