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