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