Sync with trunk (r48545)
[reactos.git] / dll / win32 / kernel32 / misc / console.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: dll/win32/kernel32/misc/console.c
6 * PURPOSE: Win32 server console functions
7 * PROGRAMMER: James Tabor
8 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
9 * UPDATE HISTORY:
10 * 199901?? ?? Created
11 * 19990204 EA SetConsoleTitleA
12 * 19990306 EA Stubs
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 #include <k32.h>
18
19 #define NDEBUG
20 #include <debug.h>
21
22 extern RTL_CRITICAL_SECTION ConsoleLock;
23 extern BOOL ConsoleInitialized;
24 extern BOOL WINAPI IsDebuggerPresent(VOID);
25
26 /* GLOBALS *******************************************************************/
27
28 PHANDLER_ROUTINE InitialHandler[1];
29 PHANDLER_ROUTINE* CtrlHandlers;
30 ULONG NrCtrlHandlers;
31 ULONG NrAllocatedHandlers;
32
33 #define INPUTEXENAME_BUFLEN 256
34 static WCHAR InputExeName[INPUTEXENAME_BUFLEN] = L"";
35
36 /* Default Console Control Handler *******************************************/
37
38 BOOL
39 WINAPI
40 DefaultConsoleCtrlHandler(DWORD Event)
41 {
42 DPRINT("Default handler called: %lx\n", Event);
43 switch(Event)
44 {
45 case CTRL_C_EVENT:
46 DPRINT("Ctrl-C Event\n");
47 break;
48
49 case CTRL_BREAK_EVENT:
50 DPRINT("Ctrl-Break Event\n");
51 break;
52
53 case CTRL_SHUTDOWN_EVENT:
54 DPRINT("Ctrl Shutdown 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
66 ExitProcess(CONTROL_C_EXIT);
67 return TRUE;
68 }
69
70 __declspec(noreturn)
71 VOID
72 CALLBACK
73 ConsoleControlDispatcher(DWORD CodeAndFlag)
74 {
75 DWORD nExitCode = 0;
76 DWORD nCode = CodeAndFlag & MAXLONG;
77 UINT i;
78 EXCEPTION_RECORD erException;
79
80 DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
81 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
82
83 switch(nCode)
84 {
85 case CTRL_C_EVENT:
86 case CTRL_BREAK_EVENT:
87 {
88 if (IsDebuggerPresent())
89 {
90 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
91 DBG_CONTROL_C : DBG_CONTROL_BREAK);
92 erException.ExceptionFlags = 0;
93 erException.ExceptionRecord = NULL;
94 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
95 erException.NumberParameters = 0;
96
97 _SEH2_TRY
98 {
99 RtlRaiseException(&erException);
100 }
101 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
102 {
103 RtlEnterCriticalSection(&ConsoleLock);
104
105 if ((nCode != CTRL_C_EVENT) ||
106 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
107 {
108 for (i = NrCtrlHandlers; i > 0; i--)
109 {
110 if (CtrlHandlers[i - 1](nCode)) break;
111 }
112 }
113
114 RtlLeaveCriticalSection(&ConsoleLock);
115 }
116 _SEH2_END;
117
118 ExitThread(0);
119 }
120
121 break;
122 }
123
124 case CTRL_CLOSE_EVENT:
125 case CTRL_LOGOFF_EVENT:
126 case CTRL_SHUTDOWN_EVENT:
127 break;
128
129 case 3:
130
131 ExitThread(0);
132 break;
133
134 case 4:
135
136 ExitProcess(CONTROL_C_EXIT);
137 break;
138
139 default:
140
141 ASSERT(FALSE);
142 break;
143 }
144
145 ASSERT(ConsoleInitialized);
146
147 RtlEnterCriticalSection(&ConsoleLock);
148 nExitCode = 0;
149 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
150 {
151 for (i = NrCtrlHandlers; i > 0; i--)
152 {
153 if ((i == 1) &&
154 (CodeAndFlag & MINLONG) &&
155 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
156 {
157 DPRINT("Skipping system/service apps\n");
158 break;
159 }
160
161 if (CtrlHandlers[i - 1](nCode))
162 {
163 switch(nCode)
164 {
165 case CTRL_CLOSE_EVENT:
166 case CTRL_LOGOFF_EVENT:
167 case CTRL_SHUTDOWN_EVENT:
168 case 3:
169 nExitCode = CodeAndFlag;
170 break;
171 }
172 break;
173 }
174 }
175 }
176
177 RtlLeaveCriticalSection(&ConsoleLock);
178 ExitThread(nExitCode);
179 }
180
181 /* Get the size needed to copy a string to a capture buffer, including alignment */
182 static ULONG
183 IntStringSize(LPCVOID String,
184 BOOL Unicode)
185 {
186 ULONG Size = (Unicode ? wcslen(String) : strlen(String)) * sizeof(WCHAR);
187 return (Size + 3) & -4;
188 }
189
190 /* Copy a string to a capture buffer */
191 static VOID
192 IntCaptureMessageString(PCSR_CAPTURE_BUFFER CaptureBuffer,
193 LPCVOID String,
194 BOOL Unicode,
195 PUNICODE_STRING RequestString)
196 {
197 ULONG Size;
198 if (Unicode)
199 {
200 Size = wcslen(String) * sizeof(WCHAR);
201 CsrCaptureMessageBuffer(CaptureBuffer, (PVOID)String, Size, (PVOID *)&RequestString->Buffer);
202 }
203 else
204 {
205 Size = strlen(String);
206 CsrAllocateMessagePointer(CaptureBuffer, Size * sizeof(WCHAR), (PVOID *)&RequestString->Buffer);
207 Size = MultiByteToWideChar(CP_ACP, 0, String, Size, RequestString->Buffer, Size * sizeof(WCHAR))
208 * sizeof(WCHAR);
209 }
210 RequestString->Length = RequestString->MaximumLength = Size;
211 }
212
213 /* FUNCTIONS *****************************************************************/
214
215 /*
216 * @implemented
217 */
218 BOOL
219 WINAPI
220 AddConsoleAliasA(LPCSTR lpSource,
221 LPCSTR lpTarget,
222 LPCSTR lpExeName)
223 {
224 LPWSTR lpSourceW = NULL;
225 LPWSTR lpTargetW = NULL;
226 LPWSTR lpExeNameW = NULL;
227 BOOL bRetVal;
228
229 if (lpSource)
230 BasepAnsiStringToHeapUnicodeString(lpSource, (LPWSTR*) &lpSourceW);
231 if (lpTarget)
232 BasepAnsiStringToHeapUnicodeString(lpTarget, (LPWSTR*) &lpTargetW);
233 if (lpExeName)
234 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
235
236 bRetVal = AddConsoleAliasW(lpSourceW, lpTargetW, lpExeNameW);
237
238 /* Clean up */
239 if (lpSourceW)
240 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpSourceW);
241 if (lpTargetW)
242 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpTargetW);
243 if (lpExeNameW)
244 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
245
246 return bRetVal;
247 }
248
249
250 /*
251 * @unimplemented
252 */
253 BOOL
254 WINAPI
255 AddConsoleAliasW(LPCWSTR lpSource,
256 LPCWSTR lpTarget,
257 LPCWSTR lpExeName)
258 {
259 PCSR_API_MESSAGE Request;
260 ULONG CsrRequest;
261 NTSTATUS Status;
262 ULONG SourceLength;
263 ULONG TargetLength = 0;
264 ULONG ExeLength;
265 ULONG Size;
266 ULONG RequestLength;
267 WCHAR * Ptr;
268
269 DPRINT("AddConsoleAliasW enterd with lpSource %S lpTarget %S lpExeName %S\n", lpSource, lpTarget, lpExeName);
270
271 ExeLength = wcslen(lpExeName) + 1;
272 SourceLength = wcslen(lpSource)+ 1;
273 if (lpTarget)
274 TargetLength = wcslen(lpTarget) + 1;
275
276 Size = (ExeLength + SourceLength + TargetLength) * sizeof(WCHAR);
277 RequestLength = sizeof(CSR_API_MESSAGE) + Size;
278
279 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RequestLength);
280 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE));
281
282 wcscpy(Ptr, lpSource);
283 Request->Data.AddConsoleAlias.SourceLength = SourceLength;
284 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + SourceLength * sizeof(WCHAR));
285
286 wcscpy(Ptr, lpExeName);
287 Request->Data.AddConsoleAlias.ExeLength = ExeLength;
288 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + (ExeLength + SourceLength)* sizeof(WCHAR));
289
290 if (lpTarget) /* target can be optional */
291 wcscpy(Ptr, lpTarget);
292
293 Request->Data.AddConsoleAlias.TargetLength = TargetLength;
294
295 CsrRequest = MAKE_CSR_API(ADD_CONSOLE_ALIAS, CSR_CONSOLE);
296 Status = CsrClientCallServer(Request,
297 NULL,
298 CsrRequest,
299 RequestLength);
300
301 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
302 {
303 SetLastErrorByStatus(Status);
304 RtlFreeHeap(GetProcessHeap(), 0, Request);
305 return FALSE;
306 }
307
308 RtlFreeHeap(GetProcessHeap(), 0, Request);
309 return TRUE;
310 }
311
312
313 /*
314 * @unimplemented (Undocumented)
315 */
316 BOOL
317 WINAPI
318 ConsoleMenuControl(HANDLE hConsole,
319 DWORD Unknown1,
320 DWORD Unknown2)
321 {
322 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
323 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
324 return FALSE;
325 }
326
327
328 /*
329 * @implemented
330 */
331 HANDLE
332 WINAPI
333 DuplicateConsoleHandle(HANDLE hConsole,
334 DWORD dwDesiredAccess,
335 BOOL bInheritHandle,
336 DWORD dwOptions)
337 {
338 CSR_API_MESSAGE Request;
339 ULONG CsrRequest;
340 NTSTATUS Status;
341
342 if (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
343 || (!(dwOptions & DUPLICATE_SAME_ACCESS)
344 && dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)))
345 {
346 SetLastError (ERROR_INVALID_PARAMETER);
347 return INVALID_HANDLE_VALUE;
348 }
349
350 CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
351 Request.Data.DuplicateHandleRequest.Handle = hConsole;
352 Request.Data.DuplicateHandleRequest.Access = dwDesiredAccess;
353 Request.Data.DuplicateHandleRequest.Inheritable = bInheritHandle;
354 Request.Data.DuplicateHandleRequest.Options = dwOptions;
355
356 Status = CsrClientCallServer(&Request,
357 NULL,
358 CsrRequest,
359 sizeof(CSR_API_MESSAGE));
360 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
361 {
362 SetLastErrorByStatus(Status);
363 return INVALID_HANDLE_VALUE;
364 }
365
366 return Request.Data.DuplicateHandleRequest.Handle;
367 }
368
369
370 static BOOL
371 IntExpungeConsoleCommandHistory(LPCVOID lpExeName, BOOL bUnicode)
372 {
373 CSR_API_MESSAGE Request;
374 PCSR_CAPTURE_BUFFER CaptureBuffer;
375 ULONG CsrRequest = MAKE_CSR_API(EXPUNGE_COMMAND_HISTORY, CSR_CONSOLE);
376 NTSTATUS Status;
377
378 if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
379 {
380 SetLastError(ERROR_INVALID_PARAMETER);
381 return FALSE;
382 }
383
384 CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
385 if (!CaptureBuffer)
386 {
387 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
388 return FALSE;
389 }
390 IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
391 &Request.Data.ExpungeCommandHistory.ExeName);
392 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
393 CsrFreeCaptureBuffer(CaptureBuffer);
394 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
395 {
396 SetLastErrorByStatus(Status);
397 return FALSE;
398 }
399 return TRUE;
400 }
401
402 /*
403 * @implemented (Undocumented)
404 */
405 BOOL
406 WINAPI
407 ExpungeConsoleCommandHistoryW(LPCWSTR lpExeName)
408 {
409 return IntExpungeConsoleCommandHistory(lpExeName, TRUE);
410 }
411
412 /*
413 * @implemented (Undocumented)
414 */
415 BOOL
416 WINAPI
417 ExpungeConsoleCommandHistoryA(LPCSTR lpExeName)
418 {
419 return IntExpungeConsoleCommandHistory(lpExeName, FALSE);
420 }
421
422
423 /*
424 * @implemented
425 */
426 DWORD
427 WINAPI
428 GetConsoleAliasW(LPWSTR lpSource,
429 LPWSTR lpTargetBuffer,
430 DWORD TargetBufferLength,
431 LPWSTR lpExeName)
432 {
433 PCSR_API_MESSAGE Request;
434 PCSR_CAPTURE_BUFFER CaptureBuffer;
435 ULONG CsrRequest;
436 NTSTATUS Status;
437 ULONG Size;
438 ULONG ExeLength;
439 ULONG SourceLength;
440 ULONG RequestLength;
441 WCHAR * Ptr;
442
443 DPRINT("GetConsoleAliasW entered lpSource %S lpExeName %S\n", lpSource, lpExeName);
444
445 if (lpTargetBuffer == NULL)
446 {
447 SetLastError(ERROR_INVALID_PARAMETER);
448 return 0;
449 }
450
451 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIAS, CSR_CONSOLE);
452
453 ExeLength = wcslen(lpExeName) + 1;
454 SourceLength = wcslen(lpSource) + 1;
455
456 Size = (ExeLength + SourceLength) * sizeof(WCHAR);
457
458 RequestLength = Size + sizeof(CSR_API_MESSAGE);
459 Request = RtlAllocateHeap(GetProcessHeap(), 0, RequestLength);
460 if (Request == NULL)
461 {
462 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
463 return 0;
464 }
465
466 CaptureBuffer = CsrAllocateCaptureBuffer(1, TargetBufferLength);
467 if (!CaptureBuffer)
468 {
469 RtlFreeHeap(GetProcessHeap(), 0, Request);
470 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
471 return 0;
472 }
473
474 Request->Data.GetConsoleAlias.TargetBuffer = NULL;
475
476 CsrCaptureMessageBuffer(CaptureBuffer,
477 NULL,
478 TargetBufferLength,
479 (PVOID*)&Request->Data.GetConsoleAlias.TargetBuffer);
480
481 Request->Data.GetConsoleAlias.TargetBufferLength = TargetBufferLength;
482
483 Ptr = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
484 wcscpy(Ptr, lpSource);
485 Ptr += SourceLength;
486 wcscpy(Ptr, lpExeName);
487
488 Request->Data.GetConsoleAlias.ExeLength = ExeLength;
489 Request->Data.GetConsoleAlias.SourceLength = SourceLength;
490
491 Status = CsrClientCallServer(Request,
492 CaptureBuffer,
493 CsrRequest,
494 sizeof(CSR_API_MESSAGE) + Size);
495
496 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
497 {
498 RtlFreeHeap(GetProcessHeap(), 0, Request);
499 CsrFreeCaptureBuffer(CaptureBuffer);
500 SetLastErrorByStatus(Status);
501 return 0;
502 }
503
504 wcscpy(lpTargetBuffer, Request->Data.GetConsoleAlias.TargetBuffer);
505 RtlFreeHeap(GetProcessHeap(), 0, Request);
506 CsrFreeCaptureBuffer(CaptureBuffer);
507
508 return Request->Data.GetConsoleAlias.BytesWritten;
509 }
510
511
512 /*
513 * @implemented
514 */
515 DWORD
516 WINAPI
517 GetConsoleAliasA(LPSTR lpSource,
518 LPSTR lpTargetBuffer,
519 DWORD TargetBufferLength,
520 LPSTR lpExeName)
521 {
522 LPWSTR lpwSource;
523 LPWSTR lpwExeName;
524 LPWSTR lpwTargetBuffer;
525 UINT dwSourceSize;
526 UINT dwExeNameSize;
527 UINT dwResult;
528
529 DPRINT("GetConsoleAliasA entered\n");
530
531 if (lpTargetBuffer == NULL)
532 {
533 SetLastError(ERROR_INVALID_PARAMETER);
534 return 0;
535 }
536
537 dwSourceSize = (strlen(lpSource)+1) * sizeof(WCHAR);
538 lpwSource = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceSize);
539 if (lpwSource == NULL)
540 {
541 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
542 return 0;
543 }
544 MultiByteToWideChar(CP_ACP, 0, lpSource, -1, lpwSource, dwSourceSize);
545
546 dwExeNameSize = (strlen(lpExeName)+1) * sizeof(WCHAR);
547 lpwExeName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwExeNameSize);
548 if (lpwExeName == NULL)
549 {
550 HeapFree(GetProcessHeap(), 0, lpwSource);
551 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
552 return 0;
553 }
554 MultiByteToWideChar(CP_ACP, 0, lpExeName, -1, lpwExeName, dwExeNameSize);
555
556 lpwTargetBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, TargetBufferLength * sizeof(WCHAR));
557 if (lpwTargetBuffer == NULL)
558 {
559 HeapFree(GetProcessHeap(), 0, lpwSource);
560 HeapFree(GetProcessHeap(), 0, lpwExeName);
561 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
562 return 0;
563 }
564
565 dwResult = GetConsoleAliasW(lpwSource, lpwTargetBuffer, TargetBufferLength * sizeof(WCHAR), lpwExeName);
566
567 HeapFree(GetProcessHeap(), 0, lpwSource);
568 HeapFree(GetProcessHeap(), 0, lpwExeName);
569
570 if (dwResult)
571 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwTargetBuffer, dwResult / sizeof(WCHAR), lpTargetBuffer, TargetBufferLength, NULL, NULL);
572
573 HeapFree(GetProcessHeap(), 0, lpwTargetBuffer);
574
575 return dwResult;
576 }
577
578
579 /*
580 * @implemented
581 */
582 DWORD
583 WINAPI
584 GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
585 DWORD ExeNameBufferLength)
586 {
587 CSR_API_MESSAGE Request;
588 PCSR_CAPTURE_BUFFER CaptureBuffer;
589 ULONG CsrRequest;
590 NTSTATUS Status;
591
592 DPRINT("GetConsoleAliasExesW entered\n");
593
594 CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
595 if (!CaptureBuffer)
596 {
597 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
598 return 0;
599 }
600
601 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES, CSR_CONSOLE);
602 CsrAllocateMessagePointer(CaptureBuffer,
603 ExeNameBufferLength,
604 (PVOID*)&Request.Data.GetConsoleAliasesExes.ExeNames);
605 Request.Data.GetConsoleAliasesExes.Length = ExeNameBufferLength;
606
607 Status = CsrClientCallServer(&Request,
608 CaptureBuffer,
609 CsrRequest,
610 sizeof(CSR_API_MESSAGE));
611
612 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
613 {
614 SetLastErrorByStatus(Status);
615 CsrFreeCaptureBuffer(CaptureBuffer);
616 return 0;
617 }
618
619 memcpy(lpExeNameBuffer,
620 Request.Data.GetConsoleAliasesExes.ExeNames,
621 Request.Data.GetConsoleAliasesExes.BytesWritten);
622
623 CsrFreeCaptureBuffer(CaptureBuffer);
624 return Request.Data.GetConsoleAliasesExes.BytesWritten;
625 }
626
627
628 /*
629 * @implemented
630 */
631 DWORD
632 WINAPI
633 GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
634 DWORD ExeNameBufferLength)
635 {
636 LPWSTR lpwExeNameBuffer;
637 DWORD dwResult;
638
639 DPRINT("GetConsoleAliasExesA entered\n");
640
641 lpwExeNameBuffer = HeapAlloc(GetProcessHeap(), 0, ExeNameBufferLength * sizeof(WCHAR));
642
643 dwResult = GetConsoleAliasExesW(lpwExeNameBuffer, ExeNameBufferLength * sizeof(WCHAR));
644
645 if (dwResult)
646 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwExeNameBuffer, dwResult / sizeof(WCHAR), lpExeNameBuffer, ExeNameBufferLength, NULL, NULL);
647
648 HeapFree(GetProcessHeap(), 0, lpwExeNameBuffer);
649 return dwResult;
650 }
651
652 /*
653 * @implemented
654 */
655 DWORD
656 WINAPI
657 GetConsoleAliasExesLengthW(VOID)
658 {
659 CSR_API_MESSAGE Request;
660 ULONG CsrRequest;
661 NTSTATUS Status;
662
663 DPRINT("GetConsoleAliasExesLengthW entered\n");
664
665 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CSR_CONSOLE);
666 Request.Data.GetConsoleAliasesExesLength.Length = 0;
667
668
669 Status = CsrClientCallServer(&Request,
670 NULL,
671 CsrRequest,
672 sizeof(CSR_API_MESSAGE));
673
674 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
675 {
676 SetLastErrorByStatus(Status);
677 return 0;
678 }
679
680 return Request.Data.GetConsoleAliasesExesLength.Length;
681 }
682
683 /*
684 * @implemented
685 */
686 DWORD
687 WINAPI
688 GetConsoleAliasExesLengthA(VOID)
689 {
690 DWORD dwLength;
691
692 DPRINT("GetConsoleAliasExesLengthA entered\n");
693
694 dwLength = GetConsoleAliasExesLengthW();
695
696 if (dwLength)
697 dwLength /= sizeof(WCHAR);
698
699 return dwLength;
700 }
701
702
703 /*
704 * @implemented
705 */
706 DWORD
707 WINAPI
708 GetConsoleAliasesW(LPWSTR AliasBuffer,
709 DWORD AliasBufferLength,
710 LPWSTR ExeName)
711 {
712 CSR_API_MESSAGE Request;
713 ULONG CsrRequest;
714 NTSTATUS Status;
715 DWORD dwLength;
716
717 DPRINT("GetConsoleAliasesW entered\n");
718
719 dwLength = GetConsoleAliasesLengthW(ExeName);
720 if (!dwLength || dwLength > AliasBufferLength)
721 return 0;
722
723 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES, CSR_CONSOLE);
724 Request.Data.GetAllConsoleAlias.AliasBuffer = AliasBuffer;
725 Request.Data.GetAllConsoleAlias.AliasBufferLength = AliasBufferLength;
726 Request.Data.GetAllConsoleAlias.lpExeName = ExeName;
727
728 Status = CsrClientCallServer(&Request,
729 NULL,
730 CsrRequest,
731 sizeof(CSR_API_MESSAGE));
732
733 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
734 {
735 SetLastErrorByStatus(Status);
736 return 0;
737 }
738
739 return Request.Data.GetAllConsoleAlias.BytesWritten / sizeof(WCHAR);
740 }
741
742
743 /*
744 * @implemented
745 */
746 DWORD
747 WINAPI
748 GetConsoleAliasesA(LPSTR AliasBuffer,
749 DWORD AliasBufferLength,
750 LPSTR ExeName)
751 {
752 DWORD dwRetVal = 0;
753 LPWSTR lpwExeName = NULL;
754 LPWSTR lpwAliasBuffer;
755
756 DPRINT("GetConsoleAliasesA entered\n");
757
758 if (ExeName)
759 BasepAnsiStringToHeapUnicodeString(ExeName, (LPWSTR*) &lpwExeName);
760
761 lpwAliasBuffer = HeapAlloc(GetProcessHeap(), 0, AliasBufferLength * sizeof(WCHAR));
762
763 dwRetVal = GetConsoleAliasesW(lpwAliasBuffer, AliasBufferLength, lpwExeName);
764
765 if (lpwExeName)
766 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpwExeName);
767
768 if (dwRetVal)
769 dwRetVal = WideCharToMultiByte(CP_ACP, 0, lpwAliasBuffer, dwRetVal, AliasBuffer, AliasBufferLength, NULL, NULL);
770
771 HeapFree(GetProcessHeap(), 0, lpwAliasBuffer);
772 return dwRetVal;
773 }
774
775
776 /*
777 * @implemented
778 */
779 DWORD
780 WINAPI
781 GetConsoleAliasesLengthW(LPWSTR lpExeName)
782 {
783 CSR_API_MESSAGE Request;
784 ULONG CsrRequest;
785 NTSTATUS Status;
786
787 DPRINT("GetConsoleAliasesLengthW entered\n");
788
789 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CSR_CONSOLE);
790 Request.Data.GetAllConsoleAliasesLength.lpExeName = lpExeName;
791 Request.Data.GetAllConsoleAliasesLength.Length = 0;
792
793 Status = CsrClientCallServer(&Request,
794 NULL,
795 CsrRequest,
796 sizeof(CSR_API_MESSAGE));
797
798 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
799 {
800 SetLastErrorByStatus(Status);
801 return 0;
802 }
803
804 return Request.Data.GetAllConsoleAliasesLength.Length;
805 }
806
807
808 /*
809 * @implemented
810 */
811 DWORD
812 WINAPI
813 GetConsoleAliasesLengthA(LPSTR lpExeName)
814 {
815 DWORD dwRetVal = 0;
816 LPWSTR lpExeNameW = NULL;
817
818 if (lpExeName)
819 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
820
821 dwRetVal = GetConsoleAliasesLengthW(lpExeNameW);
822 if (dwRetVal)
823 dwRetVal /= sizeof(WCHAR);
824
825 /* Clean up */
826 if (lpExeNameW)
827 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
828
829 return dwRetVal;
830 }
831
832
833 static DWORD
834 IntGetConsoleCommandHistory(LPVOID lpHistory, DWORD cbHistory, LPCVOID lpExeName, BOOL bUnicode)
835 {
836 CSR_API_MESSAGE Request;
837 PCSR_CAPTURE_BUFFER CaptureBuffer;
838 ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY, CSR_CONSOLE);
839 NTSTATUS Status;
840 DWORD HistoryLength = cbHistory * (bUnicode ? 1 : sizeof(WCHAR));
841
842 if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
843 {
844 SetLastError(ERROR_INVALID_PARAMETER);
845 return 0;
846 }
847
848 CaptureBuffer = CsrAllocateCaptureBuffer(2, IntStringSize(lpExeName, bUnicode) +
849 HistoryLength);
850 if (!CaptureBuffer)
851 {
852 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
853 return 0;
854 }
855 IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
856 &Request.Data.GetCommandHistory.ExeName);
857 Request.Data.GetCommandHistory.Length = HistoryLength;
858 CsrAllocateMessagePointer(CaptureBuffer, HistoryLength,
859 (PVOID*)&Request.Data.GetCommandHistory.History);
860
861 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
862 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
863 {
864 CsrFreeCaptureBuffer(CaptureBuffer);
865 SetLastErrorByStatus(Status);
866 return 0;
867 }
868
869 if (bUnicode)
870 {
871 memcpy(lpHistory,
872 Request.Data.GetCommandHistory.History,
873 Request.Data.GetCommandHistory.Length);
874 }
875 else
876 {
877 WideCharToMultiByte(CP_ACP, 0,
878 Request.Data.GetCommandHistory.History,
879 Request.Data.GetCommandHistory.Length / sizeof(WCHAR),
880 lpHistory,
881 cbHistory,
882 NULL, NULL);
883 }
884 CsrFreeCaptureBuffer(CaptureBuffer);
885 return Request.Data.GetCommandHistory.Length;
886 }
887
888 /*
889 * @implemented (Undocumented)
890 */
891 DWORD
892 WINAPI
893 GetConsoleCommandHistoryW(LPWSTR lpHistory,
894 DWORD cbHistory,
895 LPCWSTR lpExeName)
896 {
897 return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, TRUE);
898 }
899
900 /*
901 * @implemented (Undocumented)
902 */
903 DWORD
904 WINAPI
905 GetConsoleCommandHistoryA(LPSTR lpHistory,
906 DWORD cbHistory,
907 LPCSTR lpExeName)
908 {
909 return IntGetConsoleCommandHistory(lpHistory, cbHistory, lpExeName, FALSE);
910 }
911
912
913 static DWORD
914 IntGetConsoleCommandHistoryLength(LPCVOID lpExeName, BOOL bUnicode)
915 {
916 CSR_API_MESSAGE Request;
917 PCSR_CAPTURE_BUFFER CaptureBuffer;
918 ULONG CsrRequest = MAKE_CSR_API(GET_COMMAND_HISTORY_LENGTH, CSR_CONSOLE);
919 NTSTATUS Status;
920
921 if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
922 {
923 SetLastError(ERROR_INVALID_PARAMETER);
924 return 0;
925 }
926
927 CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
928 if (!CaptureBuffer)
929 {
930 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
931 return 0;
932 }
933 IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
934 &Request.Data.GetCommandHistoryLength.ExeName);
935 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
936 CsrFreeCaptureBuffer(CaptureBuffer);
937 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
938 {
939 SetLastErrorByStatus(Status);
940 return 0;
941 }
942 return Request.Data.GetCommandHistoryLength.Length;
943 }
944
945 /*
946 * @implemented (Undocumented)
947 */
948 DWORD
949 WINAPI
950 GetConsoleCommandHistoryLengthW(LPCWSTR lpExeName)
951 {
952 return IntGetConsoleCommandHistoryLength(lpExeName, TRUE);
953 }
954
955 /*
956 * @implemented (Undocumented)
957 */
958 DWORD
959 WINAPI
960 GetConsoleCommandHistoryLengthA(LPCSTR lpExeName)
961 {
962 return IntGetConsoleCommandHistoryLength(lpExeName, FALSE) / sizeof(WCHAR);
963 }
964
965
966 /*
967 * @unimplemented
968 */
969 INT
970 WINAPI
971 GetConsoleDisplayMode(LPDWORD lpdwMode)
972 /*
973 * FUNCTION: Get the console display mode
974 * ARGUMENTS:
975 * lpdwMode - Address of variable that receives the current value
976 * of display mode
977 * STATUS: Undocumented
978 */
979 {
980 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
981 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
982 return 0;
983 }
984
985
986 /*
987 * @unimplemented (Undocumented)
988 */
989 DWORD
990 WINAPI
991 GetConsoleFontInfo(DWORD Unknown0,
992 DWORD Unknown1,
993 DWORD Unknown2,
994 DWORD Unknown3)
995 {
996 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
997 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
998 return 0;
999 }
1000
1001
1002 /*
1003 * @unimplemented
1004 */
1005 COORD
1006 WINAPI
1007 GetConsoleFontSize(HANDLE hConsoleOutput,
1008 DWORD nFont)
1009 {
1010 COORD Empty = {0, 0};
1011 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
1012 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1013 return Empty;
1014 }
1015
1016
1017 /*
1018 * @implemented (Undocumented)
1019 */
1020 DWORD
1021 WINAPI
1022 GetConsoleHardwareState(HANDLE hConsole,
1023 DWORD Flags,
1024 PDWORD State)
1025 {
1026 CSR_API_MESSAGE Request;
1027 ULONG CsrRequest;
1028 NTSTATUS Status;
1029
1030 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
1031 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
1032 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
1033
1034 Status = CsrClientCallServer(&Request,
1035 NULL,
1036 CsrRequest,
1037 sizeof(CSR_API_MESSAGE));
1038 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1039 {
1040 SetLastErrorByStatus(Status);
1041 return FALSE;
1042 }
1043
1044 *State = Request.Data.ConsoleHardwareStateRequest.State;
1045 return TRUE;
1046 }
1047
1048
1049 /*
1050 * @implemented (Undocumented)
1051 */
1052 HANDLE
1053 WINAPI
1054 GetConsoleInputWaitHandle(VOID)
1055 {
1056 CSR_API_MESSAGE Request;
1057 ULONG CsrRequest;
1058 NTSTATUS Status;
1059
1060 CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
1061
1062 Status = CsrClientCallServer(&Request,
1063 NULL,
1064 CsrRequest,
1065 sizeof(CSR_API_MESSAGE));
1066 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1067 {
1068 SetLastErrorByStatus(Status);
1069 return 0;
1070 }
1071
1072 return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
1073 }
1074
1075
1076 /*
1077 * @unimplemented
1078 */
1079 INT
1080 WINAPI
1081 GetCurrentConsoleFont(HANDLE hConsoleOutput,
1082 BOOL bMaximumWindow,
1083 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
1084 {
1085 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
1086 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1087 return 0;
1088 }
1089
1090
1091 /*
1092 * @unimplemented (Undocumented)
1093 */
1094 ULONG
1095 WINAPI
1096 GetNumberOfConsoleFonts(VOID)
1097 {
1098 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
1099 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1100 return 1; /* FIXME: call csrss.exe */
1101 }
1102
1103
1104 /*
1105 * @unimplemented (Undocumented)
1106 */
1107 DWORD
1108 WINAPI
1109 InvalidateConsoleDIBits(DWORD Unknown0,
1110 DWORD Unknown1)
1111 {
1112 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1113 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1114 return 0;
1115 }
1116
1117
1118 /*
1119 * @unimplemented (Undocumented)
1120 */
1121 HANDLE
1122 WINAPI
1123 OpenConsoleW(LPCWSTR wsName,
1124 DWORD dwDesiredAccess,
1125 BOOL bInheritHandle,
1126 DWORD dwShareMode)
1127 {
1128 CSR_API_MESSAGE Request;
1129 ULONG CsrRequest;
1130 NTSTATUS Status = STATUS_SUCCESS;
1131
1132 if (wsName && 0 == _wcsicmp(wsName, L"CONIN$"))
1133 {
1134 CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
1135 }
1136 else if (wsName && 0 == _wcsicmp(wsName, L"CONOUT$"))
1137 {
1138 CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
1139 }
1140 else
1141 {
1142 SetLastError(ERROR_INVALID_PARAMETER);
1143 return(INVALID_HANDLE_VALUE);
1144 }
1145
1146 if (dwDesiredAccess & ~(GENERIC_READ|GENERIC_WRITE))
1147 {
1148 SetLastError(ERROR_INVALID_PARAMETER);
1149 return(INVALID_HANDLE_VALUE);
1150 }
1151
1152 if (dwShareMode & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))
1153 {
1154 SetLastError(ERROR_INVALID_PARAMETER);
1155 return(INVALID_HANDLE_VALUE);
1156 }
1157
1158 /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
1159 Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
1160 Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
1161 Request.Data.GetInputHandleRequest.ShareMode = dwShareMode;
1162
1163 Status = CsrClientCallServer(&Request,
1164 NULL,
1165 CsrRequest,
1166 sizeof(CSR_API_MESSAGE));
1167 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1168 {
1169 SetLastErrorByStatus(Status);
1170 return INVALID_HANDLE_VALUE;
1171 }
1172
1173 return Request.Data.GetInputHandleRequest.Handle;
1174 }
1175
1176
1177 /*
1178 * @unimplemented (Undocumented)
1179 */
1180 BOOL
1181 WINAPI
1182 SetConsoleCursor(DWORD Unknown0,
1183 DWORD Unknown1)
1184 {
1185 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1186 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1187 return FALSE;
1188 }
1189
1190
1191 /*
1192 * @unimplemented
1193 */
1194 BOOL
1195 WINAPI
1196 SetConsoleDisplayMode(HANDLE hOut,
1197 DWORD dwNewMode,
1198 PCOORD lpdwOldMode)
1199 /*
1200 * FUNCTION: Set the console display mode.
1201 * ARGUMENTS:
1202 * hOut - Standard output handle.
1203 * dwNewMode - New mode.
1204 * lpdwOldMode - Address of a variable that receives the old mode.
1205 */
1206 {
1207 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
1208 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1209 return FALSE;
1210 }
1211
1212
1213 /*
1214 * @unimplemented (Undocumented)
1215 */
1216 BOOL
1217 WINAPI
1218 SetConsoleFont(DWORD Unknown0,
1219 DWORD Unknown1)
1220 {
1221 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1222 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1223 return FALSE;
1224 }
1225
1226
1227 /*
1228 * @implemented (Undocumented)
1229 */
1230 BOOL
1231 WINAPI
1232 SetConsoleHardwareState(HANDLE hConsole,
1233 DWORD Flags,
1234 DWORD State)
1235 {
1236 CSR_API_MESSAGE Request;
1237 ULONG CsrRequest;
1238 NTSTATUS Status;
1239
1240 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
1241 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
1242 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
1243 Request.Data.ConsoleHardwareStateRequest.State = State;
1244
1245 Status = CsrClientCallServer(&Request,
1246 NULL,
1247 CsrRequest,
1248 sizeof(CSR_API_MESSAGE));
1249 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1250 {
1251 SetLastErrorByStatus(Status);
1252 return FALSE;
1253 }
1254
1255 return TRUE;
1256 }
1257
1258
1259 /*
1260 * @unimplemented (Undocumented)
1261 */
1262 BOOL
1263 WINAPI
1264 SetConsoleKeyShortcuts(DWORD Unknown0,
1265 DWORD Unknown1,
1266 DWORD Unknown2,
1267 DWORD Unknown3)
1268 {
1269 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1270 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1271 return FALSE;
1272 }
1273
1274
1275 /*
1276 * @unimplemented (Undocumented)
1277 */
1278 BOOL
1279 WINAPI
1280 SetConsoleMaximumWindowSize(DWORD Unknown0,
1281 DWORD Unknown1)
1282 {
1283 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1284 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1285 return FALSE;
1286 }
1287
1288
1289 /*
1290 * @unimplemented (Undocumented)
1291 */
1292 BOOL
1293 WINAPI
1294 SetConsoleMenuClose(DWORD Unknown0)
1295 {
1296 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
1297 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1298 return FALSE;
1299 }
1300
1301
1302 static BOOL
1303 IntSetConsoleNumberOfCommands(DWORD dwNumCommands,
1304 LPCVOID lpExeName,
1305 BOOL bUnicode)
1306 {
1307 CSR_API_MESSAGE Request;
1308 PCSR_CAPTURE_BUFFER CaptureBuffer;
1309 ULONG CsrRequest = MAKE_CSR_API(SET_HISTORY_NUMBER_COMMANDS, CSR_CONSOLE);
1310 NTSTATUS Status;
1311
1312 if (lpExeName == NULL || !(bUnicode ? *(PWCHAR)lpExeName : *(PCHAR)lpExeName))
1313 {
1314 SetLastError(ERROR_INVALID_PARAMETER);
1315 return FALSE;
1316 }
1317
1318 CaptureBuffer = CsrAllocateCaptureBuffer(1, IntStringSize(lpExeName, bUnicode));
1319 if (!CaptureBuffer)
1320 {
1321 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1322 return FALSE;
1323 }
1324 IntCaptureMessageString(CaptureBuffer, lpExeName, bUnicode,
1325 &Request.Data.SetHistoryNumberCommands.ExeName);
1326 Request.Data.SetHistoryNumberCommands.NumCommands = dwNumCommands;
1327 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
1328 CsrFreeCaptureBuffer(CaptureBuffer);
1329 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1330 {
1331 SetLastErrorByStatus(Status);
1332 return FALSE;
1333 }
1334 return TRUE;
1335 }
1336
1337 /*
1338 * @implemented (Undocumented)
1339 */
1340 BOOL
1341 WINAPI
1342 SetConsoleNumberOfCommandsA(DWORD dwNumCommands,
1343 LPCWSTR lpExeName)
1344 {
1345 return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, FALSE);
1346 }
1347
1348 /*
1349 * @implemented (Undocumented)
1350 */
1351 BOOL
1352 WINAPI
1353 SetConsoleNumberOfCommandsW(DWORD dwNumCommands,
1354 LPCSTR lpExeName)
1355 {
1356 return IntSetConsoleNumberOfCommands(dwNumCommands, lpExeName, TRUE);
1357 }
1358
1359
1360 /*
1361 * @unimplemented (Undocumented)
1362 */
1363 BOOL
1364 WINAPI
1365 SetConsolePalette(DWORD Unknown0,
1366 DWORD Unknown1,
1367 DWORD Unknown2)
1368 {
1369 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
1370 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1371 return FALSE;
1372 }
1373
1374 /*
1375 * @unimplemented (Undocumented)
1376 */
1377 DWORD
1378 WINAPI
1379 ShowConsoleCursor(DWORD Unknown0,
1380 DWORD Unknown1)
1381 {
1382 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1384 return 0;
1385 }
1386
1387
1388 /*
1389 * FUNCTION: Checks whether the given handle is a valid console handle.
1390 * ARGUMENTS:
1391 * Handle - Handle to be checked
1392 * RETURNS:
1393 * TRUE: Handle is a valid console handle
1394 * FALSE: Handle is not a valid console handle.
1395 * STATUS: Officially undocumented
1396 *
1397 * @implemented
1398 */
1399 BOOL
1400 WINAPI
1401 VerifyConsoleIoHandle(HANDLE Handle)
1402 {
1403 CSR_API_MESSAGE Request;
1404 ULONG CsrRequest;
1405 NTSTATUS Status;
1406
1407 CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
1408 Request.Data.VerifyHandleRequest.Handle = Handle;
1409
1410 Status = CsrClientCallServer(&Request,
1411 NULL,
1412 CsrRequest,
1413 sizeof(CSR_API_MESSAGE));
1414 if (!NT_SUCCESS(Status))
1415 {
1416 SetLastErrorByStatus(Status);
1417 return FALSE;
1418 }
1419
1420 return (BOOL)NT_SUCCESS(Request.Status);
1421 }
1422
1423
1424 /*
1425 * @unimplemented
1426 */
1427 DWORD
1428 WINAPI
1429 WriteConsoleInputVDMA(DWORD Unknown0,
1430 DWORD Unknown1,
1431 DWORD Unknown2,
1432 DWORD Unknown3)
1433 {
1434 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1435 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1436 return 0;
1437 }
1438
1439
1440 /*
1441 * @unimplemented
1442 */
1443 DWORD
1444 WINAPI
1445 WriteConsoleInputVDMW(DWORD Unknown0,
1446 DWORD Unknown1,
1447 DWORD Unknown2,
1448 DWORD Unknown3)
1449 {
1450 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1451 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1452 return 0;
1453 }
1454
1455
1456 /*
1457 * @implemented (Undocumented)
1458 */
1459 BOOL
1460 WINAPI
1461 CloseConsoleHandle(HANDLE Handle)
1462 {
1463 CSR_API_MESSAGE Request;
1464 ULONG CsrRequest;
1465 NTSTATUS Status;
1466
1467 CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
1468 Request.Data.CloseHandleRequest.Handle = Handle;
1469
1470 Status = CsrClientCallServer(&Request,
1471 NULL,
1472 CsrRequest,
1473 sizeof(CSR_API_MESSAGE));
1474 if (!NT_SUCCESS(Status))
1475 {
1476 SetLastErrorByStatus(Status);
1477 return FALSE;
1478 }
1479
1480 return TRUE;
1481 }
1482
1483 /*
1484 * @implemented
1485 */
1486 HANDLE
1487 WINAPI
1488 GetStdHandle(DWORD nStdHandle)
1489 /*
1490 * FUNCTION: Get a handle for the standard input, standard output
1491 * and a standard error device.
1492 * ARGUMENTS:
1493 * nStdHandle - Specifies the device for which to return the handle.
1494 * RETURNS: If the function succeeds, the return value is the handle
1495 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1496 */
1497 {
1498 PRTL_USER_PROCESS_PARAMETERS Ppb;
1499
1500 Ppb = NtCurrentPeb()->ProcessParameters;
1501 switch (nStdHandle)
1502 {
1503 case STD_INPUT_HANDLE:
1504 return Ppb->StandardInput;
1505
1506 case STD_OUTPUT_HANDLE:
1507 return Ppb->StandardOutput;
1508
1509 case STD_ERROR_HANDLE:
1510 return Ppb->StandardError;
1511 }
1512
1513 SetLastError (ERROR_INVALID_PARAMETER);
1514 return INVALID_HANDLE_VALUE;
1515 }
1516
1517
1518 /*
1519 * @implemented
1520 */
1521 BOOL
1522 WINAPI
1523 SetStdHandle(DWORD nStdHandle,
1524 HANDLE hHandle)
1525 /*
1526 * FUNCTION: Set the handle for the standard input, standard output or
1527 * the standard error device.
1528 * ARGUMENTS:
1529 * nStdHandle - Specifies the handle to be set.
1530 * hHandle - The handle to set.
1531 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1532 */
1533 {
1534 PRTL_USER_PROCESS_PARAMETERS Ppb;
1535
1536 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1537
1538 Ppb = NtCurrentPeb()->ProcessParameters;
1539
1540 switch (nStdHandle)
1541 {
1542 case STD_INPUT_HANDLE:
1543 Ppb->StandardInput = hHandle;
1544 return TRUE;
1545
1546 case STD_OUTPUT_HANDLE:
1547 Ppb->StandardOutput = hHandle;
1548 return TRUE;
1549
1550 case STD_ERROR_HANDLE:
1551 Ppb->StandardError = hHandle;
1552 return TRUE;
1553 }
1554
1555 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1556 SetLastError(ERROR_INVALID_HANDLE);
1557 return FALSE;
1558 }
1559
1560
1561 static
1562 BOOL
1563 IntWriteConsole(HANDLE hConsoleOutput,
1564 PVOID lpBuffer,
1565 DWORD nNumberOfCharsToWrite,
1566 LPDWORD lpNumberOfCharsWritten,
1567 LPVOID lpReserved,
1568 BOOL bUnicode)
1569 {
1570 PCSR_API_MESSAGE Request;
1571 ULONG CsrRequest;
1572 NTSTATUS Status;
1573 USHORT nChars;
1574 ULONG SizeBytes, CharSize;
1575 DWORD Written = 0;
1576
1577 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1578 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1579 0,
1580 max(sizeof(CSR_API_MESSAGE),
1581 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
1582 CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
1583 if (Request == NULL)
1584 {
1585 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1586 return FALSE;
1587 }
1588
1589 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
1590
1591 while (nNumberOfCharsToWrite > 0)
1592 {
1593 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1594 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1595
1596 nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1597 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1598
1599 SizeBytes = nChars * CharSize;
1600
1601 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1602
1603 Status = CsrClientCallServer(Request,
1604 NULL,
1605 CsrRequest,
1606 max(sizeof(CSR_API_MESSAGE),
1607 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1608
1609 if (Status == STATUS_PENDING)
1610 {
1611 WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
1612 CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
1613 continue;
1614 }
1615 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1616 {
1617 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1618 SetLastErrorByStatus(Status);
1619 return FALSE;
1620 }
1621
1622 nNumberOfCharsToWrite -= nChars;
1623 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1624 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1625 }
1626
1627 if (lpNumberOfCharsWritten != NULL)
1628 {
1629 *lpNumberOfCharsWritten = Written;
1630 }
1631 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1632
1633 return TRUE;
1634 }
1635
1636
1637 /*--------------------------------------------------------------
1638 * WriteConsoleA
1639 *
1640 * @implemented
1641 */
1642 BOOL
1643 WINAPI
1644 WriteConsoleA(HANDLE hConsoleOutput,
1645 CONST VOID *lpBuffer,
1646 DWORD nNumberOfCharsToWrite,
1647 LPDWORD lpNumberOfCharsWritten,
1648 LPVOID lpReserved)
1649 {
1650 return IntWriteConsole(hConsoleOutput,
1651 (PVOID)lpBuffer,
1652 nNumberOfCharsToWrite,
1653 lpNumberOfCharsWritten,
1654 lpReserved,
1655 FALSE);
1656 }
1657
1658
1659 /*--------------------------------------------------------------
1660 * WriteConsoleW
1661 *
1662 * @implemented
1663 */
1664 BOOL
1665 WINAPI
1666 WriteConsoleW(HANDLE hConsoleOutput,
1667 CONST VOID *lpBuffer,
1668 DWORD nNumberOfCharsToWrite,
1669 LPDWORD lpNumberOfCharsWritten,
1670 LPVOID lpReserved)
1671 {
1672 return IntWriteConsole(hConsoleOutput,
1673 (PVOID)lpBuffer,
1674 nNumberOfCharsToWrite,
1675 lpNumberOfCharsWritten,
1676 lpReserved,
1677 TRUE);
1678 }
1679
1680
1681 static
1682 BOOL
1683 IntReadConsole(HANDLE hConsoleInput,
1684 PVOID lpBuffer,
1685 DWORD nNumberOfCharsToRead,
1686 LPDWORD lpNumberOfCharsRead,
1687 PCONSOLE_READCONSOLE_CONTROL pInputControl,
1688 BOOL bUnicode)
1689 {
1690 CSR_API_MESSAGE Request;
1691 PCSR_CAPTURE_BUFFER CaptureBuffer;
1692 ULONG CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1693 NTSTATUS Status = STATUS_SUCCESS;
1694 ULONG CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1695
1696 CaptureBuffer = CsrAllocateCaptureBuffer(1, nNumberOfCharsToRead * CharSize);
1697 if (CaptureBuffer == NULL)
1698 {
1699 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1700 return FALSE;
1701 }
1702
1703 CsrAllocateMessagePointer(CaptureBuffer,
1704 nNumberOfCharsToRead * CharSize,
1705 &Request.Data.ReadConsoleRequest.Buffer);
1706
1707 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1708 Request.Data.ReadConsoleRequest.Unicode = bUnicode;
1709 Request.Data.ReadConsoleRequest.NrCharactersToRead = (WORD)nNumberOfCharsToRead;
1710 Request.Data.ReadConsoleRequest.NrCharactersRead = 0;
1711 Request.Data.ReadConsoleRequest.CtrlWakeupMask = 0;
1712 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
1713 {
1714 Request.Data.ReadConsoleRequest.NrCharactersRead = pInputControl->nInitialChars;
1715 memcpy(Request.Data.ReadConsoleRequest.Buffer,
1716 lpBuffer,
1717 pInputControl->nInitialChars * sizeof(WCHAR));
1718 Request.Data.ReadConsoleRequest.CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
1719 }
1720
1721 do
1722 {
1723 if (Status == STATUS_PENDING)
1724 {
1725 Status = NtWaitForSingleObject(Request.Data.ReadConsoleRequest.EventHandle,
1726 FALSE,
1727 0);
1728 if (!NT_SUCCESS(Status))
1729 {
1730 DPRINT1("Wait for console input failed!\n");
1731 break;
1732 }
1733 }
1734
1735 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
1736 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1737 {
1738 DPRINT1("CSR returned error in ReadConsole\n");
1739 CsrFreeCaptureBuffer(CaptureBuffer);
1740 SetLastErrorByStatus(Status);
1741 return FALSE;
1742 }
1743 }
1744 while (Status == STATUS_PENDING);
1745
1746 memcpy(lpBuffer,
1747 Request.Data.ReadConsoleRequest.Buffer,
1748 Request.Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1749
1750 if (lpNumberOfCharsRead != NULL)
1751 *lpNumberOfCharsRead = Request.Data.ReadConsoleRequest.NrCharactersRead;
1752
1753 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
1754 pInputControl->dwControlKeyState = Request.Data.ReadConsoleRequest.ControlKeyState;
1755
1756 CsrFreeCaptureBuffer(CaptureBuffer);
1757
1758 return TRUE;
1759 }
1760
1761
1762 /*--------------------------------------------------------------
1763 * ReadConsoleA
1764 *
1765 * @implemented
1766 */
1767 BOOL
1768 WINAPI
1769 ReadConsoleA(HANDLE hConsoleInput,
1770 LPVOID lpBuffer,
1771 DWORD nNumberOfCharsToRead,
1772 LPDWORD lpNumberOfCharsRead,
1773 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1774 {
1775 return IntReadConsole(hConsoleInput,
1776 lpBuffer,
1777 nNumberOfCharsToRead,
1778 lpNumberOfCharsRead,
1779 NULL,
1780 FALSE);
1781 }
1782
1783
1784 /*--------------------------------------------------------------
1785 * ReadConsoleW
1786 *
1787 * @implemented
1788 */
1789 BOOL
1790 WINAPI
1791 ReadConsoleW(HANDLE hConsoleInput,
1792 LPVOID lpBuffer,
1793 DWORD nNumberOfCharsToRead,
1794 LPDWORD lpNumberOfCharsRead,
1795 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1796 {
1797 return IntReadConsole(hConsoleInput,
1798 lpBuffer,
1799 nNumberOfCharsToRead,
1800 lpNumberOfCharsRead,
1801 pInputControl,
1802 TRUE);
1803 }
1804
1805
1806 /*--------------------------------------------------------------
1807 * AllocConsole
1808 *
1809 * @implemented
1810 */
1811 BOOL
1812 WINAPI
1813 AllocConsole(VOID)
1814 {
1815 CSR_API_MESSAGE Request;
1816 ULONG CsrRequest;
1817 NTSTATUS Status;
1818 HANDLE hStdError;
1819
1820 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1821 {
1822 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1823 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1824 return FALSE;
1825 }
1826
1827 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1828 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1829 Request.Data.AllocConsoleRequest.Visible = TRUE;
1830
1831 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1832
1833 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1834 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1835 {
1836 SetLastErrorByStatus(Status);
1837 return FALSE;
1838 }
1839
1840 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1841
1842 SetStdHandle(STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle);
1843 SetStdHandle(STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle);
1844
1845 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1846 0,
1847 TRUE,
1848 DUPLICATE_SAME_ACCESS);
1849
1850 SetStdHandle(STD_ERROR_HANDLE, hStdError);
1851 return TRUE;
1852 }
1853
1854
1855 /*--------------------------------------------------------------
1856 * FreeConsole
1857 *
1858 * @implemented
1859 */
1860 BOOL
1861 WINAPI
1862 FreeConsole(VOID)
1863 {
1864 // AG: I'm not sure if this is correct (what happens to std handles?)
1865 // but I just tried to reverse what AllocConsole() does...
1866
1867 CSR_API_MESSAGE Request;
1868 ULONG CsrRequest;
1869 NTSTATUS Status;
1870
1871 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1872
1873 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1874 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1875 {
1876 SetLastErrorByStatus(Status);
1877 return FALSE;
1878 }
1879
1880 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1881 return TRUE;
1882 }
1883
1884
1885 /*--------------------------------------------------------------
1886 * GetConsoleScreenBufferInfo
1887 *
1888 * @implemented
1889 */
1890 BOOL
1891 WINAPI
1892 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1893 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1894 {
1895 CSR_API_MESSAGE Request;
1896 ULONG CsrRequest;
1897 NTSTATUS Status;
1898
1899 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1900 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1901
1902 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1903 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1904 {
1905 SetLastErrorByStatus(Status);
1906 return FALSE;
1907 }
1908 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1909 return TRUE;
1910 }
1911
1912
1913 /*--------------------------------------------------------------
1914 * SetConsoleCursorPosition
1915 *
1916 * @implemented
1917 */
1918 BOOL
1919 WINAPI
1920 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1921 COORD dwCursorPosition)
1922 {
1923 CSR_API_MESSAGE Request;
1924 ULONG CsrRequest;
1925 NTSTATUS Status;
1926
1927 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1928 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1929 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1930
1931 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1932 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1933 {
1934 SetLastErrorByStatus(Status);
1935 return FALSE;
1936 }
1937
1938 return TRUE;
1939 }
1940
1941
1942 static
1943 BOOL
1944 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1945 PVOID cCharacter,
1946 DWORD nLength,
1947 COORD dwWriteCoord,
1948 LPDWORD lpNumberOfCharsWritten,
1949 BOOL bUnicode)
1950 {
1951 CSR_API_MESSAGE Request;
1952 ULONG CsrRequest;
1953 NTSTATUS Status;
1954
1955 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1956 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1957 Request.Data.FillOutputRequest.Unicode = bUnicode;
1958
1959 if(bUnicode)
1960 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1961 else
1962 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1963
1964 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1965 Request.Data.FillOutputRequest.Length = (WORD)nLength;
1966
1967 Status = CsrClientCallServer(&Request,
1968 NULL,
1969 CsrRequest,
1970 sizeof(CSR_API_MESSAGE));
1971
1972 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1973 {
1974 SetLastErrorByStatus(Status);
1975 return FALSE;
1976 }
1977
1978 if(lpNumberOfCharsWritten != NULL)
1979 {
1980 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1981 }
1982
1983 return TRUE;
1984 }
1985
1986 /*--------------------------------------------------------------
1987 * FillConsoleOutputCharacterA
1988 *
1989 * @implemented
1990 */
1991 BOOL
1992 WINAPI
1993 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
1994 CHAR cCharacter,
1995 DWORD nLength,
1996 COORD dwWriteCoord,
1997 LPDWORD lpNumberOfCharsWritten)
1998 {
1999 return IntFillConsoleOutputCharacter(hConsoleOutput,
2000 &cCharacter,
2001 nLength,
2002 dwWriteCoord,
2003 lpNumberOfCharsWritten,
2004 FALSE);
2005 }
2006
2007
2008 /*--------------------------------------------------------------
2009 * FillConsoleOutputCharacterW
2010 *
2011 * @implemented
2012 */
2013 BOOL
2014 WINAPI
2015 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
2016 WCHAR cCharacter,
2017 DWORD nLength,
2018 COORD dwWriteCoord,
2019 LPDWORD lpNumberOfCharsWritten)
2020 {
2021 return IntFillConsoleOutputCharacter(hConsoleOutput,
2022 &cCharacter,
2023 nLength,
2024 dwWriteCoord,
2025 lpNumberOfCharsWritten,
2026 TRUE);
2027 }
2028
2029
2030 static
2031 BOOL
2032 IntPeekConsoleInput(HANDLE hConsoleInput,
2033 PINPUT_RECORD lpBuffer,
2034 DWORD nLength,
2035 LPDWORD lpNumberOfEventsRead,
2036 BOOL bUnicode)
2037 {
2038 CSR_API_MESSAGE Request;
2039 ULONG CsrRequest;
2040 PCSR_CAPTURE_BUFFER CaptureBuffer;
2041 NTSTATUS Status;
2042 ULONG Size;
2043
2044 if (lpBuffer == NULL)
2045 {
2046 SetLastError(ERROR_INVALID_PARAMETER);
2047 return FALSE;
2048 }
2049
2050 Size = nLength * sizeof(INPUT_RECORD);
2051
2052 /* Allocate a Capture Buffer */
2053 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
2054 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2055
2056 /* Allocate space in the Buffer */
2057 CsrCaptureMessageBuffer(CaptureBuffer,
2058 NULL,
2059 Size,
2060 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
2061
2062 /* Set up the data to send to the Console Server */
2063 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
2064 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
2065 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
2066 Request.Data.PeekConsoleInputRequest.Length = nLength;
2067
2068 /* Call the server */
2069 Status = CsrClientCallServer(&Request,
2070 CaptureBuffer,
2071 CsrRequest,
2072 sizeof(CSR_API_MESSAGE));
2073 DPRINT("Server returned: %x\n", Request.Status);
2074
2075 /* Check for success*/
2076 if (NT_SUCCESS(Request.Status))
2077 {
2078 /* Return the number of events read */
2079 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
2080 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
2081
2082 /* Copy into the buffer */
2083 DPRINT("Copying to buffer\n");
2084 RtlCopyMemory(lpBuffer,
2085 Request.Data.PeekConsoleInputRequest.InputRecord,
2086 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
2087 }
2088 else
2089 {
2090 /* Error out */
2091 *lpNumberOfEventsRead = 0;
2092 SetLastErrorByStatus(Request.Status);
2093 }
2094
2095 /* Release the capture buffer */
2096 CsrFreeCaptureBuffer(CaptureBuffer);
2097
2098 /* Return TRUE or FALSE */
2099 return NT_SUCCESS(Request.Status);
2100 }
2101
2102 /*--------------------------------------------------------------
2103 * PeekConsoleInputA
2104 *
2105 * @implemented
2106 */
2107 BOOL
2108 WINAPI
2109 PeekConsoleInputA(HANDLE hConsoleInput,
2110 PINPUT_RECORD lpBuffer,
2111 DWORD nLength,
2112 LPDWORD lpNumberOfEventsRead)
2113 {
2114 return IntPeekConsoleInput(hConsoleInput,
2115 lpBuffer,
2116 nLength,
2117 lpNumberOfEventsRead,
2118 FALSE);
2119 }
2120
2121
2122 /*--------------------------------------------------------------
2123 * PeekConsoleInputW
2124 *
2125 * @implemented
2126 */
2127 BOOL
2128 WINAPI
2129 PeekConsoleInputW(HANDLE hConsoleInput,
2130 PINPUT_RECORD lpBuffer,
2131 DWORD nLength,
2132 LPDWORD lpNumberOfEventsRead)
2133 {
2134 return IntPeekConsoleInput(hConsoleInput,
2135 lpBuffer, nLength,
2136 lpNumberOfEventsRead,
2137 TRUE);
2138 }
2139
2140
2141 static
2142 BOOL
2143 IntReadConsoleInput(HANDLE hConsoleInput,
2144 PINPUT_RECORD lpBuffer,
2145 DWORD nLength,
2146 LPDWORD lpNumberOfEventsRead,
2147 BOOL bUnicode)
2148 {
2149 CSR_API_MESSAGE Request;
2150 ULONG CsrRequest;
2151 ULONG Read;
2152 NTSTATUS Status;
2153
2154 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
2155 Read = 0;
2156
2157 while (nLength > 0)
2158 {
2159 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
2160 Request.Data.ReadInputRequest.Unicode = bUnicode;
2161
2162 Status = CsrClientCallServer(&Request,
2163 NULL,
2164 CsrRequest,
2165 sizeof(CSR_API_MESSAGE));
2166 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2167 {
2168 if (Read == 0)
2169 {
2170 /* we couldn't read a single record, fail */
2171 SetLastErrorByStatus(Status);
2172 return FALSE;
2173 }
2174 else
2175 {
2176 /* FIXME - fail gracefully in case we already read at least one record? */
2177 break;
2178 }
2179 }
2180 else if (Status == STATUS_PENDING)
2181 {
2182 if (Read == 0)
2183 {
2184 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
2185 if (!NT_SUCCESS(Status))
2186 {
2187 SetLastErrorByStatus(Status);
2188 break;
2189 }
2190 }
2191 else
2192 {
2193 /* nothing more to read (waiting for more input??), let's just bail */
2194 break;
2195 }
2196 }
2197 else
2198 {
2199 lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
2200 nLength--;
2201
2202 if (!Request.Data.ReadInputRequest.MoreEvents)
2203 {
2204 /* nothing more to read, bail */
2205 break;
2206 }
2207 }
2208 }
2209
2210 if (lpNumberOfEventsRead != NULL)
2211 {
2212 *lpNumberOfEventsRead = Read;
2213 }
2214
2215 return (Read > 0);
2216 }
2217
2218
2219 /*--------------------------------------------------------------
2220 * ReadConsoleInputA
2221 *
2222 * @implemented
2223 */
2224 BOOL
2225 WINAPI
2226 ReadConsoleInputA(HANDLE hConsoleInput,
2227 PINPUT_RECORD lpBuffer,
2228 DWORD nLength,
2229 LPDWORD lpNumberOfEventsRead)
2230 {
2231 return IntReadConsoleInput(hConsoleInput,
2232 lpBuffer,
2233 nLength,
2234 lpNumberOfEventsRead,
2235 FALSE);
2236 }
2237
2238
2239 /*--------------------------------------------------------------
2240 * ReadConsoleInputW
2241 *
2242 * @implemented
2243 */
2244 BOOL
2245 WINAPI
2246 ReadConsoleInputW(HANDLE hConsoleInput,
2247 PINPUT_RECORD lpBuffer,
2248 DWORD nLength,
2249 LPDWORD lpNumberOfEventsRead)
2250 {
2251 return IntReadConsoleInput(hConsoleInput,
2252 lpBuffer,
2253 nLength,
2254 lpNumberOfEventsRead,
2255 TRUE);
2256 }
2257
2258
2259 static
2260 BOOL
2261 IntWriteConsoleInput(HANDLE hConsoleInput,
2262 PINPUT_RECORD lpBuffer,
2263 DWORD nLength,
2264 LPDWORD lpNumberOfEventsWritten,
2265 BOOL bUnicode)
2266 {
2267 CSR_API_MESSAGE Request;
2268 ULONG CsrRequest;
2269 PCSR_CAPTURE_BUFFER CaptureBuffer;
2270 NTSTATUS Status;
2271 DWORD Size;
2272
2273 if (lpBuffer == NULL)
2274 {
2275 SetLastError(ERROR_INVALID_PARAMETER);
2276 return FALSE;
2277 }
2278
2279 Size = nLength * sizeof(INPUT_RECORD);
2280
2281 /* Allocate a Capture Buffer */
2282 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
2283 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2284
2285 /* Allocate space in the Buffer */
2286 CsrCaptureMessageBuffer(CaptureBuffer,
2287 lpBuffer,
2288 Size,
2289 (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
2290
2291 /* Set up the data to send to the Console Server */
2292 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
2293 Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
2294 Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
2295 Request.Data.WriteConsoleInputRequest.Length = nLength;
2296
2297 /* Call the server */
2298 Status = CsrClientCallServer(&Request,
2299 CaptureBuffer,
2300 CsrRequest,
2301 sizeof(CSR_API_MESSAGE));
2302 DPRINT("Server returned: %x\n", Request.Status);
2303
2304 /* Check for success*/
2305 if (NT_SUCCESS(Request.Status))
2306 {
2307 /* Return the number of events read */
2308 DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
2309 *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
2310 }
2311 else
2312 {
2313 /* Error out */
2314 *lpNumberOfEventsWritten = 0;
2315 SetLastErrorByStatus(Request.Status);
2316 }
2317
2318 /* Release the capture buffer */
2319 CsrFreeCaptureBuffer(CaptureBuffer);
2320
2321 /* Return TRUE or FALSE */
2322 return NT_SUCCESS(Request.Status);
2323 }
2324
2325
2326 /*--------------------------------------------------------------
2327 * WriteConsoleInputA
2328 *
2329 * @implemented
2330 */
2331 BOOL
2332 WINAPI
2333 WriteConsoleInputA(HANDLE hConsoleInput,
2334 CONST INPUT_RECORD *lpBuffer,
2335 DWORD nLength,
2336 LPDWORD lpNumberOfEventsWritten)
2337 {
2338 return IntWriteConsoleInput(hConsoleInput,
2339 (PINPUT_RECORD)lpBuffer,
2340 nLength,
2341 lpNumberOfEventsWritten,
2342 FALSE);
2343 }
2344
2345
2346 /*--------------------------------------------------------------
2347 * WriteConsoleInputW
2348 *
2349 * @implemented
2350 */
2351 BOOL
2352 WINAPI
2353 WriteConsoleInputW(HANDLE hConsoleInput,
2354 CONST INPUT_RECORD *lpBuffer,
2355 DWORD nLength,
2356 LPDWORD lpNumberOfEventsWritten)
2357 {
2358 return IntWriteConsoleInput(hConsoleInput,
2359 (PINPUT_RECORD)lpBuffer,
2360 nLength,
2361 lpNumberOfEventsWritten,
2362 TRUE);
2363 }
2364
2365
2366 static
2367 BOOL
2368 IntReadConsoleOutput(HANDLE hConsoleOutput,
2369 PCHAR_INFO lpBuffer,
2370 COORD dwBufferSize,
2371 COORD dwBufferCoord,
2372 PSMALL_RECT lpReadRegion,
2373 BOOL bUnicode)
2374 {
2375 CSR_API_MESSAGE Request;
2376 ULONG CsrRequest;
2377 PCSR_CAPTURE_BUFFER CaptureBuffer;
2378 NTSTATUS Status;
2379 DWORD Size, SizeX, SizeY;
2380
2381 if (lpBuffer == NULL)
2382 {
2383 SetLastError(ERROR_INVALID_PARAMETER);
2384 return FALSE;
2385 }
2386
2387 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
2388
2389 /* Allocate a Capture Buffer */
2390 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
2391 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2392
2393 /* Allocate space in the Buffer */
2394 CsrCaptureMessageBuffer(CaptureBuffer,
2395 NULL,
2396 Size,
2397 (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
2398
2399 /* Set up the data to send to the Console Server */
2400 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
2401 Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2402 Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
2403 Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
2404 Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
2405 Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
2406
2407 /* Call the server */
2408 Status = CsrClientCallServer(&Request,
2409 CaptureBuffer,
2410 CsrRequest,
2411 sizeof(CSR_API_MESSAGE));
2412 DPRINT("Server returned: %x\n", Request.Status);
2413
2414 /* Check for success*/
2415 if (NT_SUCCESS(Request.Status))
2416 {
2417 /* Copy into the buffer */
2418 DPRINT("Copying to buffer\n");
2419 SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
2420 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
2421 SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
2422 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
2423 RtlCopyMemory(lpBuffer,
2424 Request.Data.ReadConsoleOutputRequest.CharInfo,
2425 sizeof(CHAR_INFO) * SizeX * SizeY);
2426 }
2427 else
2428 {
2429 /* Error out */
2430 SetLastErrorByStatus(Request.Status);
2431 }
2432
2433 /* Return the read region */
2434 DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
2435 *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
2436
2437 /* Release the capture buffer */
2438 CsrFreeCaptureBuffer(CaptureBuffer);
2439
2440 /* Return TRUE or FALSE */
2441 return NT_SUCCESS(Request.Status);
2442 }
2443
2444 /*--------------------------------------------------------------
2445 * ReadConsoleOutputA
2446 *
2447 * @implemented
2448 */
2449 BOOL
2450 WINAPI
2451 ReadConsoleOutputA(HANDLE hConsoleOutput,
2452 PCHAR_INFO lpBuffer,
2453 COORD dwBufferSize,
2454 COORD dwBufferCoord,
2455 PSMALL_RECT lpReadRegion)
2456 {
2457 return IntReadConsoleOutput(hConsoleOutput,
2458 lpBuffer,
2459 dwBufferSize,
2460 dwBufferCoord,
2461 lpReadRegion,
2462 FALSE);
2463 }
2464
2465
2466 /*--------------------------------------------------------------
2467 * ReadConsoleOutputW
2468 *
2469 * @implemented
2470 */
2471 BOOL
2472 WINAPI
2473 ReadConsoleOutputW(HANDLE hConsoleOutput,
2474 PCHAR_INFO lpBuffer,
2475 COORD dwBufferSize,
2476 COORD dwBufferCoord,
2477 PSMALL_RECT lpReadRegion)
2478 {
2479 return IntReadConsoleOutput(hConsoleOutput,
2480 lpBuffer,
2481 dwBufferSize,
2482 dwBufferCoord,
2483 lpReadRegion,
2484 TRUE);
2485 }
2486
2487
2488 static
2489 BOOL
2490 IntWriteConsoleOutput(HANDLE hConsoleOutput,
2491 CONST CHAR_INFO *lpBuffer,
2492 COORD dwBufferSize,
2493 COORD dwBufferCoord,
2494 PSMALL_RECT lpWriteRegion,
2495 BOOL bUnicode)
2496 {
2497 CSR_API_MESSAGE Request;
2498 ULONG CsrRequest;
2499 PCSR_CAPTURE_BUFFER CaptureBuffer;
2500 NTSTATUS Status;
2501 ULONG Size;
2502
2503 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
2504
2505 /* Allocate a Capture Buffer */
2506 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
2507 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2508
2509 /* Allocate space in the Buffer */
2510 CsrCaptureMessageBuffer(CaptureBuffer,
2511 NULL,
2512 Size,
2513 (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
2514
2515 /* Copy from the buffer */
2516 RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
2517
2518 /* Set up the data to send to the Console Server */
2519 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
2520 Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2521 Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
2522 Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
2523 Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
2524 Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
2525
2526 /* Call the server */
2527 Status = CsrClientCallServer(&Request,
2528 CaptureBuffer,
2529 CsrRequest,
2530 sizeof(CSR_API_MESSAGE));
2531 DPRINT("Server returned: %x\n", Request.Status);
2532
2533 /* Check for success*/
2534 if (!NT_SUCCESS(Request.Status))
2535 {
2536 /* Error out */
2537 SetLastErrorByStatus(Request.Status);
2538 }
2539
2540 /* Return the read region */
2541 DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
2542 *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
2543
2544 /* Release the capture buffer */
2545 CsrFreeCaptureBuffer(CaptureBuffer);
2546
2547 /* Return TRUE or FALSE */
2548 return NT_SUCCESS(Request.Status);
2549 }
2550
2551 /*--------------------------------------------------------------
2552 * WriteConsoleOutputA
2553 *
2554 * @implemented
2555 */
2556 BOOL
2557 WINAPI
2558 WriteConsoleOutputA(HANDLE hConsoleOutput,
2559 CONST CHAR_INFO *lpBuffer,
2560 COORD dwBufferSize,
2561 COORD dwBufferCoord,
2562 PSMALL_RECT lpWriteRegion)
2563 {
2564 return IntWriteConsoleOutput(hConsoleOutput,
2565 lpBuffer,
2566 dwBufferSize,
2567 dwBufferCoord,
2568 lpWriteRegion,
2569 FALSE);
2570 }
2571
2572
2573 /*--------------------------------------------------------------
2574 * WriteConsoleOutputW
2575 *
2576 * @implemented
2577 */
2578 BOOL
2579 WINAPI
2580 WriteConsoleOutputW(HANDLE hConsoleOutput,
2581 CONST CHAR_INFO *lpBuffer,
2582 COORD dwBufferSize,
2583 COORD dwBufferCoord,
2584 PSMALL_RECT lpWriteRegion)
2585 {
2586 return IntWriteConsoleOutput(hConsoleOutput,
2587 lpBuffer,
2588 dwBufferSize,
2589 dwBufferCoord,
2590 lpWriteRegion,
2591 TRUE);
2592 }
2593
2594
2595 static
2596 BOOL
2597 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
2598 PVOID lpCharacter,
2599 DWORD nLength,
2600 COORD dwReadCoord,
2601 LPDWORD lpNumberOfCharsRead,
2602 BOOL bUnicode)
2603 {
2604 PCSR_API_MESSAGE Request;
2605 ULONG CsrRequest;
2606 NTSTATUS Status;
2607 ULONG nChars, SizeBytes, CharSize;
2608 DWORD CharsRead = 0;
2609
2610 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2611
2612 nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) / CharSize;
2613 SizeBytes = nChars * CharSize;
2614
2615 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2616 max(sizeof(CSR_API_MESSAGE),
2617 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)
2618 + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2619 if (Request == NULL)
2620 {
2621 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2622 return FALSE;
2623 }
2624
2625 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2626 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
2627
2628 while (nLength > 0)
2629 {
2630 DWORD BytesRead;
2631
2632 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2633 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
2634 Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
2635 SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
2636
2637 Status = CsrClientCallServer(Request,
2638 NULL,
2639 CsrRequest,
2640 max(sizeof(CSR_API_MESSAGE),
2641 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
2642 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2643 {
2644 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2645 SetLastErrorByStatus(Status);
2646 break;
2647 }
2648
2649 BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
2650 memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
2651 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
2652 CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2653 nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2654
2655 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
2656 }
2657
2658 if (lpNumberOfCharsRead != NULL)
2659 {
2660 *lpNumberOfCharsRead = CharsRead;
2661 }
2662
2663 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2664
2665 return TRUE;
2666 }
2667
2668
2669 /*--------------------------------------------------------------
2670 * ReadConsoleOutputCharacterA
2671 *
2672 * @implemented
2673 */
2674 BOOL
2675 WINAPI
2676 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
2677 LPSTR lpCharacter,
2678 DWORD nLength,
2679 COORD dwReadCoord,
2680 LPDWORD lpNumberOfCharsRead)
2681 {
2682 return IntReadConsoleOutputCharacter(hConsoleOutput,
2683 (PVOID)lpCharacter,
2684 nLength,
2685 dwReadCoord,
2686 lpNumberOfCharsRead,
2687 FALSE);
2688 }
2689
2690
2691 /*--------------------------------------------------------------
2692 * ReadConsoleOutputCharacterW
2693 *
2694 * @implemented
2695 */
2696 BOOL
2697 WINAPI
2698 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
2699 LPWSTR lpCharacter,
2700 DWORD nLength,
2701 COORD dwReadCoord,
2702 LPDWORD lpNumberOfCharsRead)
2703 {
2704 return IntReadConsoleOutputCharacter(hConsoleOutput,
2705 (PVOID)lpCharacter,
2706 nLength,
2707 dwReadCoord,
2708 lpNumberOfCharsRead,
2709 TRUE);
2710 }
2711
2712
2713 /*--------------------------------------------------------------
2714 * ReadConsoleOutputAttribute
2715 *
2716 * @implemented
2717 */
2718 BOOL
2719 WINAPI
2720 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
2721 LPWORD lpAttribute,
2722 DWORD nLength,
2723 COORD dwReadCoord,
2724 LPDWORD lpNumberOfAttrsRead)
2725 {
2726 PCSR_API_MESSAGE Request;
2727 ULONG CsrRequest;
2728 NTSTATUS Status;
2729 DWORD Size;
2730
2731 if (lpNumberOfAttrsRead != NULL)
2732 *lpNumberOfAttrsRead = nLength;
2733
2734 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2735 0,
2736 max(sizeof(CSR_API_MESSAGE),
2737 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
2738 + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2739 if (Request == NULL)
2740 {
2741 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2742 return FALSE;
2743 }
2744
2745 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2746
2747 while (nLength != 0)
2748 {
2749 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2750 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2751
2752 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2753 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2754 else
2755 Size = nLength;
2756
2757 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2758
2759 Status = CsrClientCallServer(Request,
2760 NULL,
2761 CsrRequest,
2762 max(sizeof(CSR_API_MESSAGE),
2763 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2764 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2765 {
2766 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2767 SetLastErrorByStatus(Status);
2768 return FALSE;
2769 }
2770
2771 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2772 lpAttribute += Size;
2773 nLength -= Size;
2774 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2775 }
2776
2777 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2778
2779 return TRUE;
2780 }
2781
2782
2783 static
2784 BOOL
2785 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2786 PVOID lpCharacter,
2787 DWORD nLength,
2788 COORD dwWriteCoord,
2789 LPDWORD lpNumberOfCharsWritten,
2790 BOOL bUnicode)
2791 {
2792 PCSR_API_MESSAGE Request;
2793 ULONG CsrRequest;
2794 NTSTATUS Status;
2795 ULONG SizeBytes, CharSize, nChars;
2796 DWORD Written = 0;
2797
2798 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2799
2800 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2801 SizeBytes = nChars * CharSize;
2802
2803 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2804 max(sizeof(CSR_API_MESSAGE),
2805 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2806 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2807 if (Request == NULL)
2808 {
2809 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2810 return FALSE;
2811 }
2812
2813 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2814 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2815
2816 while (nLength > 0)
2817 {
2818 DWORD BytesWrite;
2819
2820 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2821 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2822 Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
2823 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2824
2825 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2826
2827 Status = CsrClientCallServer(Request,
2828 NULL,
2829 CsrRequest,
2830 max(sizeof(CSR_API_MESSAGE),
2831 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2832
2833 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2834 {
2835 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2836 SetLastErrorByStatus(Status);
2837 return FALSE;
2838 }
2839
2840 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2841 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2842 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2843
2844 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2845 }
2846
2847 if (lpNumberOfCharsWritten != NULL)
2848 {
2849 *lpNumberOfCharsWritten = Written;
2850 }
2851
2852 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2853
2854 return TRUE;
2855 }
2856
2857
2858 /*--------------------------------------------------------------
2859 * WriteConsoleOutputCharacterA
2860 *
2861 * @implemented
2862 */
2863 BOOL
2864 WINAPI
2865 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2866 LPCSTR lpCharacter,
2867 DWORD nLength,
2868 COORD dwWriteCoord,
2869 LPDWORD lpNumberOfCharsWritten)
2870 {
2871 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2872 (PVOID)lpCharacter,
2873 nLength,
2874 dwWriteCoord,
2875 lpNumberOfCharsWritten,
2876 FALSE);
2877 }
2878
2879
2880 /*--------------------------------------------------------------
2881 * WriteConsoleOutputCharacterW
2882 *
2883 * @implemented
2884 */
2885 BOOL
2886 WINAPI
2887 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2888 LPCWSTR lpCharacter,
2889 DWORD nLength,
2890 COORD dwWriteCoord,
2891 LPDWORD lpNumberOfCharsWritten)
2892 {
2893 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2894 (PVOID)lpCharacter,
2895 nLength,
2896 dwWriteCoord,
2897 lpNumberOfCharsWritten,
2898 TRUE);
2899 }
2900
2901
2902 /*--------------------------------------------------------------
2903 * WriteConsoleOutputAttribute
2904 *
2905 * @implemented
2906 */
2907 BOOL
2908 WINAPI
2909 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
2910 CONST WORD *lpAttribute,
2911 DWORD nLength,
2912 COORD dwWriteCoord,
2913 LPDWORD lpNumberOfAttrsWritten)
2914 {
2915 PCSR_API_MESSAGE Request;
2916 ULONG CsrRequest;
2917 NTSTATUS Status;
2918 WORD Size;
2919
2920 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2921 0,
2922 max(sizeof(CSR_API_MESSAGE),
2923 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2924 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2925 if (Request == NULL)
2926 {
2927 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2928 return FALSE;
2929 }
2930
2931 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2932 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2933
2934 if (lpNumberOfAttrsWritten)
2935 *lpNumberOfAttrsWritten = nLength;
2936 while (nLength)
2937 {
2938 Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2939 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2940 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2941 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2942
2943 Status = CsrClientCallServer(Request,
2944 NULL,
2945 CsrRequest,
2946 max(sizeof(CSR_API_MESSAGE),
2947 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2948
2949 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2950 {
2951 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2952 SetLastErrorByStatus (Status);
2953 return FALSE;
2954 }
2955 nLength -= Size;
2956 lpAttribute += Size;
2957 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2958 }
2959
2960 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2961
2962 return TRUE;
2963 }
2964
2965
2966 /*--------------------------------------------------------------
2967 * FillConsoleOutputAttribute
2968 *
2969 * @implemented
2970 */
2971 BOOL
2972 WINAPI
2973 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
2974 WORD wAttribute,
2975 DWORD nLength,
2976 COORD dwWriteCoord,
2977 LPDWORD lpNumberOfAttrsWritten)
2978 {
2979 CSR_API_MESSAGE Request;
2980 ULONG CsrRequest;
2981 NTSTATUS Status;
2982
2983 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2984 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2985 Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
2986 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2987 Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
2988
2989 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2990 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2991 {
2992 SetLastErrorByStatus ( Status );
2993 return FALSE;
2994 }
2995
2996 if (lpNumberOfAttrsWritten)
2997 *lpNumberOfAttrsWritten = nLength;
2998
2999 return TRUE;
3000 }
3001
3002
3003 /*--------------------------------------------------------------
3004 * GetConsoleMode
3005 *
3006 * @implemented
3007 */
3008 BOOL
3009 WINAPI
3010 GetConsoleMode(HANDLE hConsoleHandle,
3011 LPDWORD lpMode)
3012 {
3013 CSR_API_MESSAGE Request;
3014 ULONG CsrRequest;
3015 NTSTATUS Status;
3016
3017 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
3018 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
3019
3020 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3021 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3022 {
3023 SetLastErrorByStatus ( Status );
3024 return FALSE;
3025 }
3026 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
3027
3028 return TRUE;
3029 }
3030
3031
3032 /*--------------------------------------------------------------
3033 * GetNumberOfConsoleInputEvents
3034 *
3035 * @implemented
3036 */
3037 BOOL
3038 WINAPI
3039 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
3040 LPDWORD lpNumberOfEvents)
3041 {
3042 CSR_API_MESSAGE Request;
3043 ULONG CsrRequest;
3044 NTSTATUS Status;
3045
3046 if (lpNumberOfEvents == NULL)
3047 {
3048 SetLastError(ERROR_INVALID_PARAMETER);
3049 return FALSE;
3050 }
3051
3052 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
3053 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
3054
3055 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3056 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3057 {
3058 SetLastErrorByStatus(Status);
3059 return FALSE;
3060 }
3061
3062 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
3063
3064 return TRUE;
3065 }
3066
3067
3068 /*--------------------------------------------------------------
3069 * GetLargestConsoleWindowSize
3070 *
3071 * @unimplemented
3072 */
3073 COORD
3074 WINAPI
3075 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
3076 {
3077 COORD Coord = {80,25};
3078 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
3079 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3080 return Coord;
3081 }
3082
3083
3084 /*--------------------------------------------------------------
3085 * GetConsoleCursorInfo
3086 *
3087 * @implemented
3088 */
3089 BOOL
3090 WINAPI
3091 GetConsoleCursorInfo(HANDLE hConsoleOutput,
3092 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
3093 {
3094 CSR_API_MESSAGE Request;
3095 ULONG CsrRequest;
3096 NTSTATUS Status;
3097
3098 if (!lpConsoleCursorInfo)
3099 {
3100 if (!hConsoleOutput)
3101 SetLastError(ERROR_INVALID_HANDLE);
3102 else
3103 SetLastError(ERROR_INVALID_ACCESS);
3104
3105 return FALSE;
3106 }
3107
3108 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
3109 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3110
3111 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3112
3113 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3114 {
3115 SetLastErrorByStatus(Status);
3116 return FALSE;
3117 }
3118 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
3119
3120 return TRUE;
3121 }
3122
3123
3124 /*--------------------------------------------------------------
3125 * GetNumberOfConsoleMouseButtons
3126 *
3127 * @unimplemented
3128 */
3129 BOOL
3130 WINAPI
3131 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
3132 {
3133 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
3134 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3135 return FALSE;
3136 }
3137
3138
3139 /*--------------------------------------------------------------
3140 * SetConsoleMode
3141 *
3142 * @implemented
3143 */
3144 BOOL
3145 WINAPI
3146 SetConsoleMode(HANDLE hConsoleHandle,
3147 DWORD dwMode)
3148 {
3149 CSR_API_MESSAGE Request;
3150 ULONG CsrRequest;
3151 NTSTATUS Status;
3152
3153 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
3154 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
3155 Request.Data.SetConsoleModeRequest.Mode = dwMode;
3156
3157 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3158 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3159 {
3160 SetLastErrorByStatus ( Status );
3161 return FALSE;
3162 }
3163
3164 return TRUE;
3165 }
3166
3167
3168 /*--------------------------------------------------------------
3169 * SetConsoleActiveScreenBuffer
3170 *
3171 * @implemented
3172 */
3173 BOOL
3174 WINAPI
3175 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
3176 {
3177 CSR_API_MESSAGE Request;
3178 ULONG CsrRequest;
3179 NTSTATUS Status;
3180
3181 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
3182 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
3183
3184 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3185 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3186 {
3187 SetLastErrorByStatus(Status);
3188 return FALSE;
3189 }
3190
3191 return TRUE;
3192 }
3193
3194
3195 /*--------------------------------------------------------------
3196 * FlushConsoleInputBuffer
3197 *
3198 * @implemented
3199 */
3200 BOOL
3201 WINAPI
3202 FlushConsoleInputBuffer(HANDLE hConsoleInput)
3203 {
3204 CSR_API_MESSAGE Request;
3205 ULONG CsrRequest;
3206 NTSTATUS Status;
3207
3208 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
3209 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
3210
3211 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3212 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3213 {
3214 SetLastErrorByStatus(Status);
3215 return FALSE;
3216 }
3217
3218 return TRUE;
3219 }
3220
3221
3222 /*--------------------------------------------------------------
3223 * SetConsoleScreenBufferSize
3224 *
3225 * @implemented
3226 */
3227 BOOL
3228 WINAPI
3229 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
3230 COORD dwSize)
3231 {
3232 CSR_API_MESSAGE Request;
3233 ULONG CsrRequest;
3234 NTSTATUS Status;
3235
3236 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE);
3237 Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
3238 Request.Data.SetScreenBufferSize.Size = dwSize;
3239
3240 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3241 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3242 {
3243 SetLastErrorByStatus(Status);
3244 return FALSE;
3245 }
3246
3247 return TRUE;
3248 }
3249
3250 /*--------------------------------------------------------------
3251 * SetConsoleCursorInfo
3252 *
3253 * @implemented
3254 */
3255 BOOL
3256 WINAPI
3257 SetConsoleCursorInfo(HANDLE hConsoleOutput,
3258 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
3259 {
3260 CSR_API_MESSAGE Request;
3261 ULONG CsrRequest;
3262 NTSTATUS Status;
3263
3264 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
3265 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3266 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
3267
3268 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3269 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3270 {
3271 SetLastErrorByStatus(Status);
3272 return FALSE;
3273 }
3274
3275 return TRUE;
3276 }
3277
3278
3279 static
3280 BOOL
3281 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
3282 const SMALL_RECT *lpScrollRectangle,
3283 const SMALL_RECT *lpClipRectangle,
3284 COORD dwDestinationOrigin,
3285 const CHAR_INFO *lpFill,
3286 BOOL bUnicode)
3287 {
3288 CSR_API_MESSAGE Request;
3289 ULONG CsrRequest;
3290 NTSTATUS Status;
3291
3292 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
3293 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
3294 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
3295 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
3296
3297 if (lpClipRectangle != NULL)
3298 {
3299 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
3300 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
3301 }
3302 else
3303 {
3304 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
3305 }
3306
3307 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
3308 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
3309
3310 Status = CsrClientCallServer(&Request,
3311 NULL,
3312 CsrRequest,
3313 sizeof(CSR_API_MESSAGE));
3314
3315 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3316 {
3317 SetLastErrorByStatus(Status);
3318 return FALSE;
3319 }
3320
3321 return TRUE;
3322 }
3323
3324
3325 /*--------------------------------------------------------------
3326 * ScrollConsoleScreenBufferA
3327 *
3328 * @implemented
3329 */
3330 BOOL
3331 WINAPI
3332 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
3333 CONST SMALL_RECT *lpScrollRectangle,
3334 CONST SMALL_RECT *lpClipRectangle,
3335 COORD dwDestinationOrigin,
3336 CONST CHAR_INFO *lpFill)
3337 {
3338 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3339 (PSMALL_RECT)lpScrollRectangle,
3340 (PSMALL_RECT)lpClipRectangle,
3341 dwDestinationOrigin,
3342 (PCHAR_INFO)lpFill,
3343 FALSE);
3344 }
3345
3346
3347 /*--------------------------------------------------------------
3348 * ScrollConsoleScreenBufferW
3349 *
3350 * @implemented
3351 */
3352 BOOL
3353 WINAPI
3354 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
3355 CONST SMALL_RECT *lpScrollRectangle,
3356 CONST SMALL_RECT *lpClipRectangle,
3357 COORD dwDestinationOrigin,
3358 CONST CHAR_INFO *lpFill)
3359 {
3360 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3361 lpScrollRectangle,
3362 lpClipRectangle,
3363 dwDestinationOrigin,
3364 lpFill,
3365 TRUE);
3366 }
3367
3368
3369 /*--------------------------------------------------------------
3370 * SetConsoleWindowInfo
3371 *
3372 * @unimplemented
3373 */
3374 BOOL
3375 WINAPI
3376 SetConsoleWindowInfo(HANDLE hConsoleOutput,
3377 BOOL bAbsolute,
3378 CONST SMALL_RECT *lpConsoleWindow)
3379 {
3380 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
3381 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3382 return FALSE;
3383 }
3384
3385
3386 /*--------------------------------------------------------------
3387 * SetConsoleTextAttribute
3388 *
3389 * @implemented
3390 */
3391 BOOL
3392 WINAPI
3393 SetConsoleTextAttribute(HANDLE hConsoleOutput,
3394 WORD wAttributes)
3395 {
3396 CSR_API_MESSAGE Request;
3397 ULONG CsrRequest;
3398 NTSTATUS Status;
3399
3400 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
3401 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
3402 Request.Data.SetAttribRequest.Attrib = wAttributes;
3403
3404 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3405 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3406 {
3407 SetLastErrorByStatus(Status);
3408 return FALSE;
3409 }
3410
3411 return TRUE;
3412 }
3413
3414
3415 static
3416 BOOL
3417 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)