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