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