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