Sync with trunk r63343.
[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 NTSTATUS Status;
1506 CONSOLE_API_MESSAGE ApiMessage;
1507 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1508
1509 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1510 ScrollScreenBufferRequest->Unicode = bUnicode;
1511 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1512
1513 if (lpClipRectangle != NULL)
1514 {
1515 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1516 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1517 }
1518 else
1519 {
1520 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1521 }
1522
1523 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1524 ScrollScreenBufferRequest->Fill = *lpFill;
1525
1526 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1527 NULL,
1528 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1529 sizeof(CONSOLE_SCROLLSCREENBUFFER));
1530
1531 if (!NT_SUCCESS(Status))
1532 {
1533 BaseSetLastNTError(Status);
1534 return FALSE;
1535 }
1536
1537 return TRUE;
1538 }
1539
1540
1541 /*--------------------------------------------------------------
1542 * ScrollConsoleScreenBufferA
1543 *
1544 * @implemented
1545 */
1546 BOOL
1547 WINAPI
1548 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1549 CONST SMALL_RECT *lpScrollRectangle,
1550 CONST SMALL_RECT *lpClipRectangle,
1551 COORD dwDestinationOrigin,
1552 CONST CHAR_INFO *lpFill)
1553 {
1554 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1555 (PSMALL_RECT)lpScrollRectangle,
1556 (PSMALL_RECT)lpClipRectangle,
1557 dwDestinationOrigin,
1558 (PCHAR_INFO)lpFill,
1559 FALSE);
1560 }
1561
1562
1563 /*--------------------------------------------------------------
1564 * ScrollConsoleScreenBufferW
1565 *
1566 * @implemented
1567 */
1568 BOOL
1569 WINAPI
1570 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1571 CONST SMALL_RECT *lpScrollRectangle,
1572 CONST SMALL_RECT *lpClipRectangle,
1573 COORD dwDestinationOrigin,
1574 CONST CHAR_INFO *lpFill)
1575 {
1576 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1577 lpScrollRectangle,
1578 lpClipRectangle,
1579 dwDestinationOrigin,
1580 lpFill,
1581 TRUE);
1582 }
1583
1584
1585 /*--------------------------------------------------------------
1586 * SetConsoleWindowInfo
1587 *
1588 * @implemented
1589 */
1590 BOOL
1591 WINAPI
1592 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1593 BOOL bAbsolute,
1594 CONST SMALL_RECT *lpConsoleWindow)
1595 {
1596 CONSOLE_API_MESSAGE ApiMessage;
1597 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1598
1599 if (lpConsoleWindow == NULL)
1600 {
1601 SetLastError(ERROR_INVALID_PARAMETER);
1602 return FALSE;
1603 }
1604
1605 SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1606 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1607 SetWindowInfoRequest->Absolute = bAbsolute;
1608 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1609
1610 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1611 NULL,
1612 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1613 sizeof(*SetWindowInfoRequest));
1614 if (!NT_SUCCESS(ApiMessage.Status))
1615 {
1616 BaseSetLastNTError(ApiMessage.Status);
1617 return FALSE;
1618 }
1619
1620 return TRUE;
1621 }
1622
1623
1624 /*--------------------------------------------------------------
1625 * SetConsoleTextAttribute
1626 *
1627 * @implemented
1628 */
1629 BOOL
1630 WINAPI
1631 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1632 WORD wAttributes)
1633 {
1634 CONSOLE_API_MESSAGE ApiMessage;
1635 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest;
1636
1637 SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1638 SetTextAttribRequest->OutputHandle = hConsoleOutput;
1639 SetTextAttribRequest->Attributes = wAttributes;
1640
1641 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1642 NULL,
1643 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1644 sizeof(*SetTextAttribRequest));
1645 if (!NT_SUCCESS(ApiMessage.Status))
1646 {
1647 BaseSetLastNTError(ApiMessage.Status);
1648 return FALSE;
1649 }
1650
1651 return TRUE;
1652 }
1653
1654
1655 static
1656 BOOL
1657 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1658 {
1659 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1660
1661 if (HandlerRoutine == NULL)
1662 {
1663 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1664 return TRUE;
1665 }
1666
1667 if (NrCtrlHandlers == NrAllocatedHandlers)
1668 {
1669 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1670 0,
1671 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1672 if (NewCtrlHandlers == NULL)
1673 {
1674 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1675 return FALSE;
1676 }
1677
1678 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1679
1680 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1681
1682 CtrlHandlers = NewCtrlHandlers;
1683 NrAllocatedHandlers += 4;
1684 }
1685
1686 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1687
1688 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1689 return TRUE;
1690 }
1691
1692
1693 static
1694 BOOL
1695 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1696 {
1697 ULONG i;
1698
1699 if (HandlerRoutine == NULL)
1700 {
1701 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1702 return TRUE;
1703 }
1704
1705 for (i = 0; i < NrCtrlHandlers; i++)
1706 {
1707 if (CtrlHandlers[i] == HandlerRoutine)
1708 {
1709 if (i < (NrCtrlHandlers - 1))
1710 {
1711 memmove(&CtrlHandlers[i],
1712 &CtrlHandlers[i+1],
1713 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1714 }
1715
1716 NrCtrlHandlers--;
1717 return TRUE;
1718 }
1719 }
1720
1721 SetLastError(ERROR_INVALID_PARAMETER);
1722 return FALSE;
1723 }
1724
1725
1726 /*
1727 * @implemented
1728 */
1729 BOOL
1730 WINAPI
1731 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1732 BOOL Add)
1733 {
1734 BOOL Ret;
1735
1736 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1737 if (Add)
1738 {
1739 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1740 }
1741 else
1742 {
1743 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1744 }
1745
1746 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1747 return(Ret);
1748 }
1749
1750
1751 /*--------------------------------------------------------------
1752 * GenerateConsoleCtrlEvent
1753 *
1754 * @implemented
1755 */
1756 BOOL
1757 WINAPI
1758 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1759 DWORD dwProcessGroupId)
1760 {
1761 CONSOLE_API_MESSAGE ApiMessage;
1762 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &ApiMessage.Data.GenerateCtrlEventRequest;
1763
1764 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1765 {
1766 SetLastError(ERROR_INVALID_PARAMETER);
1767 return FALSE;
1768 }
1769
1770 GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1771 GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent;
1772 GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId;
1773
1774 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1775 NULL,
1776 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1777 sizeof(*GenerateCtrlEventRequest));
1778 if (!NT_SUCCESS(ApiMessage.Status))
1779 {
1780 BaseSetLastNTError(ApiMessage.Status);
1781 return FALSE;
1782 }
1783
1784 return TRUE;
1785 }
1786
1787
1788 static DWORD
1789 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode)
1790 {
1791 CONSOLE_API_MESSAGE ApiMessage;
1792 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1793 PCSR_CAPTURE_BUFFER CaptureBuffer;
1794
1795 if (dwNumChars == 0) return 0;
1796
1797 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1798 TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1799 TitleRequest->Unicode = bUnicode;
1800
1801 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1802 if (CaptureBuffer == NULL)
1803 {
1804 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1805 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1806 return 0;
1807 }
1808
1809 CsrAllocateMessagePointer(CaptureBuffer,
1810 TitleRequest->Length,
1811 (PVOID*)&TitleRequest->Title);
1812
1813 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1814 CaptureBuffer,
1815 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1816 sizeof(*TitleRequest));
1817 if (!NT_SUCCESS(ApiMessage.Status))
1818 {
1819 CsrFreeCaptureBuffer(CaptureBuffer);
1820 BaseSetLastNTError(ApiMessage.Status);
1821 return 0;
1822 }
1823
1824 dwNumChars = TitleRequest->Length / (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1825
1826 if (dwNumChars > 0)
1827 {
1828 memcpy(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length);
1829
1830 if (bUnicode)
1831 ((LPWSTR)lpConsoleTitle)[dwNumChars] = L'\0';
1832 else
1833 ((LPSTR)lpConsoleTitle)[dwNumChars] = '\0';
1834 }
1835
1836 CsrFreeCaptureBuffer(CaptureBuffer);
1837
1838 return dwNumChars;
1839 }
1840
1841
1842 /*--------------------------------------------------------------
1843 * GetConsoleTitleW
1844 *
1845 * @implemented
1846 */
1847 DWORD
1848 WINAPI
1849 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1850 DWORD nSize)
1851 {
1852 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1853 }
1854
1855
1856 /*--------------------------------------------------------------
1857 * GetConsoleTitleA
1858 *
1859 * @implemented
1860 */
1861 DWORD
1862 WINAPI
1863 GetConsoleTitleA(LPSTR lpConsoleTitle,
1864 DWORD nSize)
1865 {
1866 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1867 }
1868
1869
1870 static BOOL
1871 IntSetConsoleTitle(CONST VOID *lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode)
1872 {
1873 CONSOLE_API_MESSAGE ApiMessage;
1874 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1875 PCSR_CAPTURE_BUFFER CaptureBuffer;
1876
1877 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1878 TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1879 TitleRequest->Unicode = bUnicode;
1880
1881 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1882 if (CaptureBuffer == NULL)
1883 {
1884 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1885 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1886 return FALSE;
1887 }
1888
1889 CsrCaptureMessageBuffer(CaptureBuffer,
1890 (PVOID)lpConsoleTitle,
1891 TitleRequest->Length,
1892 (PVOID*)&TitleRequest->Title);
1893
1894 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1895 CaptureBuffer,
1896 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1897 sizeof(*TitleRequest));
1898
1899 CsrFreeCaptureBuffer(CaptureBuffer);
1900
1901 if (!NT_SUCCESS(ApiMessage.Status))
1902 {
1903 BaseSetLastNTError(ApiMessage.Status);
1904 return FALSE;
1905 }
1906
1907 return TRUE;
1908 }
1909
1910 /*--------------------------------------------------------------
1911 * SetConsoleTitleW
1912 *
1913 * @implemented
1914 */
1915 BOOL
1916 WINAPI
1917 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1918 {
1919 return IntSetConsoleTitle(lpConsoleTitle, wcslen(lpConsoleTitle), TRUE);
1920 }
1921
1922
1923 /*--------------------------------------------------------------
1924 * SetConsoleTitleA
1925 *
1926 * @implemented
1927 */
1928 BOOL
1929 WINAPI
1930 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1931 {
1932 return IntSetConsoleTitle(lpConsoleTitle, strlen(lpConsoleTitle), FALSE);
1933 }
1934
1935
1936 /*--------------------------------------------------------------
1937 * CreateConsoleScreenBuffer
1938 *
1939 * @implemented
1940 */
1941 HANDLE
1942 WINAPI
1943 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1944 DWORD dwShareMode,
1945 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1946 DWORD dwFlags,
1947 LPVOID lpScreenBufferData)
1948 {
1949 CONSOLE_API_MESSAGE ApiMessage;
1950 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1951 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1952 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = lpScreenBufferData;
1953
1954 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1955 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1956 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1957 {
1958 SetLastError(ERROR_INVALID_PARAMETER);
1959 return INVALID_HANDLE_VALUE;
1960 }
1961
1962 CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1963 CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess;
1964 CreateScreenBufferRequest->InheritHandle =
1965 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1966 CreateScreenBufferRequest->ShareMode = dwShareMode;
1967 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1968
1969 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1970 {
1971 if (CreateScreenBufferRequest->InheritHandle || GraphicsBufferInfo == NULL)
1972 {
1973 SetLastError(ERROR_INVALID_PARAMETER);
1974 return INVALID_HANDLE_VALUE;
1975 }
1976
1977 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
1978
1979 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
1980 if (CaptureBuffer == NULL)
1981 {
1982 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1983 return INVALID_HANDLE_VALUE;
1984 }
1985
1986 CsrCaptureMessageBuffer(CaptureBuffer,
1987 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
1988 GraphicsBufferInfo->dwBitMapInfoLength,
1989 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
1990 }
1991
1992 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1993 CaptureBuffer,
1994 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1995 sizeof(*CreateScreenBufferRequest));
1996
1997 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
1998
1999 if (!NT_SUCCESS(ApiMessage.Status))
2000 {
2001 BaseSetLastNTError(ApiMessage.Status);
2002 return INVALID_HANDLE_VALUE;
2003 }
2004
2005 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
2006 {
2007 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
2008 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
2009 }
2010
2011 return CreateScreenBufferRequest->OutputHandle;
2012 }
2013
2014
2015 /*--------------------------------------------------------------
2016 * GetConsoleCP
2017 *
2018 * @implemented
2019 */
2020 UINT
2021 WINAPI
2022 GetConsoleCP(VOID)
2023 {
2024 CONSOLE_API_MESSAGE ApiMessage;
2025 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2026
2027 /* Get the Input Code Page */
2028 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2029 GetConsoleCPRequest->OutputCP = FALSE;
2030
2031 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2032 NULL,
2033 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2034 sizeof(*GetConsoleCPRequest));
2035 if (!NT_SUCCESS(ApiMessage.Status))
2036 {
2037 BaseSetLastNTError(ApiMessage.Status);
2038 return 0;
2039 }
2040
2041 return GetConsoleCPRequest->CodePage;
2042 }
2043
2044
2045 /*--------------------------------------------------------------
2046 * SetConsoleCP
2047 *
2048 * @implemented
2049 */
2050 BOOL
2051 WINAPI
2052 SetConsoleCP(UINT wCodePageID)
2053 {
2054 CONSOLE_API_MESSAGE ApiMessage;
2055 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2056
2057 /* Set the Input Code Page */
2058 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2059 SetConsoleCPRequest->CodePage = wCodePageID;
2060 SetConsoleCPRequest->OutputCP = FALSE;
2061 /* SetConsoleCPRequest->EventHandle; */
2062
2063 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2064 NULL,
2065 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2066 sizeof(*SetConsoleCPRequest));
2067 if (!NT_SUCCESS(ApiMessage.Status))
2068 {
2069 BaseSetLastNTError(ApiMessage.Status);
2070 return FALSE;
2071 }
2072
2073 return TRUE;
2074 }
2075
2076
2077 /*--------------------------------------------------------------
2078 * GetConsoleOutputCP
2079 *
2080 * @implemented
2081 */
2082 UINT
2083 WINAPI
2084 GetConsoleOutputCP(VOID)
2085 {
2086 CONSOLE_API_MESSAGE ApiMessage;
2087 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2088
2089 /* Get the Output Code Page */
2090 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2091 GetConsoleCPRequest->OutputCP = TRUE;
2092
2093 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2094 NULL,
2095 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2096 sizeof(*GetConsoleCPRequest));
2097 if (!NT_SUCCESS(ApiMessage.Status))
2098 {
2099 BaseSetLastNTError(ApiMessage.Status);
2100 return 0;
2101 }
2102
2103 return GetConsoleCPRequest->CodePage;
2104 }
2105
2106
2107 /*--------------------------------------------------------------
2108 * SetConsoleOutputCP
2109 *
2110 * @implemented
2111 */
2112 BOOL
2113 WINAPI
2114 SetConsoleOutputCP(UINT wCodePageID)
2115 {
2116 CONSOLE_API_MESSAGE ApiMessage;
2117 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2118
2119 /* Set the Output Code Page */
2120 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2121 SetConsoleCPRequest->CodePage = wCodePageID;
2122 SetConsoleCPRequest->OutputCP = TRUE;
2123 /* SetConsoleCPRequest->EventHandle; */
2124
2125 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2126 NULL,
2127 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2128 sizeof(*SetConsoleCPRequest));
2129 if (!NT_SUCCESS(ApiMessage.Status))
2130 {
2131 BaseSetLastNTError(ApiMessage.Status);
2132 return FALSE;
2133 }
2134
2135 return TRUE;
2136 }
2137
2138
2139 /*--------------------------------------------------------------
2140 * GetConsoleProcessList
2141 *
2142 * @implemented
2143 */
2144 DWORD
2145 WINAPI
2146 GetConsoleProcessList(LPDWORD lpdwProcessList,
2147 DWORD dwProcessCount)
2148 {
2149 CONSOLE_API_MESSAGE ApiMessage;
2150 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2151 PCSR_CAPTURE_BUFFER CaptureBuffer;
2152 ULONG nProcesses = 0;
2153
2154 if (lpdwProcessList == NULL || dwProcessCount == 0)
2155 {
2156 SetLastError(ERROR_INVALID_PARAMETER);
2157 return 0;
2158 }
2159
2160 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2161 if (CaptureBuffer == NULL)
2162 {
2163 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2164 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2165 return 0;
2166 }
2167
2168 GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2169 GetProcessListRequest->ProcessCount = dwProcessCount;
2170
2171 CsrAllocateMessagePointer(CaptureBuffer,
2172 dwProcessCount * sizeof(DWORD),
2173 (PVOID*)&GetProcessListRequest->ProcessIdsList);
2174
2175 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2176 CaptureBuffer,
2177 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2178 sizeof(*GetProcessListRequest));
2179 if (!NT_SUCCESS(ApiMessage.Status))
2180 {
2181 BaseSetLastNTError(ApiMessage.Status);
2182 }
2183 else
2184 {
2185 nProcesses = GetProcessListRequest->ProcessCount;
2186 if (dwProcessCount >= nProcesses)
2187 {
2188 memcpy(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD));
2189 }
2190 }
2191
2192 CsrFreeCaptureBuffer(CaptureBuffer);
2193 return nProcesses;
2194 }
2195
2196
2197 /*--------------------------------------------------------------
2198 * GetConsoleSelectionInfo
2199 *
2200 * @implemented
2201 */
2202 BOOL
2203 WINAPI
2204 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2205 {
2206 CONSOLE_API_MESSAGE ApiMessage;
2207 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &ApiMessage.Data.GetSelectionInfoRequest;
2208
2209 if (lpConsoleSelectionInfo == NULL)
2210 {
2211 SetLastError(ERROR_INVALID_PARAMETER);
2212 return FALSE;
2213 }
2214
2215 GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2216
2217 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2218 NULL,
2219 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2220 sizeof(*GetSelectionInfoRequest));
2221 if (!NT_SUCCESS(ApiMessage.Status))
2222 {
2223 BaseSetLastNTError(ApiMessage.Status);
2224 return FALSE;
2225 }
2226
2227 *lpConsoleSelectionInfo = GetSelectionInfoRequest->Info;
2228
2229 return TRUE;
2230 }
2231
2232
2233 /*--------------------------------------------------------------
2234 * AttachConsole
2235 *
2236 * @implemented
2237 *
2238 * @note Strongly inspired by AllocConsole.
2239 */
2240 BOOL
2241 WINAPI
2242 AttachConsole(DWORD dwProcessId)
2243 {
2244 NTSTATUS Status;
2245 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2246 CONSOLE_API_MESSAGE ApiMessage;
2247 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2248
2249 if (Parameters->ConsoleHandle)
2250 {
2251 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2252 SetLastError(ERROR_ACCESS_DENIED);
2253 return FALSE;
2254 }
2255
2256 AttachConsoleRequest->ProcessId = dwProcessId;
2257 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2258 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2259
2260 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2261 NULL,
2262 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2263 sizeof(CONSOLE_ATTACHCONSOLE));
2264 if (!NT_SUCCESS(Status))
2265 {
2266 BaseSetLastNTError(Status);
2267 return FALSE;
2268 }
2269
2270 Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle;
2271 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2272 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2273 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2274
2275 /* Initialize Console Ctrl Handler */
2276 InitConsoleCtrlHandling();
2277
2278 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2279
2280 return TRUE;
2281 }
2282
2283
2284 /*--------------------------------------------------------------
2285 * GetConsoleWindow
2286 *
2287 * @implemented
2288 */
2289 HWND
2290 WINAPI
2291 GetConsoleWindow(VOID)
2292 {
2293 CONSOLE_API_MESSAGE ApiMessage;
2294 PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest;
2295
2296 GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2297
2298 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2299 NULL,
2300 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2301 sizeof(*GetWindowRequest));
2302 if (!NT_SUCCESS(ApiMessage.Status))
2303 {
2304 BaseSetLastNTError(ApiMessage.Status);
2305 return (HWND)NULL;
2306 }
2307
2308 return GetWindowRequest->WindowHandle;
2309 }
2310
2311
2312 /*--------------------------------------------------------------
2313 * SetConsoleIcon
2314 *
2315 * @implemented
2316 */
2317 BOOL
2318 WINAPI
2319 SetConsoleIcon(HICON hIcon)
2320 {
2321 CONSOLE_API_MESSAGE ApiMessage;
2322 PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest;
2323
2324 SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2325 SetIconRequest->IconHandle = hIcon;
2326
2327 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2328 NULL,
2329 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2330 sizeof(*SetIconRequest));
2331 if (!NT_SUCCESS(ApiMessage.Status))
2332 {
2333 BaseSetLastNTError(ApiMessage.Status);
2334 return FALSE;
2335 }
2336
2337 return TRUE;
2338 }
2339
2340
2341 /******************************************************************************
2342 * \name SetConsoleInputExeNameW
2343 * \brief Sets the console input file name from a unicode string.
2344 * \param lpInputExeName Pointer to a unicode string with the name.
2345 * \return TRUE if successful, FALSE if unsuccsedful.
2346 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2347 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2348 */
2349 BOOL
2350 WINAPI
2351 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2352 {
2353 int lenName;
2354
2355 if ( !lpInputExeName ||
2356 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2357 lenName > INPUTEXENAME_BUFLEN - 1 )
2358 {
2359 /* Fail if string is empty or too long */
2360 SetLastError(ERROR_INVALID_PARAMETER);
2361 return FALSE;
2362 }
2363
2364 RtlEnterCriticalSection(&ConsoleLock);
2365 _SEH2_TRY
2366 {
2367 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2368 InputExeName[lenName] = L'\0';
2369 }
2370 _SEH2_FINALLY
2371 {
2372 RtlLeaveCriticalSection(&ConsoleLock);
2373 }
2374 _SEH2_END;
2375
2376 return TRUE;
2377 }
2378
2379
2380 /******************************************************************************
2381 * \name SetConsoleInputExeNameA
2382 * \brief Sets the console input file name from an ansi string.
2383 * \param lpInputExeName Pointer to an ansi string with the name.
2384 * \return TRUE if successful, FALSE if unsuccsedful.
2385 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2386 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2387 */
2388 BOOL
2389 WINAPI
2390 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2391 {
2392 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2393 ANSI_STRING InputExeNameA;
2394 UNICODE_STRING InputExeNameU;
2395 NTSTATUS Status;
2396
2397 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2398
2399 if ( InputExeNameA.Length == 0 ||
2400 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2401 {
2402 /* Fail if string is empty or too long */
2403 SetLastError(ERROR_INVALID_PARAMETER);
2404 return FALSE;
2405 }
2406
2407 InputExeNameU.Buffer = Buffer;
2408 InputExeNameU.MaximumLength = sizeof(Buffer);
2409 InputExeNameU.Length = 0;
2410
2411 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2412 if (!NT_SUCCESS(Status))
2413 {
2414 BaseSetLastNTError(Status);
2415 return FALSE;
2416 }
2417
2418 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2419 }
2420
2421
2422 /******************************************************************************
2423 * \name GetConsoleInputExeNameW
2424 * \brief Retrieves the console input file name as unicode string.
2425 * \param nBufferLength Length of the buffer in WCHARs.
2426 * Specify 0 to receive the needed buffer length.
2427 * \param lpBuffer Pointer to a buffer that receives the string.
2428 * \return Needed buffer size if \p nBufferLength is 0.
2429 * Otherwise 1 if successful, 2 if buffer is too small.
2430 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2431 * is not big enough.
2432 */
2433 DWORD
2434 WINAPI
2435 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2436 {
2437 ULONG lenName = lstrlenW(InputExeName);
2438
2439 if (nBufferLength == 0)
2440 {
2441 /* Buffer size is requested, return it */
2442 return lenName + 1;
2443 }
2444
2445 if (lenName + 1 > nBufferLength)
2446 {
2447 /* Buffer is not large enough! */
2448 SetLastError(ERROR_BUFFER_OVERFLOW);
2449 return 2;
2450 }
2451
2452 RtlEnterCriticalSection(&ConsoleLock);
2453 _SEH2_TRY
2454 {
2455 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2456 lpBuffer[lenName] = '\0';
2457 }
2458 _SEH2_FINALLY
2459 {
2460 RtlLeaveCriticalSection(&ConsoleLock);
2461 }
2462 _SEH2_END;
2463
2464 /* Success, return 1 */
2465 return 1;
2466 }
2467
2468
2469 /******************************************************************************
2470 * \name GetConsoleInputExeNameA
2471 * \brief Retrieves the console input file name as ansi string.
2472 * \param nBufferLength Length of the buffer in CHARs.
2473 * \param lpBuffer Pointer to a buffer that receives the string.
2474 * \return 1 if successful, 2 if buffer is too small.
2475 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2476 * is not big enough. The buffer receives as much characters as fit.
2477 */
2478 DWORD
2479 WINAPI
2480 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2481 {
2482 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2483 DWORD Ret;
2484 UNICODE_STRING BufferU;
2485 ANSI_STRING BufferA;
2486
2487 /* Get the unicode name */
2488 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2489
2490 /* Initialize strings for conversion */
2491 RtlInitUnicodeString(&BufferU, Buffer);
2492 BufferA.Length = 0;
2493 BufferA.MaximumLength = (USHORT)nBufferLength;
2494 BufferA.Buffer = lpBuffer;
2495
2496 /* Convert unicode name to ansi, copying as much chars as fit */
2497 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2498
2499 /* Error handling */
2500 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2501 {
2502 SetLastError(ERROR_BUFFER_OVERFLOW);
2503 return 2;
2504 }
2505
2506 return Ret;
2507 }
2508
2509 BOOL
2510 WINAPI
2511 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2512 {
2513 STUB;
2514 return FALSE;
2515 }
2516
2517 BOOL
2518 WINAPI
2519 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2520 {
2521 STUB;
2522 return FALSE;
2523 }
2524
2525 BOOL
2526 WINAPI
2527 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2528 {
2529 STUB;
2530 return FALSE;
2531 }
2532
2533 BOOL
2534 WINAPI
2535 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2536 {
2537 STUB;
2538 return FALSE;
2539 }
2540
2541 BOOL
2542 WINAPI
2543 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2544 {
2545 STUB;
2546 return FALSE;
2547 }
2548
2549 BOOL
2550 WINAPI
2551 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2552 {
2553 STUB;
2554 return FALSE;
2555 }
2556
2557 BOOL
2558 WINAPI
2559 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2560 {
2561 STUB;
2562 return FALSE;
2563 }
2564
2565 BOOL
2566 WINAPI
2567 RegisterConsoleOS2(BOOL bUnknown)
2568 {
2569 STUB;
2570 return FALSE;
2571 }
2572
2573 BOOL
2574 WINAPI
2575 SetConsoleOS2OemFormat(BOOL bUnknown)
2576 {
2577 STUB;
2578 return FALSE;
2579 }
2580
2581 BOOL
2582 WINAPI
2583 UnregisterConsoleIME(VOID)
2584 {
2585 STUB;
2586 return FALSE;
2587 }
2588
2589
2590 /*
2591 * @unimplemented
2592 */
2593 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2594 {
2595 STUB;
2596 return 0;
2597 }
2598
2599 /*
2600 * @unimplemented
2601 */
2602 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2603 {
2604 STUB;
2605 return 0;
2606 }
2607
2608 /*
2609 * @implemented
2610 */
2611 DWORD
2612 WINAPI
2613 SetLastConsoleEventActive(VOID)
2614 {
2615 CONSOLE_API_MESSAGE ApiMessage;
2616 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest;
2617
2618 /* Set the flag used by the console control dispatcher */
2619 LastCloseNotify = TRUE;
2620
2621 /* Set up the input arguments */
2622 NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2623
2624 /* Call CSRSS; just return the NTSTATUS cast to DWORD */
2625 return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2626 NULL,
2627 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose),
2628 sizeof(*NotifyLastCloseRequest));
2629 }
2630
2631 /* EOF */