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