d1e8a97038e6af7d5c6dd71b342567216cffcc2f
[reactos.git] / reactos / 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 /*
1376 * @unimplemented (Undocumented)
1377 */
1378 BOOL
1379 WINAPI
1380 SetLastConsoleEventActive(VOID)
1381 {
1382 DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
1383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1384 return FALSE;
1385 }
1386
1387
1388 /*
1389 * @unimplemented (Undocumented)
1390 */
1391 DWORD
1392 WINAPI
1393 ShowConsoleCursor(DWORD Unknown0,
1394 DWORD Unknown1)
1395 {
1396 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1397 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1398 return 0;
1399 }
1400
1401
1402 /*
1403 * FUNCTION: Checks whether the given handle is a valid console handle.
1404 * ARGUMENTS:
1405 * Handle - Handle to be checked
1406 * RETURNS:
1407 * TRUE: Handle is a valid console handle
1408 * FALSE: Handle is not a valid console handle.
1409 * STATUS: Officially undocumented
1410 *
1411 * @implemented
1412 */
1413 BOOL
1414 WINAPI
1415 VerifyConsoleIoHandle(HANDLE Handle)
1416 {
1417 CSR_API_MESSAGE Request;
1418 ULONG CsrRequest;
1419 NTSTATUS Status;
1420
1421 CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
1422 Request.Data.VerifyHandleRequest.Handle = Handle;
1423
1424 Status = CsrClientCallServer(&Request,
1425 NULL,
1426 CsrRequest,
1427 sizeof(CSR_API_MESSAGE));
1428 if (!NT_SUCCESS(Status))
1429 {
1430 SetLastErrorByStatus(Status);
1431 return FALSE;
1432 }
1433
1434 return (BOOL)NT_SUCCESS(Request.Status);
1435 }
1436
1437
1438 /*
1439 * @unimplemented
1440 */
1441 DWORD
1442 WINAPI
1443 WriteConsoleInputVDMA(DWORD Unknown0,
1444 DWORD Unknown1,
1445 DWORD Unknown2,
1446 DWORD Unknown3)
1447 {
1448 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1449 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1450 return 0;
1451 }
1452
1453
1454 /*
1455 * @unimplemented
1456 */
1457 DWORD
1458 WINAPI
1459 WriteConsoleInputVDMW(DWORD Unknown0,
1460 DWORD Unknown1,
1461 DWORD Unknown2,
1462 DWORD Unknown3)
1463 {
1464 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1465 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1466 return 0;
1467 }
1468
1469
1470 /*
1471 * @implemented (Undocumented)
1472 */
1473 BOOL
1474 WINAPI
1475 CloseConsoleHandle(HANDLE Handle)
1476 {
1477 CSR_API_MESSAGE Request;
1478 ULONG CsrRequest;
1479 NTSTATUS Status;
1480
1481 CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
1482 Request.Data.CloseHandleRequest.Handle = Handle;
1483
1484 Status = CsrClientCallServer(&Request,
1485 NULL,
1486 CsrRequest,
1487 sizeof(CSR_API_MESSAGE));
1488 if (!NT_SUCCESS(Status))
1489 {
1490 SetLastErrorByStatus(Status);
1491 return FALSE;
1492 }
1493
1494 return TRUE;
1495 }
1496
1497 /*
1498 * @implemented
1499 */
1500 HANDLE
1501 WINAPI
1502 GetStdHandle(DWORD nStdHandle)
1503 /*
1504 * FUNCTION: Get a handle for the standard input, standard output
1505 * and a standard error device.
1506 * ARGUMENTS:
1507 * nStdHandle - Specifies the device for which to return the handle.
1508 * RETURNS: If the function succeeds, the return value is the handle
1509 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1510 */
1511 {
1512 PRTL_USER_PROCESS_PARAMETERS Ppb;
1513
1514 Ppb = NtCurrentPeb()->ProcessParameters;
1515 switch (nStdHandle)
1516 {
1517 case STD_INPUT_HANDLE:
1518 return Ppb->StandardInput;
1519
1520 case STD_OUTPUT_HANDLE:
1521 return Ppb->StandardOutput;
1522
1523 case STD_ERROR_HANDLE:
1524 return Ppb->StandardError;
1525 }
1526
1527 SetLastError (ERROR_INVALID_PARAMETER);
1528 return INVALID_HANDLE_VALUE;
1529 }
1530
1531
1532 /*
1533 * @implemented
1534 */
1535 BOOL
1536 WINAPI
1537 SetStdHandle(DWORD nStdHandle,
1538 HANDLE hHandle)
1539 /*
1540 * FUNCTION: Set the handle for the standard input, standard output or
1541 * the standard error device.
1542 * ARGUMENTS:
1543 * nStdHandle - Specifies the handle to be set.
1544 * hHandle - The handle to set.
1545 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1546 */
1547 {
1548 PRTL_USER_PROCESS_PARAMETERS Ppb;
1549
1550 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1551
1552 Ppb = NtCurrentPeb()->ProcessParameters;
1553
1554 switch (nStdHandle)
1555 {
1556 case STD_INPUT_HANDLE:
1557 Ppb->StandardInput = hHandle;
1558 return TRUE;
1559
1560 case STD_OUTPUT_HANDLE:
1561 Ppb->StandardOutput = hHandle;
1562 return TRUE;
1563
1564 case STD_ERROR_HANDLE:
1565 Ppb->StandardError = hHandle;
1566 return TRUE;
1567 }
1568
1569 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1570 SetLastError(ERROR_INVALID_HANDLE);
1571 return FALSE;
1572 }
1573
1574
1575 static
1576 BOOL
1577 IntWriteConsole(HANDLE hConsoleOutput,
1578 PVOID lpBuffer,
1579 DWORD nNumberOfCharsToWrite,
1580 LPDWORD lpNumberOfCharsWritten,
1581 LPVOID lpReserved,
1582 BOOL bUnicode)
1583 {
1584 PCSR_API_MESSAGE Request;
1585 ULONG CsrRequest;
1586 NTSTATUS Status;
1587 USHORT nChars;
1588 ULONG SizeBytes, CharSize;
1589 DWORD Written = 0;
1590
1591 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1592 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1593 0,
1594 max(sizeof(CSR_API_MESSAGE),
1595 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
1596 CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
1597 if (Request == NULL)
1598 {
1599 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1600 return FALSE;
1601 }
1602
1603 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
1604
1605 while (nNumberOfCharsToWrite > 0)
1606 {
1607 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1608 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1609
1610 nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1611 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1612
1613 SizeBytes = nChars * CharSize;
1614
1615 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1616
1617 Status = CsrClientCallServer(Request,
1618 NULL,
1619 CsrRequest,
1620 max(sizeof(CSR_API_MESSAGE),
1621 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1622
1623 if (Status == STATUS_PENDING)
1624 {
1625 WaitForSingleObject(Request->Data.WriteConsoleRequest.UnpauseEvent, INFINITE);
1626 CloseHandle(Request->Data.WriteConsoleRequest.UnpauseEvent);
1627 continue;
1628 }
1629 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1630 {
1631 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1632 SetLastErrorByStatus(Status);
1633 return FALSE;
1634 }
1635
1636 nNumberOfCharsToWrite -= nChars;
1637 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1638 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1639 }
1640
1641 if (lpNumberOfCharsWritten != NULL)
1642 {
1643 *lpNumberOfCharsWritten = Written;
1644 }
1645 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1646
1647 return TRUE;
1648 }
1649
1650
1651 /*--------------------------------------------------------------
1652 * WriteConsoleA
1653 *
1654 * @implemented
1655 */
1656 BOOL
1657 WINAPI
1658 WriteConsoleA(HANDLE hConsoleOutput,
1659 CONST VOID *lpBuffer,
1660 DWORD nNumberOfCharsToWrite,
1661 LPDWORD lpNumberOfCharsWritten,
1662 LPVOID lpReserved)
1663 {
1664 return IntWriteConsole(hConsoleOutput,
1665 (PVOID)lpBuffer,
1666 nNumberOfCharsToWrite,
1667 lpNumberOfCharsWritten,
1668 lpReserved,
1669 FALSE);
1670 }
1671
1672
1673 /*--------------------------------------------------------------
1674 * WriteConsoleW
1675 *
1676 * @implemented
1677 */
1678 BOOL
1679 WINAPI
1680 WriteConsoleW(HANDLE hConsoleOutput,
1681 CONST VOID *lpBuffer,
1682 DWORD nNumberOfCharsToWrite,
1683 LPDWORD lpNumberOfCharsWritten,
1684 LPVOID lpReserved)
1685 {
1686 return IntWriteConsole(hConsoleOutput,
1687 (PVOID)lpBuffer,
1688 nNumberOfCharsToWrite,
1689 lpNumberOfCharsWritten,
1690 lpReserved,
1691 TRUE);
1692 }
1693
1694
1695 static
1696 BOOL
1697 IntReadConsole(HANDLE hConsoleInput,
1698 PVOID lpBuffer,
1699 DWORD nNumberOfCharsToRead,
1700 LPDWORD lpNumberOfCharsRead,
1701 PCONSOLE_READCONSOLE_CONTROL pInputControl,
1702 BOOL bUnicode)
1703 {
1704 CSR_API_MESSAGE Request;
1705 PCSR_CAPTURE_BUFFER CaptureBuffer;
1706 ULONG CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1707 NTSTATUS Status = STATUS_SUCCESS;
1708 ULONG CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1709
1710 CaptureBuffer = CsrAllocateCaptureBuffer(1, nNumberOfCharsToRead * CharSize);
1711 if (CaptureBuffer == NULL)
1712 {
1713 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1714 return FALSE;
1715 }
1716
1717 CsrAllocateMessagePointer(CaptureBuffer,
1718 nNumberOfCharsToRead * CharSize,
1719 &Request.Data.ReadConsoleRequest.Buffer);
1720
1721 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1722 Request.Data.ReadConsoleRequest.Unicode = bUnicode;
1723 Request.Data.ReadConsoleRequest.NrCharactersToRead = (WORD)nNumberOfCharsToRead;
1724 Request.Data.ReadConsoleRequest.NrCharactersRead = 0;
1725 Request.Data.ReadConsoleRequest.CtrlWakeupMask = 0;
1726 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
1727 {
1728 Request.Data.ReadConsoleRequest.NrCharactersRead = pInputControl->nInitialChars;
1729 memcpy(Request.Data.ReadConsoleRequest.Buffer,
1730 lpBuffer,
1731 pInputControl->nInitialChars * sizeof(WCHAR));
1732 Request.Data.ReadConsoleRequest.CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
1733 }
1734
1735 do
1736 {
1737 if (Status == STATUS_PENDING)
1738 {
1739 Status = NtWaitForSingleObject(Request.Data.ReadConsoleRequest.EventHandle,
1740 FALSE,
1741 0);
1742 if (!NT_SUCCESS(Status))
1743 {
1744 DPRINT1("Wait for console input failed!\n");
1745 break;
1746 }
1747 }
1748
1749 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
1750 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1751 {
1752 DPRINT1("CSR returned error in ReadConsole\n");
1753 CsrFreeCaptureBuffer(CaptureBuffer);
1754 SetLastErrorByStatus(Status);
1755 return FALSE;
1756 }
1757 }
1758 while (Status == STATUS_PENDING);
1759
1760 memcpy(lpBuffer,
1761 Request.Data.ReadConsoleRequest.Buffer,
1762 Request.Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1763
1764 if (lpNumberOfCharsRead != NULL)
1765 *lpNumberOfCharsRead = Request.Data.ReadConsoleRequest.NrCharactersRead;
1766
1767 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
1768 pInputControl->dwControlKeyState = Request.Data.ReadConsoleRequest.ControlKeyState;
1769
1770 CsrFreeCaptureBuffer(CaptureBuffer);
1771
1772 return TRUE;
1773 }
1774
1775
1776 /*--------------------------------------------------------------
1777 * ReadConsoleA
1778 *
1779 * @implemented
1780 */
1781 BOOL
1782 WINAPI
1783 ReadConsoleA(HANDLE hConsoleInput,
1784 LPVOID lpBuffer,
1785 DWORD nNumberOfCharsToRead,
1786 LPDWORD lpNumberOfCharsRead,
1787 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1788 {
1789 return IntReadConsole(hConsoleInput,
1790 lpBuffer,
1791 nNumberOfCharsToRead,
1792 lpNumberOfCharsRead,
1793 NULL,
1794 FALSE);
1795 }
1796
1797
1798 /*--------------------------------------------------------------
1799 * ReadConsoleW
1800 *
1801 * @implemented
1802 */
1803 BOOL
1804 WINAPI
1805 ReadConsoleW(HANDLE hConsoleInput,
1806 LPVOID lpBuffer,
1807 DWORD nNumberOfCharsToRead,
1808 LPDWORD lpNumberOfCharsRead,
1809 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1810 {
1811 return IntReadConsole(hConsoleInput,
1812 lpBuffer,
1813 nNumberOfCharsToRead,
1814 lpNumberOfCharsRead,
1815 pInputControl,
1816 TRUE);
1817 }
1818
1819
1820 /*--------------------------------------------------------------
1821 * AllocConsole
1822 *
1823 * @implemented
1824 */
1825 BOOL
1826 WINAPI
1827 AllocConsole(VOID)
1828 {
1829 CSR_API_MESSAGE Request;
1830 ULONG CsrRequest;
1831 NTSTATUS Status;
1832 HANDLE hStdError;
1833
1834 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1835 {
1836 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1837 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1838 return FALSE;
1839 }
1840
1841 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1842 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1843 Request.Data.AllocConsoleRequest.Visible = TRUE;
1844
1845 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1846
1847 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1848 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1849 {
1850 SetLastErrorByStatus(Status);
1851 return FALSE;
1852 }
1853
1854 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1855
1856 SetStdHandle(STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle);
1857 SetStdHandle(STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle);
1858
1859 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1860 0,
1861 TRUE,
1862 DUPLICATE_SAME_ACCESS);
1863
1864 SetStdHandle(STD_ERROR_HANDLE, hStdError);
1865 return TRUE;
1866 }
1867
1868
1869 /*--------------------------------------------------------------
1870 * FreeConsole
1871 *
1872 * @implemented
1873 */
1874 BOOL
1875 WINAPI
1876 FreeConsole(VOID)
1877 {
1878 // AG: I'm not sure if this is correct (what happens to std handles?)
1879 // but I just tried to reverse what AllocConsole() does...
1880
1881 CSR_API_MESSAGE Request;
1882 ULONG CsrRequest;
1883 NTSTATUS Status;
1884
1885 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1886
1887 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1888 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1889 {
1890 SetLastErrorByStatus(Status);
1891 return FALSE;
1892 }
1893
1894 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1895 return TRUE;
1896 }
1897
1898
1899 /*--------------------------------------------------------------
1900 * GetConsoleScreenBufferInfo
1901 *
1902 * @implemented
1903 */
1904 BOOL
1905 WINAPI
1906 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1907 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1908 {
1909 CSR_API_MESSAGE Request;
1910 ULONG CsrRequest;
1911 NTSTATUS Status;
1912
1913 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1914 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1915
1916 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1917 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1918 {
1919 SetLastErrorByStatus(Status);
1920 return FALSE;
1921 }
1922 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1923 return TRUE;
1924 }
1925
1926
1927 /*--------------------------------------------------------------
1928 * SetConsoleCursorPosition
1929 *
1930 * @implemented
1931 */
1932 BOOL
1933 WINAPI
1934 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1935 COORD dwCursorPosition)
1936 {
1937 CSR_API_MESSAGE Request;
1938 ULONG CsrRequest;
1939 NTSTATUS Status;
1940
1941 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1942 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1943 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1944
1945 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1946 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1947 {
1948 SetLastErrorByStatus(Status);
1949 return FALSE;
1950 }
1951
1952 return TRUE;
1953 }
1954
1955
1956 static
1957 BOOL
1958 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1959 PVOID cCharacter,
1960 DWORD nLength,
1961 COORD dwWriteCoord,
1962 LPDWORD lpNumberOfCharsWritten,
1963 BOOL bUnicode)
1964 {
1965 CSR_API_MESSAGE Request;
1966 ULONG CsrRequest;
1967 NTSTATUS Status;
1968
1969 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1970 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1971 Request.Data.FillOutputRequest.Unicode = bUnicode;
1972
1973 if(bUnicode)
1974 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1975 else
1976 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1977
1978 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1979 Request.Data.FillOutputRequest.Length = (WORD)nLength;
1980
1981 Status = CsrClientCallServer(&Request,
1982 NULL,
1983 CsrRequest,
1984 sizeof(CSR_API_MESSAGE));
1985
1986 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1987 {
1988 SetLastErrorByStatus(Status);
1989 return FALSE;
1990 }
1991
1992 if(lpNumberOfCharsWritten != NULL)
1993 {
1994 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1995 }
1996
1997 return TRUE;
1998 }
1999
2000 /*--------------------------------------------------------------
2001 * FillConsoleOutputCharacterA
2002 *
2003 * @implemented
2004 */
2005 BOOL
2006 WINAPI
2007 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
2008 CHAR cCharacter,
2009 DWORD nLength,
2010 COORD dwWriteCoord,
2011 LPDWORD lpNumberOfCharsWritten)
2012 {
2013 return IntFillConsoleOutputCharacter(hConsoleOutput,
2014 &cCharacter,
2015 nLength,
2016 dwWriteCoord,
2017 lpNumberOfCharsWritten,
2018 FALSE);
2019 }
2020
2021
2022 /*--------------------------------------------------------------
2023 * FillConsoleOutputCharacterW
2024 *
2025 * @implemented
2026 */
2027 BOOL
2028 WINAPI
2029 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
2030 WCHAR cCharacter,
2031 DWORD nLength,
2032 COORD dwWriteCoord,
2033 LPDWORD lpNumberOfCharsWritten)
2034 {
2035 return IntFillConsoleOutputCharacter(hConsoleOutput,
2036 &cCharacter,
2037 nLength,
2038 dwWriteCoord,
2039 lpNumberOfCharsWritten,
2040 TRUE);
2041 }
2042
2043
2044 static
2045 BOOL
2046 IntPeekConsoleInput(HANDLE hConsoleInput,
2047 PINPUT_RECORD lpBuffer,
2048 DWORD nLength,
2049 LPDWORD lpNumberOfEventsRead,
2050 BOOL bUnicode)
2051 {
2052 CSR_API_MESSAGE Request;
2053 ULONG CsrRequest;
2054 PCSR_CAPTURE_BUFFER CaptureBuffer;
2055 NTSTATUS Status;
2056 ULONG Size;
2057
2058 if (lpBuffer == NULL)
2059 {
2060 SetLastError(ERROR_INVALID_PARAMETER);
2061 return FALSE;
2062 }
2063
2064 Size = nLength * sizeof(INPUT_RECORD);
2065
2066 /* Allocate a Capture Buffer */
2067 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
2068 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2069
2070 /* Allocate space in the Buffer */
2071 CsrCaptureMessageBuffer(CaptureBuffer,
2072 NULL,
2073 Size,
2074 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
2075
2076 /* Set up the data to send to the Console Server */
2077 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
2078 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
2079 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
2080 Request.Data.PeekConsoleInputRequest.Length = nLength;
2081
2082 /* Call the server */
2083 Status = CsrClientCallServer(&Request,
2084 CaptureBuffer,
2085 CsrRequest,
2086 sizeof(CSR_API_MESSAGE));
2087 DPRINT("Server returned: %x\n", Request.Status);
2088
2089 /* Check for success*/
2090 if (NT_SUCCESS(Request.Status))
2091 {
2092 /* Return the number of events read */
2093 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
2094 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
2095
2096 /* Copy into the buffer */
2097 DPRINT("Copying to buffer\n");
2098 RtlCopyMemory(lpBuffer,
2099 Request.Data.PeekConsoleInputRequest.InputRecord,
2100 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
2101 }
2102 else
2103 {
2104 /* Error out */
2105 *lpNumberOfEventsRead = 0;
2106 SetLastErrorByStatus(Request.Status);
2107 }
2108
2109 /* Release the capture buffer */
2110 CsrFreeCaptureBuffer(CaptureBuffer);
2111
2112 /* Return TRUE or FALSE */
2113 return NT_SUCCESS(Request.Status);
2114 }
2115
2116 /*--------------------------------------------------------------
2117 * PeekConsoleInputA
2118 *
2119 * @implemented
2120 */
2121 BOOL
2122 WINAPI
2123 PeekConsoleInputA(HANDLE hConsoleInput,
2124 PINPUT_RECORD lpBuffer,
2125 DWORD nLength,
2126 LPDWORD lpNumberOfEventsRead)
2127 {
2128 return IntPeekConsoleInput(hConsoleInput,
2129 lpBuffer,
2130 nLength,
2131 lpNumberOfEventsRead,
2132 FALSE);
2133 }
2134
2135
2136 /*--------------------------------------------------------------
2137 * PeekConsoleInputW
2138 *
2139 * @implemented
2140 */
2141 BOOL
2142 WINAPI
2143 PeekConsoleInputW(HANDLE hConsoleInput,
2144 PINPUT_RECORD lpBuffer,
2145 DWORD nLength,
2146 LPDWORD lpNumberOfEventsRead)
2147 {
2148 return IntPeekConsoleInput(hConsoleInput,
2149 lpBuffer, nLength,
2150 lpNumberOfEventsRead,
2151 TRUE);
2152 }
2153
2154
2155 static
2156 BOOL
2157 IntReadConsoleInput(HANDLE hConsoleInput,
2158 PINPUT_RECORD lpBuffer,
2159 DWORD nLength,
2160 LPDWORD lpNumberOfEventsRead,
2161 BOOL bUnicode)
2162 {
2163 CSR_API_MESSAGE Request;
2164 ULONG CsrRequest;
2165 ULONG Read;
2166 NTSTATUS Status;
2167
2168 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
2169 Read = 0;
2170
2171 while (nLength > 0)
2172 {
2173 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
2174 Request.Data.ReadInputRequest.Unicode = bUnicode;
2175
2176 Status = CsrClientCallServer(&Request,
2177 NULL,
2178 CsrRequest,
2179 sizeof(CSR_API_MESSAGE));
2180 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2181 {
2182 if (Read == 0)
2183 {
2184 /* we couldn't read a single record, fail */
2185 SetLastErrorByStatus(Status);
2186 return FALSE;
2187 }
2188 else
2189 {
2190 /* FIXME - fail gracefully in case we already read at least one record? */
2191 break;
2192 }
2193 }
2194 else if (Status == STATUS_PENDING)
2195 {
2196 if (Read == 0)
2197 {
2198 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
2199 if (!NT_SUCCESS(Status))
2200 {
2201 SetLastErrorByStatus(Status);
2202 break;
2203 }
2204 }
2205 else
2206 {
2207 /* nothing more to read (waiting for more input??), let's just bail */
2208 break;
2209 }
2210 }
2211 else
2212 {
2213 lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
2214 nLength--;
2215
2216 if (!Request.Data.ReadInputRequest.MoreEvents)
2217 {
2218 /* nothing more to read, bail */
2219 break;
2220 }
2221 }
2222 }
2223
2224 if (lpNumberOfEventsRead != NULL)
2225 {
2226 *lpNumberOfEventsRead = Read;
2227 }
2228
2229 return (Read > 0);
2230 }
2231
2232
2233 /*--------------------------------------------------------------
2234 * ReadConsoleInputA
2235 *
2236 * @implemented
2237 */
2238 BOOL
2239 WINAPI
2240 ReadConsoleInputA(HANDLE hConsoleInput,
2241 PINPUT_RECORD lpBuffer,
2242 DWORD nLength,
2243 LPDWORD lpNumberOfEventsRead)
2244 {
2245 return IntReadConsoleInput(hConsoleInput,
2246 lpBuffer,
2247 nLength,
2248 lpNumberOfEventsRead,
2249 FALSE);
2250 }
2251
2252
2253 /*--------------------------------------------------------------
2254 * ReadConsoleInputW
2255 *
2256 * @implemented
2257 */
2258 BOOL
2259 WINAPI
2260 ReadConsoleInputW(HANDLE hConsoleInput,
2261 PINPUT_RECORD lpBuffer,
2262 DWORD nLength,
2263 LPDWORD lpNumberOfEventsRead)
2264 {
2265 return IntReadConsoleInput(hConsoleInput,
2266 lpBuffer,
2267 nLength,
2268 lpNumberOfEventsRead,
2269 TRUE);
2270 }
2271
2272
2273 static
2274 BOOL
2275 IntWriteConsoleInput(HANDLE hConsoleInput,
2276 PINPUT_RECORD lpBuffer,
2277 DWORD nLength,
2278 LPDWORD lpNumberOfEventsWritten,
2279 BOOL bUnicode)
2280 {
2281 CSR_API_MESSAGE Request;
2282 ULONG CsrRequest;
2283 PCSR_CAPTURE_BUFFER CaptureBuffer;
2284 NTSTATUS Status;
2285 DWORD Size;
2286
2287 if (lpBuffer == NULL)
2288 {
2289 SetLastError(ERROR_INVALID_PARAMETER);
2290 return FALSE;
2291 }
2292
2293 Size = nLength * sizeof(INPUT_RECORD);
2294
2295 /* Allocate a Capture Buffer */
2296 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
2297 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2298
2299 /* Allocate space in the Buffer */
2300 CsrCaptureMessageBuffer(CaptureBuffer,
2301 lpBuffer,
2302 Size,
2303 (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
2304
2305 /* Set up the data to send to the Console Server */
2306 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
2307 Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
2308 Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
2309 Request.Data.WriteConsoleInputRequest.Length = nLength;
2310
2311 /* Call the server */
2312 Status = CsrClientCallServer(&Request,
2313 CaptureBuffer,
2314 CsrRequest,
2315 sizeof(CSR_API_MESSAGE));
2316 DPRINT("Server returned: %x\n", Request.Status);
2317
2318 /* Check for success*/
2319 if (NT_SUCCESS(Request.Status))
2320 {
2321 /* Return the number of events read */
2322 DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
2323 *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
2324 }
2325 else
2326 {
2327 /* Error out */
2328 *lpNumberOfEventsWritten = 0;
2329 SetLastErrorByStatus(Request.Status);
2330 }
2331
2332 /* Release the capture buffer */
2333 CsrFreeCaptureBuffer(CaptureBuffer);
2334
2335 /* Return TRUE or FALSE */
2336 return NT_SUCCESS(Request.Status);
2337 }
2338
2339
2340 /*--------------------------------------------------------------
2341 * WriteConsoleInputA
2342 *
2343 * @implemented
2344 */
2345 BOOL
2346 WINAPI
2347 WriteConsoleInputA(HANDLE hConsoleInput,
2348 CONST INPUT_RECORD *lpBuffer,
2349 DWORD nLength,
2350 LPDWORD lpNumberOfEventsWritten)
2351 {
2352 return IntWriteConsoleInput(hConsoleInput,
2353 (PINPUT_RECORD)lpBuffer,
2354 nLength,
2355 lpNumberOfEventsWritten,
2356 FALSE);
2357 }
2358
2359
2360 /*--------------------------------------------------------------
2361 * WriteConsoleInputW
2362 *
2363 * @implemented
2364 */
2365 BOOL
2366 WINAPI
2367 WriteConsoleInputW(HANDLE hConsoleInput,
2368 CONST INPUT_RECORD *lpBuffer,
2369 DWORD nLength,
2370 LPDWORD lpNumberOfEventsWritten)
2371 {
2372 return IntWriteConsoleInput(hConsoleInput,
2373 (PINPUT_RECORD)lpBuffer,
2374 nLength,
2375 lpNumberOfEventsWritten,
2376 TRUE);
2377 }
2378
2379
2380 static
2381 BOOL
2382 IntReadConsoleOutput(HANDLE hConsoleOutput,
2383 PCHAR_INFO lpBuffer,
2384 COORD dwBufferSize,
2385 COORD dwBufferCoord,
2386 PSMALL_RECT lpReadRegion,
2387 BOOL bUnicode)
2388 {
2389 CSR_API_MESSAGE Request;
2390 ULONG CsrRequest;
2391 PCSR_CAPTURE_BUFFER CaptureBuffer;
2392 NTSTATUS Status;
2393 DWORD Size, SizeX, SizeY;
2394
2395 if (lpBuffer == NULL)
2396 {
2397 SetLastError(ERROR_INVALID_PARAMETER);
2398 return FALSE;
2399 }
2400
2401 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
2402
2403 /* Allocate a Capture Buffer */
2404 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
2405 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2406
2407 /* Allocate space in the Buffer */
2408 CsrCaptureMessageBuffer(CaptureBuffer,
2409 NULL,
2410 Size,
2411 (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
2412
2413 /* Set up the data to send to the Console Server */
2414 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
2415 Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2416 Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
2417 Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
2418 Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
2419 Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
2420
2421 /* Call the server */
2422 Status = CsrClientCallServer(&Request,
2423 CaptureBuffer,
2424 CsrRequest,
2425 sizeof(CSR_API_MESSAGE));
2426 DPRINT("Server returned: %x\n", Request.Status);
2427
2428 /* Check for success*/
2429 if (NT_SUCCESS(Request.Status))
2430 {
2431 /* Copy into the buffer */
2432 DPRINT("Copying to buffer\n");
2433 SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
2434 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
2435 SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
2436 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
2437 RtlCopyMemory(lpBuffer,
2438 Request.Data.ReadConsoleOutputRequest.CharInfo,
2439 sizeof(CHAR_INFO) * SizeX * SizeY);
2440 }
2441 else
2442 {
2443 /* Error out */
2444 SetLastErrorByStatus(Request.Status);
2445 }
2446
2447 /* Return the read region */
2448 DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
2449 *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
2450
2451 /* Release the capture buffer */
2452 CsrFreeCaptureBuffer(CaptureBuffer);
2453
2454 /* Return TRUE or FALSE */
2455 return NT_SUCCESS(Request.Status);
2456 }
2457
2458 /*--------------------------------------------------------------
2459 * ReadConsoleOutputA
2460 *
2461 * @implemented
2462 */
2463 BOOL
2464 WINAPI
2465 ReadConsoleOutputA(HANDLE hConsoleOutput,
2466 PCHAR_INFO lpBuffer,
2467 COORD dwBufferSize,
2468 COORD dwBufferCoord,
2469 PSMALL_RECT lpReadRegion)
2470 {
2471 return IntReadConsoleOutput(hConsoleOutput,
2472 lpBuffer,
2473 dwBufferSize,
2474 dwBufferCoord,
2475 lpReadRegion,
2476 FALSE);
2477 }
2478
2479
2480 /*--------------------------------------------------------------
2481 * ReadConsoleOutputW
2482 *
2483 * @implemented
2484 */
2485 BOOL
2486 WINAPI
2487 ReadConsoleOutputW(HANDLE hConsoleOutput,
2488 PCHAR_INFO lpBuffer,
2489 COORD dwBufferSize,
2490 COORD dwBufferCoord,
2491 PSMALL_RECT lpReadRegion)
2492 {
2493 return IntReadConsoleOutput(hConsoleOutput,
2494 lpBuffer,
2495 dwBufferSize,
2496 dwBufferCoord,
2497 lpReadRegion,
2498 TRUE);
2499 }
2500
2501
2502 static
2503 BOOL
2504 IntWriteConsoleOutput(HANDLE hConsoleOutput,
2505 CONST CHAR_INFO *lpBuffer,
2506 COORD dwBufferSize,
2507 COORD dwBufferCoord,
2508 PSMALL_RECT lpWriteRegion,
2509 BOOL bUnicode)
2510 {
2511 CSR_API_MESSAGE Request;
2512 ULONG CsrRequest;
2513 PCSR_CAPTURE_BUFFER CaptureBuffer;
2514 NTSTATUS Status;
2515 ULONG Size;
2516
2517 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
2518
2519 /* Allocate a Capture Buffer */
2520 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
2521 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2522
2523 /* Allocate space in the Buffer */
2524 CsrCaptureMessageBuffer(CaptureBuffer,
2525 NULL,
2526 Size,
2527 (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
2528
2529 /* Copy from the buffer */
2530 RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
2531
2532 /* Set up the data to send to the Console Server */
2533 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
2534 Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2535 Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
2536 Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
2537 Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
2538 Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
2539
2540 /* Call the server */
2541 Status = CsrClientCallServer(&Request,
2542 CaptureBuffer,
2543 CsrRequest,
2544 sizeof(CSR_API_MESSAGE));
2545 DPRINT("Server returned: %x\n", Request.Status);
2546
2547 /* Check for success*/
2548 if (!NT_SUCCESS(Request.Status))
2549 {
2550 /* Error out */
2551 SetLastErrorByStatus(Request.Status);
2552 }
2553
2554 /* Return the read region */
2555 DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
2556 *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
2557
2558 /* Release the capture buffer */
2559 CsrFreeCaptureBuffer(CaptureBuffer);
2560
2561 /* Return TRUE or FALSE */
2562 return NT_SUCCESS(Request.Status);
2563 }
2564
2565 /*--------------------------------------------------------------
2566 * WriteConsoleOutputA
2567 *
2568 * @implemented
2569 */
2570 BOOL
2571 WINAPI
2572 WriteConsoleOutputA(HANDLE hConsoleOutput,
2573 CONST CHAR_INFO *lpBuffer,
2574 COORD dwBufferSize,
2575 COORD dwBufferCoord,
2576 PSMALL_RECT lpWriteRegion)
2577 {
2578 return IntWriteConsoleOutput(hConsoleOutput,
2579 lpBuffer,
2580 dwBufferSize,
2581 dwBufferCoord,
2582 lpWriteRegion,
2583 FALSE);
2584 }
2585
2586
2587 /*--------------------------------------------------------------
2588 * WriteConsoleOutputW
2589 *
2590 * @implemented
2591 */
2592 BOOL
2593 WINAPI
2594 WriteConsoleOutputW(HANDLE hConsoleOutput,
2595 CONST CHAR_INFO *lpBuffer,
2596 COORD dwBufferSize,
2597 COORD dwBufferCoord,
2598 PSMALL_RECT lpWriteRegion)
2599 {
2600 return IntWriteConsoleOutput(hConsoleOutput,
2601 lpBuffer,
2602 dwBufferSize,
2603 dwBufferCoord,
2604 lpWriteRegion,
2605 TRUE);
2606 }
2607
2608
2609 static
2610 BOOL
2611 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
2612 PVOID lpCharacter,
2613 DWORD nLength,
2614 COORD dwReadCoord,
2615 LPDWORD lpNumberOfCharsRead,
2616 BOOL bUnicode)
2617 {
2618 PCSR_API_MESSAGE Request;
2619 ULONG CsrRequest;
2620 NTSTATUS Status;
2621 ULONG nChars, SizeBytes, CharSize;
2622 DWORD CharsRead = 0;
2623
2624 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2625
2626 nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) / CharSize;
2627 SizeBytes = nChars * CharSize;
2628
2629 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2630 max(sizeof(CSR_API_MESSAGE),
2631 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)
2632 + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2633 if (Request == NULL)
2634 {
2635 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2636 return FALSE;
2637 }
2638
2639 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2640 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
2641
2642 while (nLength > 0)
2643 {
2644 DWORD BytesRead;
2645
2646 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2647 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
2648 Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
2649 SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
2650
2651 Status = CsrClientCallServer(Request,
2652 NULL,
2653 CsrRequest,
2654 max(sizeof(CSR_API_MESSAGE),
2655 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
2656 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2657 {
2658 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2659 SetLastErrorByStatus(Status);
2660 break;
2661 }
2662
2663 BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
2664 memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
2665 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
2666 CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2667 nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2668
2669 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
2670 }
2671
2672 if (lpNumberOfCharsRead != NULL)
2673 {
2674 *lpNumberOfCharsRead = CharsRead;
2675 }
2676
2677 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2678
2679 return TRUE;
2680 }
2681
2682
2683 /*--------------------------------------------------------------
2684 * ReadConsoleOutputCharacterA
2685 *
2686 * @implemented
2687 */
2688 BOOL
2689 WINAPI
2690 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
2691 LPSTR lpCharacter,
2692 DWORD nLength,
2693 COORD dwReadCoord,
2694 LPDWORD lpNumberOfCharsRead)
2695 {
2696 return IntReadConsoleOutputCharacter(hConsoleOutput,
2697 (PVOID)lpCharacter,
2698 nLength,
2699 dwReadCoord,
2700 lpNumberOfCharsRead,
2701 FALSE);
2702 }
2703
2704
2705 /*--------------------------------------------------------------
2706 * ReadConsoleOutputCharacterW
2707 *
2708 * @implemented
2709 */
2710 BOOL
2711 WINAPI
2712 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
2713 LPWSTR lpCharacter,
2714 DWORD nLength,
2715 COORD dwReadCoord,
2716 LPDWORD lpNumberOfCharsRead)
2717 {
2718 return IntReadConsoleOutputCharacter(hConsoleOutput,
2719 (PVOID)lpCharacter,
2720 nLength,
2721 dwReadCoord,
2722 lpNumberOfCharsRead,
2723 TRUE);
2724 }
2725
2726
2727 /*--------------------------------------------------------------
2728 * ReadConsoleOutputAttribute
2729 *
2730 * @implemented
2731 */
2732 BOOL
2733 WINAPI
2734 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
2735 LPWORD lpAttribute,
2736 DWORD nLength,
2737 COORD dwReadCoord,
2738 LPDWORD lpNumberOfAttrsRead)
2739 {
2740 PCSR_API_MESSAGE Request;
2741 ULONG CsrRequest;
2742 NTSTATUS Status;
2743 DWORD Size;
2744
2745 if (lpNumberOfAttrsRead != NULL)
2746 *lpNumberOfAttrsRead = nLength;
2747
2748 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2749 0,
2750 max(sizeof(CSR_API_MESSAGE),
2751 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
2752 + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2753 if (Request == NULL)
2754 {
2755 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2756 return FALSE;
2757 }
2758
2759 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2760
2761 while (nLength != 0)
2762 {
2763 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2764 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2765
2766 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2767 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2768 else
2769 Size = nLength;
2770
2771 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2772
2773 Status = CsrClientCallServer(Request,
2774 NULL,
2775 CsrRequest,
2776 max(sizeof(CSR_API_MESSAGE),
2777 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2778 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2779 {
2780 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2781 SetLastErrorByStatus(Status);
2782 return FALSE;
2783 }
2784
2785 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2786 lpAttribute += Size;
2787 nLength -= Size;
2788 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2789 }
2790
2791 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2792
2793 return TRUE;
2794 }
2795
2796
2797 static
2798 BOOL
2799 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2800 PVOID lpCharacter,
2801 DWORD nLength,
2802 COORD dwWriteCoord,
2803 LPDWORD lpNumberOfCharsWritten,
2804 BOOL bUnicode)
2805 {
2806 PCSR_API_MESSAGE Request;
2807 ULONG CsrRequest;
2808 NTSTATUS Status;
2809 ULONG SizeBytes, CharSize, nChars;
2810 DWORD Written = 0;
2811
2812 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2813
2814 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2815 SizeBytes = nChars * CharSize;
2816
2817 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2818 max(sizeof(CSR_API_MESSAGE),
2819 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2820 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2821 if (Request == NULL)
2822 {
2823 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2824 return FALSE;
2825 }
2826
2827 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2828 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2829
2830 while (nLength > 0)
2831 {
2832 DWORD BytesWrite;
2833
2834 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2835 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2836 Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
2837 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2838
2839 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2840
2841 Status = CsrClientCallServer(Request,
2842 NULL,
2843 CsrRequest,
2844 max(sizeof(CSR_API_MESSAGE),
2845 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2846
2847 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2848 {
2849 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2850 SetLastErrorByStatus(Status);
2851 return FALSE;
2852 }
2853
2854 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2855 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2856 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2857
2858 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2859 }
2860
2861 if (lpNumberOfCharsWritten != NULL)
2862 {
2863 *lpNumberOfCharsWritten = Written;
2864 }
2865
2866 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2867
2868 return TRUE;
2869 }
2870
2871
2872 /*--------------------------------------------------------------
2873 * WriteConsoleOutputCharacterA
2874 *
2875 * @implemented
2876 */
2877 BOOL
2878 WINAPI
2879 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2880 LPCSTR lpCharacter,
2881 DWORD nLength,
2882 COORD dwWriteCoord,
2883 LPDWORD lpNumberOfCharsWritten)
2884 {
2885 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2886 (PVOID)lpCharacter,
2887 nLength,
2888 dwWriteCoord,
2889 lpNumberOfCharsWritten,
2890 FALSE);
2891 }
2892
2893
2894 /*--------------------------------------------------------------
2895 * WriteConsoleOutputCharacterW
2896 *
2897 * @implemented
2898 */
2899 BOOL
2900 WINAPI
2901 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2902 LPCWSTR lpCharacter,
2903 DWORD nLength,
2904 COORD dwWriteCoord,
2905 LPDWORD lpNumberOfCharsWritten)
2906 {
2907 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2908 (PVOID)lpCharacter,
2909 nLength,
2910 dwWriteCoord,
2911 lpNumberOfCharsWritten,
2912 TRUE);
2913 }
2914
2915
2916 /*--------------------------------------------------------------
2917 * WriteConsoleOutputAttribute
2918 *
2919 * @implemented
2920 */
2921 BOOL
2922 WINAPI
2923 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
2924 CONST WORD *lpAttribute,
2925 DWORD nLength,
2926 COORD dwWriteCoord,
2927 LPDWORD lpNumberOfAttrsWritten)
2928 {
2929 PCSR_API_MESSAGE Request;
2930 ULONG CsrRequest;
2931 NTSTATUS Status;
2932 WORD Size;
2933
2934 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2935 0,
2936 max(sizeof(CSR_API_MESSAGE),
2937 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2938 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2939 if (Request == NULL)
2940 {
2941 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2942 return FALSE;
2943 }
2944
2945 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2946 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2947
2948 if (lpNumberOfAttrsWritten)
2949 *lpNumberOfAttrsWritten = nLength;
2950 while (nLength)
2951 {
2952 Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2953 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2954 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2955 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2956
2957 Status = CsrClientCallServer(Request,
2958 NULL,
2959 CsrRequest,
2960 max(sizeof(CSR_API_MESSAGE),
2961 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2962
2963 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2964 {
2965 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2966 SetLastErrorByStatus (Status);
2967 return FALSE;
2968 }
2969 nLength -= Size;
2970 lpAttribute += Size;
2971 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2972 }
2973
2974 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2975
2976 return TRUE;
2977 }
2978
2979
2980 /*--------------------------------------------------------------
2981 * FillConsoleOutputAttribute
2982 *
2983 * @implemented
2984 */
2985 BOOL
2986 WINAPI
2987 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
2988 WORD wAttribute,
2989 DWORD nLength,
2990 COORD dwWriteCoord,
2991 LPDWORD lpNumberOfAttrsWritten)
2992 {
2993 CSR_API_MESSAGE Request;
2994 ULONG CsrRequest;
2995 NTSTATUS Status;
2996
2997 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2998 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2999 Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
3000 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
3001 Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
3002
3003 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3004 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3005 {
3006 SetLastErrorByStatus ( Status );
3007 return FALSE;
3008 }
3009
3010 if (lpNumberOfAttrsWritten)
3011 *lpNumberOfAttrsWritten = nLength;
3012
3013 return TRUE;
3014 }
3015
3016
3017 /*--------------------------------------------------------------
3018 * GetConsoleMode
3019 *
3020 * @implemented
3021 */
3022 BOOL
3023 WINAPI
3024 GetConsoleMode(HANDLE hConsoleHandle,
3025 LPDWORD lpMode)
3026 {
3027 CSR_API_MESSAGE Request;
3028 ULONG CsrRequest;
3029 NTSTATUS Status;
3030
3031 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
3032 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
3033
3034 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
3035 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3036 {
3037 SetLastErrorByStatus ( Status );
3038 return FALSE;
3039 }
3040 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
3041
3042 return TRUE;
3043 }
3044
3045
3046 /*--------------------------------------------------------------
3047 * GetNumberOfConsoleInputEvents
3048 *
3049 * @implemented
3050 */
3051 BOOL
3052 WINAPI
3053 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
3054 LPDWORD lpNumberOfEvents)
3055 {
3056 CSR_API_MESSAGE Request;
3057 ULONG CsrRequest;
3058 NTSTATUS Status;
3059
3060 if (lpNumberOfEvents == NULL)
3061 {
3062 SetLastError(ERROR_INVALID_PARAMETER);
3063 return FALSE;
3064 }
3065
3066 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
3067 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
3068
3069 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3070 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3071 {
3072 SetLastErrorByStatus(Status);
3073 return FALSE;
3074 }
3075
3076 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
3077
3078 return TRUE;
3079 }
3080
3081
3082 /*--------------------------------------------------------------
3083 * GetLargestConsoleWindowSize
3084 *
3085 * @unimplemented
3086 */
3087 COORD
3088 WINAPI
3089 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
3090 {
3091 COORD Coord = {80,25};
3092 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
3093 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3094 return Coord;
3095 }
3096
3097
3098 /*--------------------------------------------------------------
3099 * GetConsoleCursorInfo
3100 *
3101 * @implemented
3102 */
3103 BOOL
3104 WINAPI
3105 GetConsoleCursorInfo(HANDLE hConsoleOutput,
3106 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
3107 {
3108 CSR_API_MESSAGE Request;
3109 ULONG CsrRequest;
3110 NTSTATUS Status;
3111
3112 if (!lpConsoleCursorInfo)
3113 {
3114 if (!hConsoleOutput)
3115 SetLastError(ERROR_INVALID_HANDLE);
3116 else
3117 SetLastError(ERROR_INVALID_ACCESS);
3118
3119 return FALSE;
3120 }
3121
3122 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
3123 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3124
3125 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3126
3127 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3128 {
3129 SetLastErrorByStatus(Status);
3130 return FALSE;
3131 }
3132 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
3133
3134 return TRUE;
3135 }
3136
3137
3138 /*--------------------------------------------------------------
3139 * GetNumberOfConsoleMouseButtons
3140 *
3141 * @unimplemented
3142 */
3143 BOOL
3144 WINAPI
3145 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
3146 {
3147 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
3148 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3149 return FALSE;
3150 }
3151
3152
3153 /*--------------------------------------------------------------
3154 * SetConsoleMode
3155 *
3156 * @implemented
3157 */
3158 BOOL
3159 WINAPI
3160 SetConsoleMode(HANDLE hConsoleHandle,
3161 DWORD dwMode)
3162 {
3163 CSR_API_MESSAGE Request;
3164 ULONG CsrRequest;
3165 NTSTATUS Status;
3166
3167 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
3168 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
3169 Request.Data.SetConsoleModeRequest.Mode = dwMode;
3170
3171 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3172 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3173 {
3174 SetLastErrorByStatus ( Status );
3175 return FALSE;
3176 }
3177
3178 return TRUE;
3179 }
3180
3181
3182 /*--------------------------------------------------------------
3183 * SetConsoleActiveScreenBuffer
3184 *
3185 * @implemented
3186 */
3187 BOOL
3188 WINAPI
3189 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
3190 {
3191 CSR_API_MESSAGE Request;
3192 ULONG CsrRequest;
3193 NTSTATUS Status;
3194
3195 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
3196 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
3197
3198 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3199 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3200 {
3201 SetLastErrorByStatus(Status);
3202 return FALSE;
3203 }
3204
3205 return TRUE;
3206 }
3207
3208
3209 /*--------------------------------------------------------------
3210 * FlushConsoleInputBuffer
3211 *
3212 * @implemented
3213 */
3214 BOOL
3215 WINAPI
3216 FlushConsoleInputBuffer(HANDLE hConsoleInput)
3217 {
3218 CSR_API_MESSAGE Request;
3219 ULONG CsrRequest;
3220 NTSTATUS Status;
3221
3222 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
3223 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
3224
3225 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3226 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3227 {
3228 SetLastErrorByStatus(Status);
3229 return FALSE;
3230 }
3231
3232 return TRUE;
3233 }
3234
3235
3236 /*--------------------------------------------------------------
3237 * SetConsoleScreenBufferSize
3238 *
3239 * @implemented
3240 */
3241 BOOL
3242 WINAPI
3243 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
3244 COORD dwSize)
3245 {
3246 CSR_API_MESSAGE Request;
3247 ULONG CsrRequest;
3248 NTSTATUS Status;
3249
3250 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER_SIZE, CSR_CONSOLE);
3251 Request.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
3252 Request.Data.SetScreenBufferSize.Size = dwSize;
3253
3254 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3255 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3256 {
3257 SetLastErrorByStatus(Status);
3258 return FALSE;
3259 }
3260
3261 return TRUE;
3262 }
3263
3264 /*--------------------------------------------------------------
3265 * SetConsoleCursorInfo
3266 *
3267 * @implemented
3268 */
3269 BOOL
3270 WINAPI
3271 SetConsoleCursorInfo(HANDLE hConsoleOutput,
3272 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
3273 {
3274 CSR_API_MESSAGE Request;
3275 ULONG CsrRequest;
3276 NTSTATUS Status;
3277
3278 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
3279 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3280 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
3281
3282 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3283 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3284 {
3285 SetLastErrorByStatus(Status);
3286 return FALSE;
3287 }
3288
3289 return TRUE;
3290 }
3291
3292
3293 static
3294 BOOL
3295 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
3296 const SMALL_RECT *lpScrollRectangle,
3297 const SMALL_RECT *lpClipRectangle,
3298 COORD dwDestinationOrigin,
3299 const CHAR_INFO *lpFill,
3300 BOOL bUnicode)
3301 {
3302 CSR_API_MESSAGE Request;
3303 ULONG CsrRequest;
3304 NTSTATUS Status;
3305
3306 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
3307 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
3308 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
3309 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
3310
3311 if (lpClipRectangle != NULL)
3312 {
3313 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
3314 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
3315 }
3316 else
3317 {
3318 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
3319 }
3320
3321 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
3322 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
3323
3324 Status = CsrClientCallServer(&Request,
3325 NULL,
3326 CsrRequest,
3327 sizeof(CSR_API_MESSAGE));
3328
3329 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3330 {
3331 SetLastErrorByStatus(Status);
3332 return FALSE;
3333 }
3334
3335 return TRUE;
3336 }
3337
3338
3339 /*--------------------------------------------------------------
3340 * ScrollConsoleScreenBufferA
3341 *
3342 * @implemented
3343 */
3344 BOOL
3345 WINAPI
3346 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
3347 CONST SMALL_RECT *lpScrollRectangle,
3348 CONST SMALL_RECT *lpClipRectangle,
3349 COORD dwDestinationOrigin,
3350 CONST CHAR_INFO *lpFill)
3351 {
3352 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3353 (PSMALL_RECT)lpScrollRectangle,
3354 (PSMALL_RECT)lpClipRectangle,
3355 dwDestinationOrigin,
3356 (PCHAR_INFO)lpFill,
3357 FALSE);
3358 }
3359
3360
3361 /*--------------------------------------------------------------
3362 * ScrollConsoleScreenBufferW
3363 *
3364 * @implemented
3365 */
3366 BOOL
3367 WINAPI
3368 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
3369 CONST SMALL_RECT *lpScrollRectangle,
3370 CONST SMALL_RECT *lpClipRectangle,
3371 COORD dwDestinationOrigin,
3372 CONST CHAR_INFO *lpFill)
3373 {
3374 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3375 lpScrollRectangle,
3376 lpClipRectangle,
3377 dwDestinationOrigin,
3378 lpFill,
3379 TRUE);
3380 }
3381
3382
3383 /*--------------------------------------------------------------
3384 * SetConsoleWindowInfo
3385 *
3386 * @unimplemented
3387 */
3388 BOOL
3389 WINAPI
3390 SetConsoleWindowInfo(HANDLE hConsoleOutput,
3391 BOOL bAbsolute,
3392 CONST SMALL_RECT *lpConsoleWindow)
3393 {
3394 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
3395 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3396 return FALSE;
3397 }
3398
3399
3400 /*--------------------------------------------------------------
3401 * SetConsoleTextAttribute
3402 *
3403 * @implemented
3404 */
3405 BOOL
3406 WINAPI
3407 SetConsoleTextAttribute(HANDLE hConsoleOutput,
3408 WORD wAttributes)
3409 {
3410 CSR_API_MESSAGE Request;
3411 ULONG CsrRequest;
3412 NTSTATUS Status;
3413
3414 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
3415 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
3416 Request.Data.SetAttribRequest.Attrib = wAttributes;
3417
3418 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3419 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3420 {
3421 SetLastErrorByStatus(Status);
3422 return FALSE;
3423 }
3424
3425 return TRUE;
3426 }
3427
3428
3429 static
3430 BOOL
3431 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3432 {
3433 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
3434
3435 if (HandlerRoutine == NULL)
3436 {
3437 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
3438 return TRUE;
3439 }
3440
3441 if (NrCtrlHandlers == NrAllocatedHandlers)
3442 {
3443 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
3444 0,
3445 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
3446 if (NewCtrlHandlers == NULL)
3447 {
3448 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3449 return FALSE;
3450 }
3451
3452 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
3453
3454 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
3455
3456 CtrlHandlers = NewCtrlHandlers;
3457 NrAllocatedHandlers += 4;
3458 }
3459
3460 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
3461
3462 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
3463 return TRUE;
3464 }
3465
3466
3467 static
3468 BOOL
3469 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3470 {
3471 ULONG i;
3472
3473 if (HandlerRoutine == NULL)
3474 {
3475 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
3476 return TRUE;
3477 }
3478
3479 for (i = 0; i < NrCtrlHandlers; i++)
3480 {
3481 if (CtrlHandlers[i] == HandlerRoutine)
3482 {
3483 if (i < (NrCtrlHandlers - 1))
3484 {
3485 memmove(&CtrlHandlers[i],
3486 &CtrlHandlers[i+1],
3487 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
3488 }
3489
3490 NrCtrlHandlers--;
3491 return TRUE;
3492 }
3493 }
3494
3495 SetLastError(ERROR_INVALID_PARAMETER);
3496 return FALSE;
3497 }
3498
3499
3500 /*
3501 * @implemented
3502 */
3503 BOOL
3504 WINAPI
3505 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
3506 BOOL Add)
3507 {
3508 BOOL Ret;
3509
3510 RtlEnterCriticalSection(&DllLock);
3511 if (Add)
3512 {
3513 Ret = AddConsoleCtrlHandler(HandlerRoutine);
3514 }
3515 else
3516 {
3517 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
3518 }
3519
3520 RtlLeaveCriticalSection(&DllLock);
3521 return(Ret);
3522 }
3523
3524
3525 /*--------------------------------------------------------------
3526 * GenerateConsoleCtrlEvent
3527 *
3528 * @implemented
3529 */
3530 BOOL
3531 WINAPI
3532 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
3533 DWORD dwProcessGroupId)
3534 {
3535 CSR_API_MESSAGE Request;
3536 ULONG CsrRequest;
3537 NTSTATUS Status;
3538
3539 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
3540 {
3541 SetLastError(ERROR_INVALID_PARAMETER);
3542 return FALSE;
3543 }
3544
3545 CsrRequest = MAKE_CSR_API(GENERATE_CTRL_EVENT, CSR_CONSOLE);
3546 Request.Data.GenerateCtrlEvent.Event = dwCtrlEvent;
3547 Request.Data.GenerateCtrlEvent.ProcessGroup = dwProcessGroupId;
3548
3549 Status = CsrClientCallServer(&Request,
3550 NULL,
3551 CsrRequest,
3552 sizeof(CSR_API_MESSAGE));
3553 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
3554 {
3555 SetLastErrorByStatus(Status);
3556 return FALSE;
3557 }
3558
3559 return TRUE;
3560 }
3561
3562
3563 static DWORD
3564 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
3565 {
3566 CSR_API_MESSAGE Request;
3567 PCSR_CAPTURE_BUFFER CaptureBuffer;
3568 ULONG CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
3569 NTSTATUS Status;
3570
3571 if (nSize == 0)
3572 return 0;
3573
3574 Request.Data.GetTitleRequest.Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
3575 CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.GetTitleRequest.Length);
3576 if (CaptureBuffer == NULL)
3577 {
3578 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3579 return 0;
3580 }
3581
3582 CsrAllocateMessagePointer(CaptureBuffer,
3583 Request.Data.GetTitleRequest.Length,
3584 (PVOID*)&Request.Data.GetTitleRequest.Title);
3585
3586 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
3587 if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
3588 {
3589 CsrFreeCaptureBuffer(CaptureBuffer);
3590 SetLastErrorByStatus(Status);
3591 return 0;
3592 }
3593
3594 if (bUnicode)
3595 {
3596 if (nSize >= sizeof(WCHAR))
3597 wcscpy((LPWSTR)lpConsoleTitle, Request.Data.GetTitleRequest.Title);
3598 }
3599 else
3600 {
3601 if (nSize < Request.Data.GetTitleRequest.Length / sizeof(WCHAR) ||
3602 !WideCharToMultiByte(CP_ACP, // ANSI code page
3603 0, // performance and mapping flags
3604 Request.Data.GetTitleRequest.Title, // address of wide-character string
3605 -1, // number of characters in string
3606 (LPSTR)lpConsoleTitle, // address of buffer for new string
3607 nSize, // size of buffer
3608 NULL, // FAST
3609 NULL))
3610 {
3611 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
3612 *(LPSTR)lpConsoleTitle = '\0';
3613 Request.Data.GetTitleRequest.Length = 0;
3614 }
3615 }
3616 CsrFreeCaptureBuffer(CaptureBuffer);
3617
3618 return Request.Data.GetTitleRequest.Length / sizeof(WCHAR);
3619 }
3620
3621 /*--------------------------------------------------------------
3622 * GetConsoleTitleW
3623 *
3624 * @implemented
3625 */
3626 DWORD
3627 WINAPI
3628 GetConsoleTitleW(LPWSTR lpConsoleTitle,
3629 DWORD nSize)
3630 {
3631 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
3632 }
3633
3634 /*--------------------------------------------------------------
3635 * GetConsoleTitleA
3636 *
3637 * 19990306 EA
3638 *
3639 * @implemented
3640 */
3641 DWORD
3642 WINAPI
3643 GetConsoleTitleA(LPSTR lpConsoleTitle,
3644 DWORD nSize)
3645 {
3646 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
3647 }
3648
3649
3650 /*--------------------------------------------------------------
3651 * SetConsoleTitleW
3652 *
3653 * @implemented
3654 */
3655 BOOL
3656 WINAPI
3657 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
3658 {
3659 CSR_API_MESSAGE Request;
3660 PCSR_CAPTURE_BUFFER CaptureBuffer;
3661 ULONG CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3662 NTSTATUS Status;
3663
3664 Request.Data.SetTitleRequest.Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
3665
3666 CaptureBuffer = CsrAllocateCaptureBuffer(1, Request.Data.SetTitleRequest.Length);
3667 if (CaptureBuffer == NULL)
3668 {
3669 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3670 return FALSE;
3671 }
3672
3673 CsrCaptureMessageBuffer(CaptureBuffer,
3674 (PVOID)lpConsoleTitle,
3675 Request.Data.SetTitleRequest.Length,
3676 (PVOID*)&Request.Data.SetTitleRequest.Title);
3677
3678 Status = CsrClientCallServer(&Request, CaptureBuffer, CsrRequest, sizeof(CSR_API_MESSAGE));
3679 CsrFreeCaptureBuffer(CaptureBuffer);
3680 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3681 {
3682 SetLastErrorByStatus(Status);
3683 return FALSE;
3684 }
3685
3686 return TRUE;
3687 }
3688
3689
3690 /*--------------------------------------------------------------
3691 * SetConsoleTitleA
3692 *
3693 * 19990204 EA Added
3694 *
3695 * @implemented
3696 */
3697 BOOL
3698 WINAPI
3699 SetConsoleTitleA(LPCSTR lpConsoleTitle)
3700 {
3701 ULONG Length = strlen(lpConsoleTitle) + 1;
3702 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
3703 BOOL Ret;
3704 if (!WideTitle)
3705 {
3706 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3707 return FALSE;
3708 }
3709 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
3710 Ret = SetConsoleTitleW(WideTitle);
3711 HeapFree(GetProcessHeap(), 0, WideTitle);
3712 return Ret;
3713 }
3714
3715
3716 /*--------------------------------------------------------------
3717 * CreateConsoleScreenBuffer
3718 *
3719 * @implemented
3720 */
3721 HANDLE
3722 WINAPI
3723 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
3724 DWORD dwShareMode,
3725 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3726 DWORD dwFlags,
3727 LPVOID lpScreenBufferData)
3728 {
3729 CSR_API_MESSAGE Request;
3730 ULONG CsrRequest;
3731 NTSTATUS Status;
3732
3733 if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)
3734 || dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)
3735 || dwFlags != CONSOLE_TEXTMODE_BUFFER)
3736 {
3737 SetLastError(ERROR_INVALID_PARAMETER);
3738 return INVALID_HANDLE_VALUE;
3739 }
3740
3741 Request.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
3742 Request.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
3743 Request.Data.CreateScreenBufferRequest.Inheritable =
3744 lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE;
3745
3746 CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
3747 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3748 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3749 {
3750 SetLastErrorByStatus(Status);
3751 return INVALID_HANDLE_VALUE;
3752 }
3753 return Request.Data.CreateScreenBufferRequest.OutputHandle;
3754 }
3755
3756
3757 /*--------------------------------------------------------------
3758 * GetConsoleCP
3759 *
3760 * @implemented
3761 */
3762 UINT
3763 WINAPI
3764 GetConsoleCP(VOID)
3765 {
3766 CSR_API_MESSAGE Request;
3767 ULONG CsrRequest;
3768 NTSTATUS Status;
3769
3770 CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
3771 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3772 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3773 {
3774 SetLastErrorByStatus (Status);
3775 return 0;
3776 }
3777
3778 return Request.Data.GetConsoleCodePage.CodePage;
3779 }
3780
3781
3782 /*--------------------------------------------------------------
3783 * SetConsoleCP
3784 *
3785 * @implemented
3786 */
3787 BOOL
3788 WINAPI
3789 SetConsoleCP(UINT wCodePageID)
3790 {
3791 CSR_API_MESSAGE Request;
3792 ULONG CsrRequest;
3793 NTSTATUS Status;
3794
3795 CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
3796 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3797
3798 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3799 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3800 {
3801 SetLastErrorByStatus(Status);
3802 }
3803
3804 return NT_SUCCESS(Status);
3805 }
3806
3807
3808 /*--------------------------------------------------------------
3809 * GetConsoleOutputCP
3810 *
3811 * @implemented
3812 */
3813 UINT
3814 WINAPI
3815 GetConsoleOutputCP(VOID)
3816 {
3817 CSR_API_MESSAGE Request;
3818 ULONG CsrRequest;
3819 NTSTATUS Status;
3820
3821 CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3822 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3823 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3824 {
3825 SetLastErrorByStatus (Status);
3826 return 0;
3827 }
3828
3829 return Request.Data.GetConsoleOutputCodePage.CodePage;
3830 }
3831
3832
3833 /*--------------------------------------------------------------
3834 * SetConsoleOutputCP
3835 *
3836 * @implemented
3837 */
3838 BOOL
3839 WINAPI
3840 SetConsoleOutputCP(UINT wCodePageID)
3841 {
3842 CSR_API_MESSAGE Request;
3843 ULONG CsrRequest;
3844 NTSTATUS Status;
3845
3846 CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3847 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3848 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3849 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3850 {
3851 SetLastErrorByStatus(Status);
3852 }
3853
3854 return NT_SUCCESS(Status);
3855 }
3856
3857
3858 /*--------------------------------------------------------------
3859 * GetConsoleProcessList
3860 *
3861 * @implemented
3862 */
3863 DWORD
3864 WINAPI
3865 GetConsoleProcessList(LPDWORD lpdwProcessList,
3866 DWORD dwProcessCount)
3867 {
3868 PCSR_CAPTURE_BUFFER CaptureBuffer;
3869 CSR_API_MESSAGE Request;
3870 ULONG CsrRequest;
3871 ULONG nProcesses;
3872 NTSTATUS Status;
3873
3874 if (lpdwProcessList == NULL || dwProcessCount == 0)
3875 {
3876 SetLastError(ERROR_INVALID_PARAMETER);
3877 return 0;
3878 }
3879
3880 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
3881 if (CaptureBuffer == NULL)
3882 {
3883 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3884 return FALSE;
3885 }
3886
3887 CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
3888 Request.Data.GetProcessListRequest.nMaxIds = dwProcessCount;
3889 CsrAllocateMessagePointer(CaptureBuffer,
3890 dwProcessCount * sizeof(DWORD),
3891 (PVOID*)&Request.Data.GetProcessListRequest.ProcessId);
3892
3893 Status = CsrClientCallServer(&Request,
3894 CaptureBuffer,
3895 CsrRequest,
3896 sizeof(CSR_API_MESSAGE));
3897 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3898 {
3899 SetLastErrorByStatus (Status);
3900 nProcesses = 0;
3901 }
3902 else
3903 {
3904 nProcesses = Request.Data.GetProcessListRequest.nProcessIdsTotal;
3905 if (dwProcessCount >= nProcesses)
3906 {
3907 memcpy(lpdwProcessList, Request.Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
3908 }
3909 }
3910
3911 CsrFreeCaptureBuffer(CaptureBuffer);
3912 return nProcesses;
3913 }
3914
3915
3916
3917 /*--------------------------------------------------------------
3918 * GetConsoleSelectionInfo
3919 *
3920 * @implemented
3921 */
3922 BOOL
3923 WINAPI
3924 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3925 {
3926 CSR_API_MESSAGE Request;
3927 ULONG CsrRequest = MAKE_CSR_API(GET_CONSOLE_SELECTION_INFO, CSR_CONSOLE);
3928 NTSTATUS Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3929 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3930 {
3931 SetLastErrorByStatus(Status);
3932 return FALSE;
3933 }
3934
3935 *lpConsoleSelectionInfo = Request.Data.GetConsoleSelectionInfo.Info;
3936 return TRUE;
3937 }
3938
3939
3940
3941 /*--------------------------------------------------------------
3942 * AttachConsole
3943 *
3944 * @unimplemented
3945 */
3946 BOOL
3947 WINAPI
3948 AttachConsole(DWORD dwProcessId)
3949 {
3950 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
3951 return TRUE;
3952 }
3953
3954 /*--------------------------------------------------------------
3955 * GetConsoleWindow
3956 *
3957 * @implemented
3958 */
3959 HWND
3960 WINAPI
3961 GetConsoleWindow(VOID)
3962 {
3963 CSR_API_MESSAGE Request;
3964 ULONG CsrRequest;
3965 NTSTATUS Status;
3966
3967 CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
3968 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3969 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
3970 {
3971 SetLastErrorByStatus(Status);
3972 return (HWND) NULL;
3973 }
3974
3975 return Request.Data.GetConsoleWindowRequest.WindowHandle;
3976 }
3977
3978
3979 /*--------------------------------------------------------------
3980 * SetConsoleIcon
3981 *
3982 * @implemented
3983 */
3984 BOOL
3985 WINAPI
3986 SetConsoleIcon(HICON hicon)
3987 {
3988 CSR_API_MESSAGE Request;
3989 ULONG CsrRequest;
3990 NTSTATUS Status;
3991
3992 CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
3993 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3994
3995 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3996 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3997 {
3998 SetLastErrorByStatus(Status);
3999 return FALSE;
4000 }
4001
4002 return NT_SUCCESS(Status);
4003 }
4004
4005
4006 /******************************************************************************
4007 * \name SetConsoleInputExeNameW
4008 * \brief Sets the console input file name from a unicode string.
4009 * \param lpInputExeName Pointer to a unicode string with the name.
4010 * \return TRUE if successful, FALSE if unsuccsedful.
4011 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
4012 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
4013 */
4014 BOOL
4015 WINAPI
4016 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
4017 {
4018 int lenName;
4019
4020 if (!lpInputExeName
4021 || (lenName = lstrlenW(lpInputExeName)) == 0
4022 || lenName > INPUTEXENAME_BUFLEN - 1)
4023 {
4024 /* Fail if string is empty or too long */
4025 SetLastError(ERROR_INVALID_PARAMETER);
4026 return FALSE;
4027 }
4028
4029 RtlEnterCriticalSection(&ConsoleLock);
4030 _SEH2_TRY
4031 {
4032 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
4033 InputExeName[lenName] = L'\0';
4034 }
4035 _SEH2_FINALLY
4036 {
4037 RtlLeaveCriticalSection(&ConsoleLock);
4038 }
4039 _SEH2_END;
4040
4041 return TRUE;
4042 }
4043
4044
4045 /******************************************************************************
4046 * \name SetConsoleInputExeNameA
4047 * \brief Sets the console input file name from an ansi string.
4048 * \param lpInputExeName Pointer to an ansi string with the name.
4049 * \return TRUE if successful, FALSE if unsuccsedful.
4050 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
4051 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
4052 */
4053 BOOL
4054 WINAPI
4055 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
4056 {
4057 WCHAR Buffer[INPUTEXENAME_BUFLEN];
4058 ANSI_STRING InputExeNameA;
4059 UNICODE_STRING InputExeNameU;
4060 NTSTATUS Status;
4061 BOOL Ret;
4062
4063 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
4064
4065 if(InputExeNameA.Length == 0 ||
4066 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
4067 {
4068 /* Fail if string is empty or too long */
4069 SetLastError(ERROR_INVALID_PARAMETER);
4070 return FALSE;
4071 }
4072
4073 InputExeNameU.Buffer = Buffer;
4074 InputExeNameU.MaximumLength = sizeof(Buffer);
4075 InputExeNameU.Length = 0;
4076 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
4077 if(NT_SUCCESS(Status))
4078 {
4079 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
4080 }
4081 else
4082 {
4083 SetLastErrorByStatus(Status);
4084 Ret = FALSE;
4085 }
4086
4087 return Ret;
4088 }
4089
4090
4091 /******************************************************************************
4092 * \name GetConsoleInputExeNameW
4093 * \brief Retrieves the console input file name as unicode string.
4094 * \param nBufferLength Length of the buffer in WCHARs.
4095 * Specify 0 to recieve the needed buffer length.
4096 * \param lpBuffer Pointer to a buffer that recieves the string.
4097 * \return Needed buffer size if \p nBufferLength is 0.
4098 * Otherwise 1 if successful, 2 if buffer is too small.
4099 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
4100 * is not big enough.
4101 */
4102 DWORD
4103 WINAPI
4104 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
4105 {
4106 int lenName = lstrlenW(InputExeName);
4107
4108 if (nBufferLength == 0)
4109 {
4110 /* Buffer size is requested, return it */
4111 return lenName + 1;
4112 }
4113
4114 if(lenName + 1 > nBufferLength)
4115 {
4116 /* Buffer is not large enough! */
4117 SetLastError(ERROR_BUFFER_OVERFLOW);
4118 return 2;
4119 }
4120
4121 RtlEnterCriticalSection(&ConsoleLock);
4122 _SEH2_TRY
4123 {
4124 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
4125 lpBuffer[lenName] = '\0';
4126 }
4127 _SEH2_FINALLY
4128 {
4129 RtlLeaveCriticalSection(&ConsoleLock);
4130 }
4131 _SEH2_END;
4132
4133 /* Success, return 1 */
4134 return 1;
4135 }
4136
4137
4138 /******************************************************************************
4139 * \name GetConsoleInputExeNameA
4140 * \brief Retrieves the console input file name as ansi string.
4141 * \param nBufferLength Length of the buffer in CHARs.
4142 * \param lpBuffer Pointer to a buffer that recieves the string.
4143 * \return 1 if successful, 2 if buffer is too small.
4144 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
4145 * is not big enough. The buffer recieves as much characters as fit.
4146 */
4147 DWORD
4148 WINAPI
4149 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
4150 {
4151 WCHAR Buffer[INPUTEXENAME_BUFLEN];
4152 DWORD Ret;
4153 UNICODE_STRING BufferU;
4154 ANSI_STRING BufferA;
4155
4156 /* Get the unicode name */
4157 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
4158
4159 /* Initialize strings for conversion */
4160 RtlInitUnicodeString(&BufferU, Buffer);
4161 BufferA.Length = 0;
4162 BufferA.MaximumLength = nBufferLength;
4163 BufferA.Buffer = lpBuffer;
4164
4165 /* Convert unicode name to ansi, copying as much chars as fit */
4166 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
4167
4168 /* Error handling */
4169 if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
4170 {
4171 SetLastError(ERROR_BUFFER_OVERFLOW);
4172 return 2;
4173 }
4174
4175 return Ret;
4176 }
4177
4178
4179 /*--------------------------------------------------------------
4180 * GetConsoleHistoryInfo
4181 *
4182 * @implemented
4183 */
4184 BOOL
4185 WINAPI
4186 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
4187 {
4188 CSR_API_MESSAGE Request;
4189 ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE);
4190 NTSTATUS Status;
4191 if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO))
4192 {
4193 SetLastError(ERROR_INVALID_PARAMETER);
4194 return FALSE;
4195 }
4196 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
4197 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
4198 {
4199 SetLastErrorByStatus(Status);
4200 return FALSE;
4201 }
4202 lpConsoleHistoryInfo->HistoryBufferSize = Request.Data.GetHistoryInfo.HistoryBufferSize;
4203 lpConsoleHistoryInfo->NumberOfHistoryBuffers = Request.Data.GetHistoryInfo.NumberOfHistoryBuffers;
4204 lpConsoleHistoryInfo->dwFlags = Request.Data.GetHistoryInfo.dwFlags;
4205 return TRUE;
4206 }
4207
4208
4209 /*--------------------------------------------------------------
4210 * SetConsoleHistoryInfo
4211 *
4212 * @implemented
4213 */
4214 BOOL
4215 WINAPI
4216 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
4217 {
4218 CSR_API_MESSAGE Request;
4219 ULONG CsrRequest = MAKE_CSR_API(GET_HISTORY_INFO, CSR_CONSOLE);
4220 NTSTATUS Status;
4221 if (lpConsoleHistoryInfo->cbSize != sizeof(CONSOLE_HISTORY_INFO))
4222 {
4223 SetLastError(ERROR_INVALID_PARAMETER);
4224 return FALSE;
4225 }
4226 Request.Data.SetHistoryInfo.HistoryBufferSize = lpConsoleHistoryInfo->HistoryBufferSize;
4227 Request.Data.SetHistoryInfo.NumberOfHistoryBuffers = lpConsoleHistoryInfo->NumberOfHistoryBuffers;
4228 Request.Data.SetHistoryInfo.dwFlags = lpConsoleHistoryInfo->dwFlags;
4229 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
4230 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
4231 {
4232 SetLastErrorByStatus(Status);
4233 return FALSE;
4234 }
4235 return TRUE;
4236 }
4237
4238
4239 /*--------------------------------------------------------------
4240 * GetConsoleOriginalTitleW
4241 *
4242 * @unimplemented
4243 */
4244 DWORD
4245 WINAPI
4246 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
4247 IN DWORD nSize)
4248 {
4249 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4250 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4251 return 0;
4252 }
4253
4254
4255 /*--------------------------------------------------------------
4256 * GetConsoleOriginalTitleA
4257 *
4258 * @unimplemented
4259 */
4260 DWORD
4261 WINAPI
4262 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
4263 IN DWORD nSize)
4264 {
4265 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4266 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4267 return 0;
4268 }
4269
4270
4271 /*--------------------------------------------------------------
4272 * GetConsoleScreenBufferInfoEx
4273 *
4274 * @unimplemented
4275 */
4276 BOOL
4277 WINAPI
4278 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4279 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4280 {
4281 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4282 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4283 return FALSE;
4284 }
4285
4286
4287 /*--------------------------------------------------------------
4288 * SetConsoleScreenBufferInfoEx
4289 *
4290 * @unimplemented
4291 */
4292 BOOL
4293 WINAPI
4294 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4295 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4296 {
4297 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4298 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4299 return FALSE;
4300 }
4301
4302
4303 /*--------------------------------------------------------------
4304 * GetCurrentConsoleFontEx
4305 *
4306 * @unimplemented
4307 */
4308 BOOL
4309 WINAPI
4310 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
4311 IN BOOL bMaximumWindow,
4312 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
4313 {
4314 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
4315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4316 return FALSE;
4317 }
4318
4319 /* EOF */