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