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