[KERNEL32]: Bug fix CTRL-C handler registration/deregistration/notification, needed...
[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 switch(Event)
43 {
44 case CTRL_C_EVENT:
45 DPRINT("Ctrl-C Event\n");
46 break;
47
48 case CTRL_BREAK_EVENT:
49 DPRINT("Ctrl-Break Event\n");
50 break;
51
52 case CTRL_SHUTDOWN_EVENT:
53 DPRINT1("Ctrl Shutdown Event\n");
54 break;
55
56 case CTRL_CLOSE_EVENT:
57 DPRINT("Ctrl Close Event\n");
58 break;
59
60 case CTRL_LOGOFF_EVENT:
61 DPRINT1("Ctrl Logoff Event\n");
62 break;
63 }
64
65 ExitProcess(CONTROL_C_EXIT);
66 return TRUE;
67 }
68
69 __declspec(noreturn)
70 VOID
71 CALLBACK
72 ConsoleControlDispatcher(DWORD CodeAndFlag)
73 {
74 DWORD nExitCode = 0;
75 DWORD nCode = CodeAndFlag & MAXLONG;
76 UINT i;
77 EXCEPTION_RECORD erException;
78
79 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
80
81 switch(nCode)
82 {
83 case CTRL_C_EVENT:
84 case CTRL_BREAK_EVENT:
85 {
86 if (IsDebuggerPresent())
87 {
88 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
89 DBG_CONTROL_C : DBG_CONTROL_BREAK);
90 erException.ExceptionFlags = 0;
91 erException.ExceptionRecord = NULL;
92 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
93 erException.NumberParameters = 0;
94
95 _SEH2_TRY
96 {
97 RtlRaiseException(&erException);
98 }
99 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
100 {
101 RtlEnterCriticalSection(&ConsoleLock);
102
103 if ((nCode != CTRL_C_EVENT) ||
104 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
105 {
106 for (i = NrCtrlHandlers; i > 0; i--)
107 {
108 if (CtrlHandlers[i - 1](nCode)) break;
109 }
110 }
111
112 RtlLeaveCriticalSection(&ConsoleLock);
113 }
114 _SEH2_END;
115
116 ExitThread(0);
117 }
118
119 break;
120 }
121
122 case CTRL_CLOSE_EVENT:
123 case CTRL_LOGOFF_EVENT:
124 case CTRL_SHUTDOWN_EVENT:
125 break;
126
127 case 3:
128
129 ExitThread(0);
130 break;
131
132 case 4:
133
134 ExitProcess(CONTROL_C_EXIT);
135 break;
136
137 default:
138
139 ASSERT(FALSE);
140 break;
141 }
142
143 ASSERT(ConsoleInitialized);
144
145 RtlEnterCriticalSection(&ConsoleLock);
146 nExitCode = 0;
147 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
148 {
149 for (i = NrCtrlHandlers; i > 0; i--)
150 {
151 if ((i == 1) &&
152 (CodeAndFlag & MINLONG) &&
153 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
154 {
155 break;
156 }
157
158 if (CtrlHandlers[i - 1](nCode))
159 {
160 switch(nCode)
161 {
162 case CTRL_CLOSE_EVENT:
163 case CTRL_LOGOFF_EVENT:
164 case CTRL_SHUTDOWN_EVENT:
165 case 3:
166 nExitCode = CodeAndFlag;
167 break;
168 }
169 break;
170 }
171 }
172 }
173
174 RtlLeaveCriticalSection(&ConsoleLock);
175
176 ExitThread(nExitCode);
177 }
178
179
180 /* FUNCTIONS *****************************************************************/
181
182 /*
183 * @implemented
184 */
185 BOOL
186 WINAPI
187 AddConsoleAliasA(LPCSTR lpSource,
188 LPCSTR lpTarget,
189 LPCSTR lpExeName)
190 {
191 LPWSTR lpSourceW = NULL;
192 LPWSTR lpTargetW = NULL;
193 LPWSTR lpExeNameW = NULL;
194 BOOL bRetVal;
195
196 if (lpSource)
197 BasepAnsiStringToHeapUnicodeString(lpSource, (LPWSTR*) &lpSourceW);
198 if (lpTarget)
199 BasepAnsiStringToHeapUnicodeString(lpTarget, (LPWSTR*) &lpTargetW);
200 if (lpExeName)
201 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
202
203 bRetVal = AddConsoleAliasW(lpSourceW, lpTargetW, lpExeNameW);
204
205 /* Clean up */
206 if (lpSourceW)
207 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpSourceW);
208 if (lpTargetW)
209 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpTargetW);
210 if (lpExeNameW)
211 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
212
213 return bRetVal;
214 }
215
216
217 /*
218 * @unimplemented
219 */
220 BOOL
221 WINAPI
222 AddConsoleAliasW(LPCWSTR lpSource,
223 LPCWSTR lpTarget,
224 LPCWSTR lpExeName)
225 {
226 PCSR_API_MESSAGE Request;
227 ULONG CsrRequest;
228 NTSTATUS Status;
229 ULONG SourceLength;
230 ULONG TargetLength = 0;
231 ULONG ExeLength;
232 ULONG Size;
233 ULONG RequestLength;
234 WCHAR * Ptr;
235
236 DPRINT("AddConsoleAliasW enterd with lpSource %S lpTarget %S lpExeName %S\n", lpSource, lpTarget, lpExeName);
237
238 ExeLength = wcslen(lpExeName) + 1;
239 SourceLength = wcslen(lpSource)+ 1;
240 if (lpTarget)
241 TargetLength = wcslen(lpTarget) + 1;
242
243 Size = (ExeLength + SourceLength + TargetLength) * sizeof(WCHAR);
244 RequestLength = sizeof(CSR_API_MESSAGE) + Size;
245
246 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RequestLength);
247 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE));
248
249 wcscpy(Ptr, lpSource);
250 Request->Data.AddConsoleAlias.SourceLength = SourceLength;
251 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + SourceLength * sizeof(WCHAR));
252
253 wcscpy(Ptr, lpExeName);
254 Request->Data.AddConsoleAlias.ExeLength = ExeLength;
255 Ptr = (WCHAR*)(((ULONG_PTR)Request) + sizeof(CSR_API_MESSAGE) + (ExeLength + SourceLength)* sizeof(WCHAR));
256
257 if (lpTarget) /* target can be optional */
258 wcscpy(Ptr, lpTarget);
259
260 Request->Data.AddConsoleAlias.TargetLength = TargetLength;
261
262 CsrRequest = MAKE_CSR_API(ADD_CONSOLE_ALIAS, CSR_CONSOLE);
263 Status = CsrClientCallServer(Request,
264 NULL,
265 CsrRequest,
266 RequestLength);
267
268 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
269 {
270 SetLastErrorByStatus(Status);
271 RtlFreeHeap(GetProcessHeap(), 0, Request);
272 return FALSE;
273 }
274
275 RtlFreeHeap(GetProcessHeap(), 0, Request);
276 return TRUE;
277 }
278
279
280 /*
281 * @unimplemented (Undocumented)
282 */
283 BOOL
284 WINAPI
285 ConsoleMenuControl(HANDLE hConsole,
286 DWORD Unknown1,
287 DWORD Unknown2)
288 {
289 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
290 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
291 return FALSE;
292 }
293
294
295 /*
296 * @implemented
297 */
298 HANDLE
299 WINAPI
300 DuplicateConsoleHandle(HANDLE hConsole,
301 DWORD dwDesiredAccess,
302 BOOL bInheritHandle,
303 DWORD dwOptions)
304 {
305 CSR_API_MESSAGE Request;
306 ULONG CsrRequest;
307 NTSTATUS Status;
308
309 if (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)
310 || (!(dwOptions & DUPLICATE_SAME_ACCESS)
311 && dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)))
312 {
313 SetLastError (ERROR_INVALID_PARAMETER);
314 return INVALID_HANDLE_VALUE;
315 }
316
317 CsrRequest = MAKE_CSR_API(DUPLICATE_HANDLE, CSR_NATIVE);
318 Request.Data.DuplicateHandleRequest.Handle = hConsole;
319 Request.Data.DuplicateHandleRequest.Access = dwDesiredAccess;
320 Request.Data.DuplicateHandleRequest.Inheritable = bInheritHandle;
321 Request.Data.DuplicateHandleRequest.Options = dwOptions;
322
323 Status = CsrClientCallServer(&Request,
324 NULL,
325 CsrRequest,
326 sizeof(CSR_API_MESSAGE));
327 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Request.Status))
328 {
329 SetLastErrorByStatus(Status);
330 return INVALID_HANDLE_VALUE;
331 }
332
333 return Request.Data.DuplicateHandleRequest.Handle;
334 }
335
336
337 /*
338 * @unimplemented (Undocumented)
339 */
340 DWORD
341 WINAPI
342 ExpungeConsoleCommandHistoryW(DWORD Unknown0)
343 {
344 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
345 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
346 return 0;
347 }
348
349
350 /*
351 * @unimplemented (Undocumented)
352 */
353 DWORD
354 WINAPI
355 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
356 {
357 DPRINT1("ExpungeConsoleCommandHistoryW(0x%x) UNIMPLEMENTED!\n", Unknown0);
358 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
359 return 0;
360 }
361
362
363 /*
364 * @implemented
365 */
366 DWORD
367 WINAPI
368 GetConsoleAliasW(LPWSTR lpSource,
369 LPWSTR lpTargetBuffer,
370 DWORD TargetBufferLength,
371 LPWSTR lpExeName)
372 {
373 PCSR_API_MESSAGE Request;
374 PCSR_CAPTURE_BUFFER CaptureBuffer;
375 ULONG CsrRequest;
376 NTSTATUS Status;
377 ULONG Size;
378 ULONG ExeLength;
379 ULONG SourceLength;
380 ULONG RequestLength;
381 WCHAR * Ptr;
382
383 DPRINT("GetConsoleAliasW entered lpSource %S lpExeName %S\n", lpSource, lpExeName);
384
385 if (lpTargetBuffer == NULL)
386 {
387 SetLastError(ERROR_INVALID_PARAMETER);
388 return 0;
389 }
390
391 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIAS, CSR_CONSOLE);
392
393 ExeLength = wcslen(lpExeName) + 1;
394 SourceLength = wcslen(lpSource) + 1;
395
396 Size = (ExeLength + SourceLength) * sizeof(WCHAR);
397
398 RequestLength = Size + sizeof(CSR_API_MESSAGE);
399 Request = RtlAllocateHeap(GetProcessHeap(), 0, RequestLength);
400 if (Request == NULL)
401 {
402 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
403 return 0;
404 }
405
406 CaptureBuffer = CsrAllocateCaptureBuffer(1, TargetBufferLength);
407 if (!CaptureBuffer)
408 {
409 RtlFreeHeap(GetProcessHeap(), 0, Request);
410 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
411 return 0;
412 }
413
414 Request->Data.GetConsoleAlias.TargetBuffer = NULL;
415
416 CsrCaptureMessageBuffer(CaptureBuffer,
417 NULL,
418 TargetBufferLength,
419 (PVOID*)&Request->Data.GetConsoleAlias.TargetBuffer);
420
421 Request->Data.GetConsoleAlias.TargetBufferLength = TargetBufferLength;
422
423 Ptr = (LPWSTR)((ULONG_PTR)Request + sizeof(CSR_API_MESSAGE));
424 wcscpy(Ptr, lpSource);
425 Ptr += SourceLength;
426 wcscpy(Ptr, lpExeName);
427
428 Request->Data.GetConsoleAlias.ExeLength = ExeLength;
429 Request->Data.GetConsoleAlias.SourceLength = SourceLength;
430
431 Status = CsrClientCallServer(Request,
432 CaptureBuffer,
433 CsrRequest,
434 sizeof(CSR_API_MESSAGE) + Size);
435
436 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
437 {
438 RtlFreeHeap(GetProcessHeap(), 0, Request);
439 CsrFreeCaptureBuffer(CaptureBuffer);
440 SetLastErrorByStatus(Status);
441 return 0;
442 }
443
444 wcscpy(lpTargetBuffer, Request->Data.GetConsoleAlias.TargetBuffer);
445 RtlFreeHeap(GetProcessHeap(), 0, Request);
446 CsrFreeCaptureBuffer(CaptureBuffer);
447
448 return Request->Data.GetConsoleAlias.BytesWritten;
449 }
450
451
452 /*
453 * @implemented
454 */
455 DWORD
456 WINAPI
457 GetConsoleAliasA(LPSTR lpSource,
458 LPSTR lpTargetBuffer,
459 DWORD TargetBufferLength,
460 LPSTR lpExeName)
461 {
462 LPWSTR lpwSource;
463 LPWSTR lpwExeName;
464 LPWSTR lpwTargetBuffer;
465 UINT dwSourceSize;
466 UINT dwExeNameSize;
467 UINT dwResult;
468
469 DPRINT("GetConsoleAliasA entered\n");
470
471 if (lpTargetBuffer == NULL)
472 {
473 SetLastError(ERROR_INVALID_PARAMETER);
474 return 0;
475 }
476
477 dwSourceSize = (strlen(lpSource)+1) * sizeof(WCHAR);
478 lpwSource = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceSize);
479 if (lpwSource == NULL)
480 {
481 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
482 return 0;
483 }
484 MultiByteToWideChar(CP_ACP, 0, lpSource, -1, lpwSource, dwSourceSize);
485
486 dwExeNameSize = (strlen(lpExeName)+1) * sizeof(WCHAR);
487 lpwExeName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwExeNameSize);
488 if (lpwExeName == NULL)
489 {
490 HeapFree(GetProcessHeap(), 0, lpwSource);
491 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
492 return 0;
493 }
494 MultiByteToWideChar(CP_ACP, 0, lpExeName, -1, lpwExeName, dwExeNameSize);
495
496 lpwTargetBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, TargetBufferLength * sizeof(WCHAR));
497 if (lpwTargetBuffer == NULL)
498 {
499 HeapFree(GetProcessHeap(), 0, lpwSource);
500 HeapFree(GetProcessHeap(), 0, lpwExeName);
501 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
502 return 0;
503 }
504
505 dwResult = GetConsoleAliasW(lpwSource, lpwTargetBuffer, TargetBufferLength * sizeof(WCHAR), lpwExeName);
506
507 HeapFree(GetProcessHeap(), 0, lpwSource);
508 HeapFree(GetProcessHeap(), 0, lpwExeName);
509
510 if (dwResult)
511 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwTargetBuffer, dwResult / sizeof(WCHAR), lpTargetBuffer, TargetBufferLength, NULL, NULL);
512
513 HeapFree(GetProcessHeap(), 0, lpwTargetBuffer);
514
515 return dwResult;
516 }
517
518
519 /*
520 * @implemented
521 */
522 DWORD
523 WINAPI
524 GetConsoleAliasExesW(LPWSTR lpExeNameBuffer,
525 DWORD ExeNameBufferLength)
526 {
527 CSR_API_MESSAGE Request;
528 PCSR_CAPTURE_BUFFER CaptureBuffer;
529 ULONG CsrRequest;
530 NTSTATUS Status;
531
532 DPRINT("GetConsoleAliasExesW entered\n");
533
534 CaptureBuffer = CsrAllocateCaptureBuffer(1, ExeNameBufferLength);
535 if (!CaptureBuffer)
536 {
537 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
538 return 0;
539 }
540
541 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES, CSR_CONSOLE);
542 CsrAllocateMessagePointer(CaptureBuffer,
543 ExeNameBufferLength,
544 (PVOID*)&Request.Data.GetConsoleAliasesExes.ExeNames);
545 Request.Data.GetConsoleAliasesExes.Length = ExeNameBufferLength;
546
547 Status = CsrClientCallServer(&Request,
548 CaptureBuffer,
549 CsrRequest,
550 sizeof(CSR_API_MESSAGE));
551
552 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
553 {
554 SetLastErrorByStatus(Status);
555 CsrFreeCaptureBuffer(CaptureBuffer);
556 return 0;
557 }
558
559 memcpy(lpExeNameBuffer,
560 Request.Data.GetConsoleAliasesExes.ExeNames,
561 Request.Data.GetConsoleAliasesExes.BytesWritten);
562
563 CsrFreeCaptureBuffer(CaptureBuffer);
564 return Request.Data.GetConsoleAliasesExes.BytesWritten;
565 }
566
567
568 /*
569 * @implemented
570 */
571 DWORD
572 WINAPI
573 GetConsoleAliasExesA(LPSTR lpExeNameBuffer,
574 DWORD ExeNameBufferLength)
575 {
576 LPWSTR lpwExeNameBuffer;
577 DWORD dwResult;
578
579 DPRINT("GetConsoleAliasExesA entered\n");
580
581 lpwExeNameBuffer = HeapAlloc(GetProcessHeap(), 0, ExeNameBufferLength * sizeof(WCHAR));
582
583 dwResult = GetConsoleAliasExesW(lpwExeNameBuffer, ExeNameBufferLength * sizeof(WCHAR));
584
585 if (dwResult)
586 dwResult = WideCharToMultiByte(CP_ACP, 0, lpwExeNameBuffer, dwResult / sizeof(WCHAR), lpExeNameBuffer, ExeNameBufferLength, NULL, NULL);
587
588 HeapFree(GetProcessHeap(), 0, lpwExeNameBuffer);
589 return dwResult;
590 }
591
592 /*
593 * @implemented
594 */
595 DWORD
596 WINAPI
597 GetConsoleAliasExesLengthW(VOID)
598 {
599 CSR_API_MESSAGE Request;
600 ULONG CsrRequest;
601 NTSTATUS Status;
602
603 DPRINT("GetConsoleAliasExesLengthW entered\n");
604
605 CsrRequest = MAKE_CSR_API(GET_CONSOLE_ALIASES_EXES_LENGTH, CSR_CONSOLE);
606 Request.Data.GetConsoleAliasesExesLength.Length = 0;
607
608
609 Status = CsrClientCallServer(&Request,
610 NULL,
611 CsrRequest,
612 sizeof(CSR_API_MESSAGE));
613
614 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
615 {
616 SetLastErrorByStatus(Status);
617 return 0;
618 }
619
620 return Request.Data.GetConsoleAliasesExesLength.Length;
621 }
622
623 /*
624 * @implemented
625 */
626 DWORD
627 WINAPI
628 GetConsoleAliasExesLengthA(VOID)
629 {
630 DWORD dwLength;
631
632 DPRINT("GetConsoleAliasExesLengthA entered\n");
633
634 dwLength = GetConsoleAliasExesLengthW();
635
636 if (dwLength)
637 dwLength /= sizeof(WCHAR);
638
639 return dwLength;
640 }
641
642
643 /*
644 * @implemented
645 */
646 DWORD
647 WINAPI
648 GetConsoleAliasesW(LPWSTR AliasBuffer,
649 DWORD AliasBufferLength,
650 LPWSTR ExeName)
651 {
652 CSR_API_MESSAGE Request;
653 ULONG CsrRequest;
654 NTSTATUS Status;
655 DWORD dwLength;
656
657 DPRINT("GetConsoleAliasesW entered\n");
658
659 dwLength = GetConsoleAliasesLengthW(ExeName);
660 if (!dwLength || dwLength > AliasBufferLength)
661 return 0;
662
663 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES, CSR_CONSOLE);
664 Request.Data.GetAllConsoleAlias.AliasBuffer = AliasBuffer;
665 Request.Data.GetAllConsoleAlias.AliasBufferLength = AliasBufferLength;
666 Request.Data.GetAllConsoleAlias.lpExeName = ExeName;
667
668 Status = CsrClientCallServer(&Request,
669 NULL,
670 CsrRequest,
671 sizeof(CSR_API_MESSAGE));
672
673 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
674 {
675 SetLastErrorByStatus(Status);
676 return 0;
677 }
678
679 return Request.Data.GetAllConsoleAlias.BytesWritten / sizeof(WCHAR);
680 }
681
682
683 /*
684 * @implemented
685 */
686 DWORD
687 WINAPI
688 GetConsoleAliasesA(LPSTR AliasBuffer,
689 DWORD AliasBufferLength,
690 LPSTR ExeName)
691 {
692 DWORD dwRetVal = 0;
693 LPWSTR lpwExeName = NULL;
694 LPWSTR lpwAliasBuffer;
695
696 DPRINT("GetConsoleAliasesA entered\n");
697
698 if (ExeName)
699 BasepAnsiStringToHeapUnicodeString(ExeName, (LPWSTR*) &lpwExeName);
700
701 lpwAliasBuffer = HeapAlloc(GetProcessHeap(), 0, AliasBufferLength * sizeof(WCHAR));
702
703 dwRetVal = GetConsoleAliasesW(lpwAliasBuffer, AliasBufferLength, lpwExeName);
704
705 if (lpwExeName)
706 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpwExeName);
707
708 if (dwRetVal)
709 dwRetVal = WideCharToMultiByte(CP_ACP, 0, lpwAliasBuffer, dwRetVal, AliasBuffer, AliasBufferLength, NULL, NULL);
710
711 HeapFree(GetProcessHeap(), 0, lpwAliasBuffer);
712 return dwRetVal;
713 }
714
715
716 /*
717 * @implemented
718 */
719 DWORD
720 WINAPI
721 GetConsoleAliasesLengthW(LPWSTR lpExeName)
722 {
723 CSR_API_MESSAGE Request;
724 ULONG CsrRequest;
725 NTSTATUS Status;
726
727 DPRINT("GetConsoleAliasesLengthW entered\n");
728
729 CsrRequest = MAKE_CSR_API(GET_ALL_CONSOLE_ALIASES_LENGTH, CSR_CONSOLE);
730 Request.Data.GetAllConsoleAliasesLength.lpExeName = lpExeName;
731 Request.Data.GetAllConsoleAliasesLength.Length = 0;
732
733 Status = CsrClientCallServer(&Request,
734 NULL,
735 CsrRequest,
736 sizeof(CSR_API_MESSAGE));
737
738 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
739 {
740 SetLastErrorByStatus(Status);
741 return 0;
742 }
743
744 return Request.Data.GetAllConsoleAliasesLength.Length;
745 }
746
747
748 /*
749 * @implemented
750 */
751 DWORD
752 WINAPI
753 GetConsoleAliasesLengthA(LPSTR lpExeName)
754 {
755 DWORD dwRetVal = 0;
756 LPWSTR lpExeNameW = NULL;
757
758 if (lpExeName)
759 BasepAnsiStringToHeapUnicodeString(lpExeName, (LPWSTR*) &lpExeNameW);
760
761 dwRetVal = GetConsoleAliasesLengthW(lpExeNameW);
762 if (dwRetVal)
763 dwRetVal /= sizeof(WCHAR);
764
765 /* Clean up */
766 if (lpExeNameW)
767 RtlFreeHeap(GetProcessHeap(), 0, (LPWSTR*) lpExeNameW);
768
769 return dwRetVal;
770 }
771
772
773 /*
774 * @unimplemented (Undocumented)
775 */
776 DWORD
777 WINAPI
778 GetConsoleCommandHistoryW(DWORD Unknown0,
779 DWORD Unknown1,
780 DWORD Unknown2)
781 {
782 DPRINT1("GetConsoleCommandHistoryW(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
783 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
784 return 0;
785 }
786
787
788 /*
789 * @unimplemented (Undocumented)
790 */
791 DWORD
792 WINAPI
793 GetConsoleCommandHistoryA(DWORD Unknown0,
794 DWORD Unknown1,
795 DWORD Unknown2)
796 {
797 DPRINT1("GetConsoleCommandHistoryA(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
798 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
799 return 0;
800 }
801
802
803 /*
804 * @unimplemented (Undocumented)
805 */
806 DWORD
807 WINAPI
808 GetConsoleCommandHistoryLengthW(DWORD Unknown0)
809 {
810 DPRINT1("GetConsoleCommandHistoryLengthW(0x%x) UNIMPLEMENTED!\n", Unknown0);
811 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
812 return 0;
813 }
814
815
816 /*
817 * @unimplemented (Undocumented)
818 */
819 DWORD
820 WINAPI
821 GetConsoleCommandHistoryLengthA(DWORD Unknown0)
822 {
823 DPRINT1("GetConsoleCommandHistoryLengthA(0x%x) UNIMPLEMENTED!\n", Unknown0);
824 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
825 return 0;
826 }
827
828 /*
829 * @unimplemented
830 */
831 INT
832 WINAPI
833 GetConsoleDisplayMode(LPDWORD lpdwMode)
834 /*
835 * FUNCTION: Get the console display mode
836 * ARGUMENTS:
837 * lpdwMode - Address of variable that receives the current value
838 * of display mode
839 * STATUS: Undocumented
840 */
841 {
842 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
843 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
844 return 0;
845 }
846
847
848 /*
849 * @unimplemented (Undocumented)
850 */
851 DWORD
852 WINAPI
853 GetConsoleFontInfo(DWORD Unknown0,
854 DWORD Unknown1,
855 DWORD Unknown2,
856 DWORD Unknown3)
857 {
858 DPRINT1("GetConsoleFontInfo(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
859 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
860 return 0;
861 }
862
863
864 /*
865 * @unimplemented
866 */
867 COORD
868 WINAPI
869 GetConsoleFontSize(HANDLE hConsoleOutput,
870 DWORD nFont)
871 {
872 COORD Empty = {0, 0};
873 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
874 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
875 return Empty;
876 }
877
878
879 /*
880 * @implemented (Undocumented)
881 */
882 DWORD
883 WINAPI
884 GetConsoleHardwareState(HANDLE hConsole,
885 DWORD Flags,
886 PDWORD State)
887 {
888 CSR_API_MESSAGE Request;
889 ULONG CsrRequest;
890 NTSTATUS Status;
891
892 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
893 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
894 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
895
896 Status = CsrClientCallServer(&Request,
897 NULL,
898 CsrRequest,
899 sizeof(CSR_API_MESSAGE));
900 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
901 {
902 SetLastErrorByStatus(Status);
903 return FALSE;
904 }
905
906 *State = Request.Data.ConsoleHardwareStateRequest.State;
907 return TRUE;
908 }
909
910
911 /*
912 * @implemented (Undocumented)
913 */
914 HANDLE
915 WINAPI
916 GetConsoleInputWaitHandle(VOID)
917 {
918 CSR_API_MESSAGE Request;
919 ULONG CsrRequest;
920 NTSTATUS Status;
921
922 CsrRequest = MAKE_CSR_API(GET_INPUT_WAIT_HANDLE, CSR_CONSOLE);
923
924 Status = CsrClientCallServer(&Request,
925 NULL,
926 CsrRequest,
927 sizeof(CSR_API_MESSAGE));
928 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
929 {
930 SetLastErrorByStatus(Status);
931 return 0;
932 }
933
934 return Request.Data.GetConsoleInputWaitHandle.InputWaitHandle;
935 }
936
937
938 /*
939 * @unimplemented
940 */
941 INT
942 WINAPI
943 GetCurrentConsoleFont(HANDLE hConsoleOutput,
944 BOOL bMaximumWindow,
945 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
946 {
947 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
948 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
949 return 0;
950 }
951
952
953 /*
954 * @unimplemented (Undocumented)
955 */
956 ULONG
957 WINAPI
958 GetNumberOfConsoleFonts(VOID)
959 {
960 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
961 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
962 return 1; /* FIXME: call csrss.exe */
963 }
964
965
966 /*
967 * @unimplemented (Undocumented)
968 */
969 DWORD
970 WINAPI
971 InvalidateConsoleDIBits(DWORD Unknown0,
972 DWORD Unknown1)
973 {
974 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
975 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
976 return 0;
977 }
978
979
980 /*
981 * @unimplemented (Undocumented)
982 */
983 HANDLE
984 WINAPI
985 OpenConsoleW(LPCWSTR wsName,
986 DWORD dwDesiredAccess,
987 BOOL bInheritHandle,
988 DWORD dwShareMode)
989 {
990 CSR_API_MESSAGE Request;
991 ULONG CsrRequest;
992 NTSTATUS Status = STATUS_SUCCESS;
993
994 if (0 == _wcsicmp(wsName, L"CONIN$"))
995 {
996 CsrRequest = MAKE_CSR_API(GET_INPUT_HANDLE, CSR_NATIVE);
997 }
998 else if (0 == _wcsicmp(wsName, L"CONOUT$"))
999 {
1000 CsrRequest = MAKE_CSR_API(GET_OUTPUT_HANDLE, CSR_NATIVE);
1001 }
1002 else
1003 {
1004 SetLastError(ERROR_INVALID_PARAMETER);
1005 return(INVALID_HANDLE_VALUE);
1006 }
1007
1008 if (dwDesiredAccess & ~(GENERIC_READ|GENERIC_WRITE))
1009 {
1010 SetLastError(ERROR_INVALID_PARAMETER);
1011 return(INVALID_HANDLE_VALUE);
1012 }
1013
1014 if (dwShareMode & ~(FILE_SHARE_READ|FILE_SHARE_WRITE))
1015 {
1016 SetLastError(ERROR_INVALID_PARAMETER);
1017 return(INVALID_HANDLE_VALUE);
1018 }
1019
1020 /* Structures for GET_INPUT_HANDLE and GET_OUTPUT_HANDLE requests are identical */
1021 Request.Data.GetInputHandleRequest.Access = dwDesiredAccess;
1022 Request.Data.GetInputHandleRequest.Inheritable = bInheritHandle;
1023
1024 Status = CsrClientCallServer(&Request,
1025 NULL,
1026 CsrRequest,
1027 sizeof(CSR_API_MESSAGE));
1028 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1029 {
1030 SetLastErrorByStatus(Status);
1031 return INVALID_HANDLE_VALUE;
1032 }
1033
1034 return Request.Data.GetInputHandleRequest.InputHandle;
1035 }
1036
1037
1038 /*
1039 * @unimplemented (Undocumented)
1040 */
1041 BOOL
1042 WINAPI
1043 SetConsoleCommandHistoryMode(DWORD dwMode)
1044 {
1045 DPRINT1("SetConsoleCommandHistoryMode(0x%x) UNIMPLEMENTED!\n", dwMode);
1046 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1047 return FALSE;
1048 }
1049
1050
1051 /*
1052 * @unimplemented (Undocumented)
1053 */
1054 BOOL
1055 WINAPI
1056 SetConsoleCursor(DWORD Unknown0,
1057 DWORD Unknown1)
1058 {
1059 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1060 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1061 return FALSE;
1062 }
1063
1064
1065 /*
1066 * @unimplemented
1067 */
1068 BOOL
1069 WINAPI
1070 SetConsoleDisplayMode(HANDLE hOut,
1071 DWORD dwNewMode,
1072 PCOORD lpdwOldMode)
1073 /*
1074 * FUNCTION: Set the console display mode.
1075 * ARGUMENTS:
1076 * hOut - Standard output handle.
1077 * dwNewMode - New mode.
1078 * lpdwOldMode - Address of a variable that receives the old mode.
1079 */
1080 {
1081 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
1082 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1083 return FALSE;
1084 }
1085
1086
1087 /*
1088 * @unimplemented (Undocumented)
1089 */
1090 BOOL
1091 WINAPI
1092 SetConsoleFont(DWORD Unknown0,
1093 DWORD Unknown1)
1094 {
1095 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1096 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1097 return FALSE;
1098 }
1099
1100
1101 /*
1102 * @implemented (Undocumented)
1103 */
1104 BOOL
1105 WINAPI
1106 SetConsoleHardwareState(HANDLE hConsole,
1107 DWORD Flags,
1108 DWORD State)
1109 {
1110 CSR_API_MESSAGE Request;
1111 ULONG CsrRequest;
1112 NTSTATUS Status;
1113
1114 CsrRequest = MAKE_CSR_API(SETGET_CONSOLE_HW_STATE, CSR_CONSOLE);
1115 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
1116 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
1117 Request.Data.ConsoleHardwareStateRequest.State = State;
1118
1119 Status = CsrClientCallServer(&Request,
1120 NULL,
1121 CsrRequest,
1122 sizeof(CSR_API_MESSAGE));
1123 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1124 {
1125 SetLastErrorByStatus(Status);
1126 return FALSE;
1127 }
1128
1129 return TRUE;
1130 }
1131
1132
1133 /*
1134 * @unimplemented (Undocumented)
1135 */
1136 BOOL
1137 WINAPI
1138 SetConsoleKeyShortcuts(DWORD Unknown0,
1139 DWORD Unknown1,
1140 DWORD Unknown2,
1141 DWORD Unknown3)
1142 {
1143 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1144 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1145 return FALSE;
1146 }
1147
1148
1149 /*
1150 * @unimplemented (Undocumented)
1151 */
1152 BOOL
1153 WINAPI
1154 SetConsoleMaximumWindowSize(DWORD Unknown0,
1155 DWORD Unknown1)
1156 {
1157 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1158 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1159 return FALSE;
1160 }
1161
1162
1163 /*
1164 * @unimplemented (Undocumented)
1165 */
1166 BOOL
1167 WINAPI
1168 SetConsoleMenuClose(DWORD Unknown0)
1169 {
1170 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
1171 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1172 return FALSE;
1173 }
1174
1175
1176 /*
1177 * @unimplemented (Undocumented)
1178 */
1179 BOOL
1180 WINAPI
1181 SetConsoleNumberOfCommandsA(DWORD Unknown0,
1182 DWORD Unknown1)
1183 {
1184 DPRINT1("SetConsoleNumberOfCommandsA(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1185 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1186 return FALSE;
1187 }
1188
1189
1190 /*
1191 * @unimplemented (Undocumented)
1192 */
1193 BOOL
1194 WINAPI
1195 SetConsoleNumberOfCommandsW(DWORD Unknown0,
1196 DWORD Unknown1)
1197 {
1198 DPRINT1("SetConsoleNumberOfCommandsW(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1199 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1200 return FALSE;
1201 }
1202
1203
1204 /*
1205 * @unimplemented (Undocumented)
1206 */
1207 BOOL
1208 WINAPI
1209 SetConsolePalette(DWORD Unknown0,
1210 DWORD Unknown1,
1211 DWORD Unknown2)
1212 {
1213 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
1214 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1215 return FALSE;
1216 }
1217
1218
1219 /*
1220 * @unimplemented (Undocumented)
1221 */
1222 BOOL
1223 WINAPI
1224 SetLastConsoleEventActive(VOID)
1225 {
1226 DPRINT1("SetLastConsoleEventActive() UNIMPLEMENTED!\n");
1227 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1228 return FALSE;
1229 }
1230
1231
1232 /*
1233 * @unimplemented (Undocumented)
1234 */
1235 DWORD
1236 WINAPI
1237 ShowConsoleCursor(DWORD Unknown0,
1238 DWORD Unknown1)
1239 {
1240 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
1241 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1242 return 0;
1243 }
1244
1245
1246 /*
1247 * FUNCTION: Checks whether the given handle is a valid console handle.
1248 * ARGUMENTS:
1249 * Handle - Handle to be checked
1250 * RETURNS:
1251 * TRUE: Handle is a valid console handle
1252 * FALSE: Handle is not a valid console handle.
1253 * STATUS: Officially undocumented
1254 *
1255 * @implemented
1256 */
1257 BOOL
1258 WINAPI
1259 VerifyConsoleIoHandle(HANDLE Handle)
1260 {
1261 CSR_API_MESSAGE Request;
1262 ULONG CsrRequest;
1263 NTSTATUS Status;
1264
1265 CsrRequest = MAKE_CSR_API(VERIFY_HANDLE, CSR_NATIVE);
1266 Request.Data.VerifyHandleRequest.Handle = Handle;
1267
1268 Status = CsrClientCallServer(&Request,
1269 NULL,
1270 CsrRequest,
1271 sizeof(CSR_API_MESSAGE));
1272 if (!NT_SUCCESS(Status))
1273 {
1274 SetLastErrorByStatus(Status);
1275 return FALSE;
1276 }
1277
1278 return (BOOL)NT_SUCCESS(Request.Status);
1279 }
1280
1281
1282 /*
1283 * @unimplemented
1284 */
1285 DWORD
1286 WINAPI
1287 WriteConsoleInputVDMA(DWORD Unknown0,
1288 DWORD Unknown1,
1289 DWORD Unknown2,
1290 DWORD Unknown3)
1291 {
1292 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1293 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1294 return 0;
1295 }
1296
1297
1298 /*
1299 * @unimplemented
1300 */
1301 DWORD
1302 WINAPI
1303 WriteConsoleInputVDMW(DWORD Unknown0,
1304 DWORD Unknown1,
1305 DWORD Unknown2,
1306 DWORD Unknown3)
1307 {
1308 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
1309 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1310 return 0;
1311 }
1312
1313
1314 /*
1315 * @implemented (Undocumented)
1316 */
1317 BOOL
1318 WINAPI
1319 CloseConsoleHandle(HANDLE Handle)
1320 {
1321 CSR_API_MESSAGE Request;
1322 ULONG CsrRequest;
1323 NTSTATUS Status;
1324
1325 CsrRequest = MAKE_CSR_API(CLOSE_HANDLE, CSR_NATIVE);
1326 Request.Data.CloseHandleRequest.Handle = Handle;
1327
1328 Status = CsrClientCallServer(&Request,
1329 NULL,
1330 CsrRequest,
1331 sizeof(CSR_API_MESSAGE));
1332 if (!NT_SUCCESS(Status))
1333 {
1334 SetLastErrorByStatus(Status);
1335 return FALSE;
1336 }
1337
1338 return TRUE;
1339 }
1340
1341 /*
1342 * @implemented
1343 */
1344 HANDLE
1345 WINAPI
1346 GetStdHandle(DWORD nStdHandle)
1347 /*
1348 * FUNCTION: Get a handle for the standard input, standard output
1349 * and a standard error device.
1350 * ARGUMENTS:
1351 * nStdHandle - Specifies the device for which to return the handle.
1352 * RETURNS: If the function succeeds, the return value is the handle
1353 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
1354 */
1355 {
1356 PRTL_USER_PROCESS_PARAMETERS Ppb;
1357
1358 Ppb = NtCurrentPeb()->ProcessParameters;
1359 switch (nStdHandle)
1360 {
1361 case STD_INPUT_HANDLE:
1362 return Ppb->StandardInput;
1363
1364 case STD_OUTPUT_HANDLE:
1365 return Ppb->StandardOutput;
1366
1367 case STD_ERROR_HANDLE:
1368 return Ppb->StandardError;
1369 }
1370
1371 SetLastError (ERROR_INVALID_PARAMETER);
1372 return INVALID_HANDLE_VALUE;
1373 }
1374
1375
1376 /*
1377 * @implemented
1378 */
1379 BOOL
1380 WINAPI
1381 SetStdHandle(DWORD nStdHandle,
1382 HANDLE hHandle)
1383 /*
1384 * FUNCTION: Set the handle for the standard input, standard output or
1385 * the standard error device.
1386 * ARGUMENTS:
1387 * nStdHandle - Specifies the handle to be set.
1388 * hHandle - The handle to set.
1389 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1390 */
1391 {
1392 PRTL_USER_PROCESS_PARAMETERS Ppb;
1393
1394 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1395
1396 Ppb = NtCurrentPeb()->ProcessParameters;
1397
1398 switch (nStdHandle)
1399 {
1400 case STD_INPUT_HANDLE:
1401 Ppb->StandardInput = hHandle;
1402 return TRUE;
1403
1404 case STD_OUTPUT_HANDLE:
1405 Ppb->StandardOutput = hHandle;
1406 return TRUE;
1407
1408 case STD_ERROR_HANDLE:
1409 Ppb->StandardError = hHandle;
1410 return TRUE;
1411 }
1412
1413 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1414 SetLastError(ERROR_INVALID_HANDLE);
1415 return FALSE;
1416 }
1417
1418
1419 static
1420 BOOL
1421 IntWriteConsole(HANDLE hConsoleOutput,
1422 PVOID lpBuffer,
1423 DWORD nNumberOfCharsToWrite,
1424 LPDWORD lpNumberOfCharsWritten,
1425 LPVOID lpReserved,
1426 BOOL bUnicode)
1427 {
1428 PCSR_API_MESSAGE Request;
1429 ULONG CsrRequest;
1430 NTSTATUS Status;
1431 USHORT nChars;
1432 ULONG SizeBytes, CharSize;
1433 DWORD Written = 0;
1434
1435 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1436 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1437 0,
1438 max(sizeof(CSR_API_MESSAGE),
1439 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + min(nNumberOfCharsToWrite,
1440 CSRSS_MAX_WRITE_CONSOLE / CharSize) * CharSize));
1441 if (Request == NULL)
1442 {
1443 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1444 return FALSE;
1445 }
1446
1447 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE, CSR_CONSOLE);
1448
1449 while (nNumberOfCharsToWrite > 0)
1450 {
1451 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1452 Request->Data.WriteConsoleRequest.Unicode = bUnicode;
1453
1454 nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
1455 Request->Data.WriteConsoleRequest.NrCharactersToWrite = nChars;
1456
1457 SizeBytes = nChars * CharSize;
1458
1459 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, SizeBytes);
1460
1461 Status = CsrClientCallServer(Request,
1462 NULL,
1463 CsrRequest,
1464 max(sizeof(CSR_API_MESSAGE),
1465 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE) + SizeBytes));
1466
1467 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1468 {
1469 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1470 SetLastErrorByStatus(Status);
1471 return FALSE;
1472 }
1473
1474 nNumberOfCharsToWrite -= nChars;
1475 lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
1476 Written += Request->Data.WriteConsoleRequest.NrCharactersWritten;
1477 }
1478
1479 if (lpNumberOfCharsWritten != NULL)
1480 {
1481 *lpNumberOfCharsWritten = Written;
1482 }
1483 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1484
1485 return TRUE;
1486 }
1487
1488
1489 /*--------------------------------------------------------------
1490 * WriteConsoleA
1491 *
1492 * @implemented
1493 */
1494 BOOL
1495 WINAPI
1496 WriteConsoleA(HANDLE hConsoleOutput,
1497 CONST VOID *lpBuffer,
1498 DWORD nNumberOfCharsToWrite,
1499 LPDWORD lpNumberOfCharsWritten,
1500 LPVOID lpReserved)
1501 {
1502 return IntWriteConsole(hConsoleOutput,
1503 (PVOID)lpBuffer,
1504 nNumberOfCharsToWrite,
1505 lpNumberOfCharsWritten,
1506 lpReserved,
1507 FALSE);
1508 }
1509
1510
1511 /*--------------------------------------------------------------
1512 * WriteConsoleW
1513 *
1514 * @implemented
1515 */
1516 BOOL
1517 WINAPI
1518 WriteConsoleW(HANDLE hConsoleOutput,
1519 CONST VOID *lpBuffer,
1520 DWORD nNumberOfCharsToWrite,
1521 LPDWORD lpNumberOfCharsWritten,
1522 LPVOID lpReserved)
1523 {
1524 return IntWriteConsole(hConsoleOutput,
1525 (PVOID)lpBuffer,
1526 nNumberOfCharsToWrite,
1527 lpNumberOfCharsWritten,
1528 lpReserved,
1529 TRUE);
1530 }
1531
1532
1533 static
1534 BOOL
1535 IntReadConsole(HANDLE hConsoleInput,
1536 PVOID lpBuffer,
1537 DWORD nNumberOfCharsToRead,
1538 LPDWORD lpNumberOfCharsRead,
1539 PCONSOLE_READCONSOLE_CONTROL lpReserved,
1540 BOOL bUnicode)
1541 {
1542 PCSR_API_MESSAGE Request;
1543 ULONG CsrRequest;
1544 NTSTATUS Status;
1545 ULONG CharSize, CharsRead = 0;
1546
1547 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1548 Request = RtlAllocateHeap(RtlGetProcessHeap(),
1549 0,
1550 max(sizeof(CSR_API_MESSAGE),
1551 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE) + min(nNumberOfCharsToRead,
1552 CSRSS_MAX_READ_CONSOLE / CharSize) * CharSize));
1553 if (Request == NULL)
1554 {
1555 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1556 return FALSE;
1557 }
1558
1559 Request->Status = STATUS_SUCCESS;
1560 CsrRequest = MAKE_CSR_API(READ_CONSOLE, CSR_CONSOLE);
1561
1562 do
1563 {
1564 if (Request->Status == STATUS_PENDING)
1565 {
1566 Status = NtWaitForSingleObject(Request->Data.ReadConsoleRequest.EventHandle,
1567 FALSE,
1568 0);
1569 if (!NT_SUCCESS(Status))
1570 {
1571 DPRINT1("Wait for console input failed!\n");
1572 break;
1573 }
1574 }
1575
1576 Request->Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1577 Request->Data.ReadConsoleRequest.Unicode = bUnicode;
1578 Request->Data.ReadConsoleRequest.NrCharactersToRead = (WORD)min(nNumberOfCharsToRead, CSRSS_MAX_READ_CONSOLE / CharSize);
1579 Request->Data.ReadConsoleRequest.nCharsCanBeDeleted = (WORD)CharsRead;
1580
1581 Status = CsrClientCallServer(Request,
1582 NULL,
1583 CsrRequest,
1584 max(sizeof(CSR_API_MESSAGE),
1585 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE)
1586 + Request->Data.ReadConsoleRequest.NrCharactersToRead * CharSize));
1587
1588 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
1589 {
1590 DPRINT1("CSR returned error in ReadConsole\n");
1591 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1592 SetLastErrorByStatus(Status);
1593 return FALSE;
1594 }
1595
1596 nNumberOfCharsToRead -= Request->Data.ReadConsoleRequest.NrCharactersRead;
1597 memcpy((PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)(CharsRead * CharSize)),
1598 Request->Data.ReadConsoleRequest.Buffer,
1599 Request->Data.ReadConsoleRequest.NrCharactersRead * CharSize);
1600 CharsRead += Request->Data.ReadConsoleRequest.NrCharactersRead;
1601
1602 if (Request->Status == STATUS_NOTIFY_CLEANUP)
1603 {
1604 if(CharsRead > 0)
1605 {
1606 CharsRead--;
1607 nNumberOfCharsToRead++;
1608 }
1609 Request->Status = STATUS_PENDING;
1610 }
1611 }
1612 while (Request->Status == STATUS_PENDING && nNumberOfCharsToRead > 0);
1613
1614 if (lpNumberOfCharsRead != NULL)
1615 {
1616 *lpNumberOfCharsRead = CharsRead;
1617 }
1618
1619 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
1620
1621 return TRUE;
1622 }
1623
1624
1625 /*--------------------------------------------------------------
1626 * ReadConsoleA
1627 *
1628 * @implemented
1629 */
1630 BOOL
1631 WINAPI
1632 ReadConsoleA(HANDLE hConsoleInput,
1633 LPVOID lpBuffer,
1634 DWORD nNumberOfCharsToRead,
1635 LPDWORD lpNumberOfCharsRead,
1636 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1637 {
1638 return IntReadConsole(hConsoleInput,
1639 lpBuffer,
1640 nNumberOfCharsToRead,
1641 lpNumberOfCharsRead,
1642 pInputControl,
1643 FALSE);
1644 }
1645
1646
1647 /*--------------------------------------------------------------
1648 * ReadConsoleW
1649 *
1650 * @implemented
1651 */
1652 BOOL
1653 WINAPI
1654 ReadConsoleW(HANDLE hConsoleInput,
1655 LPVOID lpBuffer,
1656 DWORD nNumberOfCharsToRead,
1657 LPDWORD lpNumberOfCharsRead,
1658 PCONSOLE_READCONSOLE_CONTROL pInputControl)
1659 {
1660 return IntReadConsole(hConsoleInput,
1661 lpBuffer,
1662 nNumberOfCharsToRead,
1663 lpNumberOfCharsRead,
1664 pInputControl,
1665 TRUE);
1666 }
1667
1668
1669 /*--------------------------------------------------------------
1670 * AllocConsole
1671 *
1672 * @implemented
1673 */
1674 BOOL
1675 WINAPI
1676 AllocConsole(VOID)
1677 {
1678 CSR_API_MESSAGE Request;
1679 ULONG CsrRequest;
1680 NTSTATUS Status;
1681 HANDLE hStdError;
1682
1683 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1684 {
1685 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1686 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1687 return FALSE;
1688 }
1689
1690 Request.Data.AllocConsoleRequest.CtrlDispatcher = ConsoleControlDispatcher;
1691 Request.Data.AllocConsoleRequest.ConsoleNeeded = TRUE;
1692
1693 CsrRequest = MAKE_CSR_API(ALLOC_CONSOLE, CSR_CONSOLE);
1694
1695 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1696 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1697 {
1698 SetLastErrorByStatus(Status);
1699 return FALSE;
1700 }
1701
1702 NtCurrentPeb()->ProcessParameters->ConsoleHandle = Request.Data.AllocConsoleRequest.Console;
1703
1704 SetStdHandle(STD_INPUT_HANDLE, Request.Data.AllocConsoleRequest.InputHandle);
1705 SetStdHandle(STD_OUTPUT_HANDLE, Request.Data.AllocConsoleRequest.OutputHandle);
1706
1707 hStdError = DuplicateConsoleHandle(Request.Data.AllocConsoleRequest.OutputHandle,
1708 0,
1709 TRUE,
1710 DUPLICATE_SAME_ACCESS);
1711
1712 SetStdHandle(STD_ERROR_HANDLE, hStdError);
1713 return TRUE;
1714 }
1715
1716
1717 /*--------------------------------------------------------------
1718 * FreeConsole
1719 *
1720 * @implemented
1721 */
1722 BOOL
1723 WINAPI
1724 FreeConsole(VOID)
1725 {
1726 // AG: I'm not sure if this is correct (what happens to std handles?)
1727 // but I just tried to reverse what AllocConsole() does...
1728
1729 CSR_API_MESSAGE Request;
1730 ULONG CsrRequest;
1731 NTSTATUS Status;
1732
1733 CsrRequest = MAKE_CSR_API(FREE_CONSOLE, CSR_CONSOLE);
1734
1735 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1736 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1737 {
1738 SetLastErrorByStatus(Status);
1739 return FALSE;
1740 }
1741
1742 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1743 return TRUE;
1744 }
1745
1746
1747 /*--------------------------------------------------------------
1748 * GetConsoleScreenBufferInfo
1749 *
1750 * @implemented
1751 */
1752 BOOL
1753 WINAPI
1754 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1755 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1756 {
1757 CSR_API_MESSAGE Request;
1758 ULONG CsrRequest;
1759 NTSTATUS Status;
1760
1761 CsrRequest = MAKE_CSR_API(SCREEN_BUFFER_INFO, CSR_CONSOLE);
1762 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1763
1764 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1765 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1766 {
1767 SetLastErrorByStatus(Status);
1768 return FALSE;
1769 }
1770 *lpConsoleScreenBufferInfo = Request.Data.ScreenBufferInfoRequest.Info;
1771 return TRUE;
1772 }
1773
1774
1775 /*--------------------------------------------------------------
1776 * SetConsoleCursorPosition
1777 *
1778 * @implemented
1779 */
1780 BOOL
1781 WINAPI
1782 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1783 COORD dwCursorPosition)
1784 {
1785 CSR_API_MESSAGE Request;
1786 ULONG CsrRequest;
1787 NTSTATUS Status;
1788
1789 CsrRequest = MAKE_CSR_API(SET_CURSOR, CSR_CONSOLE);
1790 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1791 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1792
1793 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
1794 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1795 {
1796 SetLastErrorByStatus(Status);
1797 return FALSE;
1798 }
1799
1800 return TRUE;
1801 }
1802
1803
1804 static
1805 BOOL
1806 IntFillConsoleOutputCharacter(HANDLE hConsoleOutput,
1807 PVOID cCharacter,
1808 DWORD nLength,
1809 COORD dwWriteCoord,
1810 LPDWORD lpNumberOfCharsWritten,
1811 BOOL bUnicode)
1812 {
1813 CSR_API_MESSAGE Request;
1814 ULONG CsrRequest;
1815 NTSTATUS Status;
1816
1817 CsrRequest = MAKE_CSR_API(FILL_OUTPUT, CSR_CONSOLE);
1818 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1819 Request.Data.FillOutputRequest.Unicode = bUnicode;
1820
1821 if(bUnicode)
1822 Request.Data.FillOutputRequest.Char.UnicodeChar = *((WCHAR*)cCharacter);
1823 else
1824 Request.Data.FillOutputRequest.Char.AsciiChar = *((CHAR*)cCharacter);
1825
1826 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1827 Request.Data.FillOutputRequest.Length = (WORD)nLength;
1828
1829 Status = CsrClientCallServer(&Request,
1830 NULL,
1831 CsrRequest,
1832 sizeof(CSR_API_MESSAGE));
1833
1834 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
1835 {
1836 SetLastErrorByStatus(Status);
1837 return FALSE;
1838 }
1839
1840 if(lpNumberOfCharsWritten != NULL)
1841 {
1842 *lpNumberOfCharsWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
1843 }
1844
1845 return TRUE;
1846 }
1847
1848 /*--------------------------------------------------------------
1849 * FillConsoleOutputCharacterA
1850 *
1851 * @implemented
1852 */
1853 BOOL
1854 WINAPI
1855 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
1856 CHAR cCharacter,
1857 DWORD nLength,
1858 COORD dwWriteCoord,
1859 LPDWORD lpNumberOfCharsWritten)
1860 {
1861 return IntFillConsoleOutputCharacter(hConsoleOutput,
1862 &cCharacter,
1863 nLength,
1864 dwWriteCoord,
1865 lpNumberOfCharsWritten,
1866 FALSE);
1867 }
1868
1869
1870 /*--------------------------------------------------------------
1871 * FillConsoleOutputCharacterW
1872 *
1873 * @implemented
1874 */
1875 BOOL
1876 WINAPI
1877 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
1878 WCHAR cCharacter,
1879 DWORD nLength,
1880 COORD dwWriteCoord,
1881 LPDWORD lpNumberOfCharsWritten)
1882 {
1883 return IntFillConsoleOutputCharacter(hConsoleOutput,
1884 &cCharacter,
1885 nLength,
1886 dwWriteCoord,
1887 lpNumberOfCharsWritten,
1888 TRUE);
1889 }
1890
1891
1892 static
1893 BOOL
1894 IntPeekConsoleInput(HANDLE hConsoleInput,
1895 PINPUT_RECORD lpBuffer,
1896 DWORD nLength,
1897 LPDWORD lpNumberOfEventsRead,
1898 BOOL bUnicode)
1899 {
1900 CSR_API_MESSAGE Request;
1901 ULONG CsrRequest;
1902 PCSR_CAPTURE_BUFFER CaptureBuffer;
1903 NTSTATUS Status;
1904 ULONG Size;
1905
1906 if (lpBuffer == NULL)
1907 {
1908 SetLastError(ERROR_INVALID_PARAMETER);
1909 return FALSE;
1910 }
1911
1912 Size = nLength * sizeof(INPUT_RECORD);
1913
1914 /* Allocate a Capture Buffer */
1915 DPRINT("IntPeekConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
1916 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
1917
1918 /* Allocate space in the Buffer */
1919 CsrCaptureMessageBuffer(CaptureBuffer,
1920 NULL,
1921 Size,
1922 (PVOID*)&Request.Data.PeekConsoleInputRequest.InputRecord);
1923
1924 /* Set up the data to send to the Console Server */
1925 CsrRequest = MAKE_CSR_API(PEEK_CONSOLE_INPUT, CSR_CONSOLE);
1926 Request.Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1927 Request.Data.PeekConsoleInputRequest.Unicode = bUnicode;
1928 Request.Data.PeekConsoleInputRequest.Length = nLength;
1929
1930 /* Call the server */
1931 Status = CsrClientCallServer(&Request,
1932 CaptureBuffer,
1933 CsrRequest,
1934 sizeof(CSR_API_MESSAGE));
1935 DPRINT("Server returned: %x\n", Request.Status);
1936
1937 /* Check for success*/
1938 if (NT_SUCCESS(Request.Status))
1939 {
1940 /* Return the number of events read */
1941 DPRINT("Events read: %lx\n", Request.Data.PeekConsoleInputRequest.Length);
1942 *lpNumberOfEventsRead = Request.Data.PeekConsoleInputRequest.Length;
1943
1944 /* Copy into the buffer */
1945 DPRINT("Copying to buffer\n");
1946 RtlCopyMemory(lpBuffer,
1947 Request.Data.PeekConsoleInputRequest.InputRecord,
1948 sizeof(INPUT_RECORD) * *lpNumberOfEventsRead);
1949 }
1950 else
1951 {
1952 /* Error out */
1953 *lpNumberOfEventsRead = 0;
1954 SetLastErrorByStatus(Request.Status);
1955 }
1956
1957 /* Release the capture buffer */
1958 CsrFreeCaptureBuffer(CaptureBuffer);
1959
1960 /* Return TRUE or FALSE */
1961 return NT_SUCCESS(Request.Status);
1962 }
1963
1964 /*--------------------------------------------------------------
1965 * PeekConsoleInputA
1966 *
1967 * @implemented
1968 */
1969 BOOL
1970 WINAPI
1971 PeekConsoleInputA(HANDLE hConsoleInput,
1972 PINPUT_RECORD lpBuffer,
1973 DWORD nLength,
1974 LPDWORD lpNumberOfEventsRead)
1975 {
1976 return IntPeekConsoleInput(hConsoleInput,
1977 lpBuffer,
1978 nLength,
1979 lpNumberOfEventsRead,
1980 FALSE);
1981 }
1982
1983
1984 /*--------------------------------------------------------------
1985 * PeekConsoleInputW
1986 *
1987 * @implemented
1988 */
1989 BOOL
1990 WINAPI
1991 PeekConsoleInputW(HANDLE hConsoleInput,
1992 PINPUT_RECORD lpBuffer,
1993 DWORD nLength,
1994 LPDWORD lpNumberOfEventsRead)
1995 {
1996 return IntPeekConsoleInput(hConsoleInput,
1997 lpBuffer, nLength,
1998 lpNumberOfEventsRead,
1999 TRUE);
2000 }
2001
2002
2003 static
2004 BOOL
2005 IntReadConsoleInput(HANDLE hConsoleInput,
2006 PINPUT_RECORD lpBuffer,
2007 DWORD nLength,
2008 LPDWORD lpNumberOfEventsRead,
2009 BOOL bUnicode)
2010 {
2011 CSR_API_MESSAGE Request;
2012 ULONG CsrRequest;
2013 ULONG Read;
2014 NTSTATUS Status;
2015
2016 CsrRequest = MAKE_CSR_API(READ_INPUT, CSR_CONSOLE);
2017 Read = 0;
2018
2019 while (nLength > 0)
2020 {
2021 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
2022 Request.Data.ReadInputRequest.Unicode = bUnicode;
2023
2024 Status = CsrClientCallServer(&Request,
2025 NULL,
2026 CsrRequest,
2027 sizeof(CSR_API_MESSAGE));
2028 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2029 {
2030 if (Read == 0)
2031 {
2032 /* we couldn't read a single record, fail */
2033 SetLastErrorByStatus(Status);
2034 return FALSE;
2035 }
2036 else
2037 {
2038 /* FIXME - fail gracefully in case we already read at least one record? */
2039 break;
2040 }
2041 }
2042 else if (Status == STATUS_PENDING)
2043 {
2044 if (Read == 0)
2045 {
2046 Status = NtWaitForSingleObject(Request.Data.ReadInputRequest.Event, FALSE, 0);
2047 if (!NT_SUCCESS(Status))
2048 {
2049 SetLastErrorByStatus(Status);
2050 break;
2051 }
2052 }
2053 else
2054 {
2055 /* nothing more to read (waiting for more input??), let's just bail */
2056 break;
2057 }
2058 }
2059 else
2060 {
2061 lpBuffer[Read++] = Request.Data.ReadInputRequest.Input;
2062 nLength--;
2063
2064 if (!Request.Data.ReadInputRequest.MoreEvents)
2065 {
2066 /* nothing more to read, bail */
2067 break;
2068 }
2069 }
2070 }
2071
2072 if (lpNumberOfEventsRead != NULL)
2073 {
2074 *lpNumberOfEventsRead = Read;
2075 }
2076
2077 return (Read > 0);
2078 }
2079
2080
2081 /*--------------------------------------------------------------
2082 * ReadConsoleInputA
2083 *
2084 * @implemented
2085 */
2086 BOOL
2087 WINAPI
2088 ReadConsoleInputA(HANDLE hConsoleInput,
2089 PINPUT_RECORD lpBuffer,
2090 DWORD nLength,
2091 LPDWORD lpNumberOfEventsRead)
2092 {
2093 return IntReadConsoleInput(hConsoleInput,
2094 lpBuffer,
2095 nLength,
2096 lpNumberOfEventsRead,
2097 FALSE);
2098 }
2099
2100
2101 /*--------------------------------------------------------------
2102 * ReadConsoleInputW
2103 *
2104 * @implemented
2105 */
2106 BOOL
2107 WINAPI
2108 ReadConsoleInputW(HANDLE hConsoleInput,
2109 PINPUT_RECORD lpBuffer,
2110 DWORD nLength,
2111 LPDWORD lpNumberOfEventsRead)
2112 {
2113 return IntReadConsoleInput(hConsoleInput,
2114 lpBuffer,
2115 nLength,
2116 lpNumberOfEventsRead,
2117 TRUE);
2118 }
2119
2120
2121 static
2122 BOOL
2123 IntWriteConsoleInput(HANDLE hConsoleInput,
2124 PINPUT_RECORD lpBuffer,
2125 DWORD nLength,
2126 LPDWORD lpNumberOfEventsWritten,
2127 BOOL bUnicode)
2128 {
2129 CSR_API_MESSAGE Request;
2130 ULONG CsrRequest;
2131 PCSR_CAPTURE_BUFFER CaptureBuffer;
2132 NTSTATUS Status;
2133 DWORD Size;
2134
2135 if (lpBuffer == NULL)
2136 {
2137 SetLastError(ERROR_INVALID_PARAMETER);
2138 return FALSE;
2139 }
2140
2141 Size = nLength * sizeof(INPUT_RECORD);
2142
2143 /* Allocate a Capture Buffer */
2144 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
2145 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2146
2147 /* Allocate space in the Buffer */
2148 CsrCaptureMessageBuffer(CaptureBuffer,
2149 lpBuffer,
2150 Size,
2151 (PVOID*)&Request.Data.WriteConsoleInputRequest.InputRecord);
2152
2153 /* Set up the data to send to the Console Server */
2154 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_INPUT, CSR_CONSOLE);
2155 Request.Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
2156 Request.Data.WriteConsoleInputRequest.Unicode = bUnicode;
2157 Request.Data.WriteConsoleInputRequest.Length = nLength;
2158
2159 /* Call the server */
2160 Status = CsrClientCallServer(&Request,
2161 CaptureBuffer,
2162 CsrRequest,
2163 sizeof(CSR_API_MESSAGE));
2164 DPRINT("Server returned: %x\n", Request.Status);
2165
2166 /* Check for success*/
2167 if (NT_SUCCESS(Request.Status))
2168 {
2169 /* Return the number of events read */
2170 DPRINT("Events read: %lx\n", Request.Data.WriteConsoleInputRequest.Length);
2171 *lpNumberOfEventsWritten = Request.Data.WriteConsoleInputRequest.Length;
2172 }
2173 else
2174 {
2175 /* Error out */
2176 *lpNumberOfEventsWritten = 0;
2177 SetLastErrorByStatus(Request.Status);
2178 }
2179
2180 /* Release the capture buffer */
2181 CsrFreeCaptureBuffer(CaptureBuffer);
2182
2183 /* Return TRUE or FALSE */
2184 return NT_SUCCESS(Request.Status);
2185 }
2186
2187
2188 /*--------------------------------------------------------------
2189 * WriteConsoleInputA
2190 *
2191 * @implemented
2192 */
2193 BOOL
2194 WINAPI
2195 WriteConsoleInputA(HANDLE hConsoleInput,
2196 CONST INPUT_RECORD *lpBuffer,
2197 DWORD nLength,
2198 LPDWORD lpNumberOfEventsWritten)
2199 {
2200 return IntWriteConsoleInput(hConsoleInput,
2201 (PINPUT_RECORD)lpBuffer,
2202 nLength,
2203 lpNumberOfEventsWritten,
2204 FALSE);
2205 }
2206
2207
2208 /*--------------------------------------------------------------
2209 * WriteConsoleInputW
2210 *
2211 * @implemented
2212 */
2213 BOOL
2214 WINAPI
2215 WriteConsoleInputW(HANDLE hConsoleInput,
2216 CONST INPUT_RECORD *lpBuffer,
2217 DWORD nLength,
2218 LPDWORD lpNumberOfEventsWritten)
2219 {
2220 return IntWriteConsoleInput(hConsoleInput,
2221 (PINPUT_RECORD)lpBuffer,
2222 nLength,
2223 lpNumberOfEventsWritten,
2224 TRUE);
2225 }
2226
2227
2228 static
2229 BOOL
2230 IntReadConsoleOutput(HANDLE hConsoleOutput,
2231 PCHAR_INFO lpBuffer,
2232 COORD dwBufferSize,
2233 COORD dwBufferCoord,
2234 PSMALL_RECT lpReadRegion,
2235 BOOL bUnicode)
2236 {
2237 CSR_API_MESSAGE Request;
2238 ULONG CsrRequest;
2239 PCSR_CAPTURE_BUFFER CaptureBuffer;
2240 NTSTATUS Status;
2241 DWORD Size, SizeX, SizeY;
2242
2243 if (lpBuffer == NULL)
2244 {
2245 SetLastError(ERROR_INVALID_PARAMETER);
2246 return FALSE;
2247 }
2248
2249 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
2250
2251 /* Allocate a Capture Buffer */
2252 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
2253 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2254
2255 /* Allocate space in the Buffer */
2256 CsrCaptureMessageBuffer(CaptureBuffer,
2257 NULL,
2258 Size,
2259 (PVOID*)&Request.Data.ReadConsoleOutputRequest.CharInfo);
2260
2261 /* Set up the data to send to the Console Server */
2262 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT, CSR_CONSOLE);
2263 Request.Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2264 Request.Data.ReadConsoleOutputRequest.Unicode = bUnicode;
2265 Request.Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
2266 Request.Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
2267 Request.Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
2268
2269 /* Call the server */
2270 Status = CsrClientCallServer(&Request,
2271 CaptureBuffer,
2272 CsrRequest,
2273 sizeof(CSR_API_MESSAGE));
2274 DPRINT("Server returned: %x\n", Request.Status);
2275
2276 /* Check for success*/
2277 if (NT_SUCCESS(Request.Status))
2278 {
2279 /* Copy into the buffer */
2280 DPRINT("Copying to buffer\n");
2281 SizeX = Request.Data.ReadConsoleOutputRequest.ReadRegion.Right -
2282 Request.Data.ReadConsoleOutputRequest.ReadRegion.Left + 1;
2283 SizeY = Request.Data.ReadConsoleOutputRequest.ReadRegion.Bottom -
2284 Request.Data.ReadConsoleOutputRequest.ReadRegion.Top + 1;
2285 RtlCopyMemory(lpBuffer,
2286 Request.Data.ReadConsoleOutputRequest.CharInfo,
2287 sizeof(CHAR_INFO) * SizeX * SizeY);
2288 }
2289 else
2290 {
2291 /* Error out */
2292 SetLastErrorByStatus(Request.Status);
2293 }
2294
2295 /* Return the read region */
2296 DPRINT("read region: %lx\n", Request.Data.ReadConsoleOutputRequest.ReadRegion);
2297 *lpReadRegion = Request.Data.ReadConsoleOutputRequest.ReadRegion;
2298
2299 /* Release the capture buffer */
2300 CsrFreeCaptureBuffer(CaptureBuffer);
2301
2302 /* Return TRUE or FALSE */
2303 return NT_SUCCESS(Request.Status);
2304 }
2305
2306 /*--------------------------------------------------------------
2307 * ReadConsoleOutputA
2308 *
2309 * @implemented
2310 */
2311 BOOL
2312 WINAPI
2313 ReadConsoleOutputA(HANDLE hConsoleOutput,
2314 PCHAR_INFO lpBuffer,
2315 COORD dwBufferSize,
2316 COORD dwBufferCoord,
2317 PSMALL_RECT lpReadRegion)
2318 {
2319 return IntReadConsoleOutput(hConsoleOutput,
2320 lpBuffer,
2321 dwBufferSize,
2322 dwBufferCoord,
2323 lpReadRegion,
2324 FALSE);
2325 }
2326
2327
2328 /*--------------------------------------------------------------
2329 * ReadConsoleOutputW
2330 *
2331 * @implemented
2332 */
2333 BOOL
2334 WINAPI
2335 ReadConsoleOutputW(HANDLE hConsoleOutput,
2336 PCHAR_INFO lpBuffer,
2337 COORD dwBufferSize,
2338 COORD dwBufferCoord,
2339 PSMALL_RECT lpReadRegion)
2340 {
2341 return IntReadConsoleOutput(hConsoleOutput,
2342 lpBuffer,
2343 dwBufferSize,
2344 dwBufferCoord,
2345 lpReadRegion,
2346 TRUE);
2347 }
2348
2349
2350 static
2351 BOOL
2352 IntWriteConsoleOutput(HANDLE hConsoleOutput,
2353 CONST CHAR_INFO *lpBuffer,
2354 COORD dwBufferSize,
2355 COORD dwBufferCoord,
2356 PSMALL_RECT lpWriteRegion,
2357 BOOL bUnicode)
2358 {
2359 CSR_API_MESSAGE Request;
2360 ULONG CsrRequest;
2361 PCSR_CAPTURE_BUFFER CaptureBuffer;
2362 NTSTATUS Status;
2363 ULONG Size;
2364
2365 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
2366
2367 /* Allocate a Capture Buffer */
2368 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
2369 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
2370
2371 /* Allocate space in the Buffer */
2372 CsrCaptureMessageBuffer(CaptureBuffer,
2373 NULL,
2374 Size,
2375 (PVOID*)&Request.Data.WriteConsoleOutputRequest.CharInfo);
2376
2377 /* Copy from the buffer */
2378 RtlCopyMemory(Request.Data.WriteConsoleOutputRequest.CharInfo, lpBuffer, Size);
2379
2380 /* Set up the data to send to the Console Server */
2381 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT, CSR_CONSOLE);
2382 Request.Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
2383 Request.Data.WriteConsoleOutputRequest.Unicode = bUnicode;
2384 Request.Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
2385 Request.Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
2386 Request.Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
2387
2388 /* Call the server */
2389 Status = CsrClientCallServer(&Request,
2390 CaptureBuffer,
2391 CsrRequest,
2392 sizeof(CSR_API_MESSAGE));
2393 DPRINT("Server returned: %x\n", Request.Status);
2394
2395 /* Check for success*/
2396 if (!NT_SUCCESS(Request.Status))
2397 {
2398 /* Error out */
2399 SetLastErrorByStatus(Request.Status);
2400 }
2401
2402 /* Return the read region */
2403 DPRINT("read region: %lx\n", Request.Data.WriteConsoleOutputRequest.WriteRegion);
2404 *lpWriteRegion = Request.Data.WriteConsoleOutputRequest.WriteRegion;
2405
2406 /* Release the capture buffer */
2407 CsrFreeCaptureBuffer(CaptureBuffer);
2408
2409 /* Return TRUE or FALSE */
2410 return NT_SUCCESS(Request.Status);
2411 }
2412
2413 /*--------------------------------------------------------------
2414 * WriteConsoleOutputA
2415 *
2416 * @implemented
2417 */
2418 BOOL
2419 WINAPI
2420 WriteConsoleOutputA(HANDLE hConsoleOutput,
2421 CONST CHAR_INFO *lpBuffer,
2422 COORD dwBufferSize,
2423 COORD dwBufferCoord,
2424 PSMALL_RECT lpWriteRegion)
2425 {
2426 return IntWriteConsoleOutput(hConsoleOutput,
2427 lpBuffer,
2428 dwBufferSize,
2429 dwBufferCoord,
2430 lpWriteRegion,
2431 FALSE);
2432 }
2433
2434
2435 /*--------------------------------------------------------------
2436 * WriteConsoleOutputW
2437 *
2438 * @implemented
2439 */
2440 BOOL
2441 WINAPI
2442 WriteConsoleOutputW(HANDLE hConsoleOutput,
2443 CONST CHAR_INFO *lpBuffer,
2444 COORD dwBufferSize,
2445 COORD dwBufferCoord,
2446 PSMALL_RECT lpWriteRegion)
2447 {
2448 return IntWriteConsoleOutput(hConsoleOutput,
2449 lpBuffer,
2450 dwBufferSize,
2451 dwBufferCoord,
2452 lpWriteRegion,
2453 TRUE);
2454 }
2455
2456
2457 static
2458 BOOL
2459 IntReadConsoleOutputCharacter(HANDLE hConsoleOutput,
2460 PVOID lpCharacter,
2461 DWORD nLength,
2462 COORD dwReadCoord,
2463 LPDWORD lpNumberOfCharsRead,
2464 BOOL bUnicode)
2465 {
2466 PCSR_API_MESSAGE Request;
2467 ULONG CsrRequest;
2468 NTSTATUS Status;
2469 ULONG nChars, SizeBytes, CharSize;
2470 DWORD CharsRead = 0;
2471
2472 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2473
2474 nChars = min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR) / CharSize;
2475 SizeBytes = nChars * CharSize;
2476
2477 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2478 max(sizeof(CSR_API_MESSAGE),
2479 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR)
2480 + min (nChars, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2481 if (Request == NULL)
2482 {
2483 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2484 return FALSE;
2485 }
2486
2487 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2488 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
2489
2490 while (nLength > 0)
2491 {
2492 DWORD BytesRead;
2493
2494 Request->Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2495 Request->Data.ReadConsoleOutputCharRequest.Unicode = bUnicode;
2496 Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead = min(nLength, nChars);
2497 SizeBytes = Request->Data.ReadConsoleOutputCharRequest.NumCharsToRead * CharSize;
2498
2499 Status = CsrClientCallServer(Request,
2500 NULL,
2501 CsrRequest,
2502 max(sizeof(CSR_API_MESSAGE),
2503 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_CHAR) + SizeBytes));
2504 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2505 {
2506 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2507 SetLastErrorByStatus(Status);
2508 break;
2509 }
2510
2511 BytesRead = Request->Data.ReadConsoleOutputCharRequest.CharsRead * CharSize;
2512 memcpy(lpCharacter, Request->Data.ReadConsoleOutputCharRequest.String, BytesRead);
2513 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)BytesRead);
2514 CharsRead += Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2515 nLength -= Request->Data.ReadConsoleOutputCharRequest.CharsRead;
2516
2517 Request->Data.ReadConsoleOutputCharRequest.ReadCoord = Request->Data.ReadConsoleOutputCharRequest.EndCoord;
2518 }
2519
2520 if (lpNumberOfCharsRead != NULL)
2521 {
2522 *lpNumberOfCharsRead = CharsRead;
2523 }
2524
2525 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2526
2527 return TRUE;
2528 }
2529
2530
2531 /*--------------------------------------------------------------
2532 * ReadConsoleOutputCharacterA
2533 *
2534 * @implemented
2535 */
2536 BOOL
2537 WINAPI
2538 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
2539 LPSTR lpCharacter,
2540 DWORD nLength,
2541 COORD dwReadCoord,
2542 LPDWORD lpNumberOfCharsRead)
2543 {
2544 return IntReadConsoleOutputCharacter(hConsoleOutput,
2545 (PVOID)lpCharacter,
2546 nLength,
2547 dwReadCoord,
2548 lpNumberOfCharsRead,
2549 FALSE);
2550 }
2551
2552
2553 /*--------------------------------------------------------------
2554 * ReadConsoleOutputCharacterW
2555 *
2556 * @implemented
2557 */
2558 BOOL
2559 WINAPI
2560 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
2561 LPWSTR lpCharacter,
2562 DWORD nLength,
2563 COORD dwReadCoord,
2564 LPDWORD lpNumberOfCharsRead)
2565 {
2566 return IntReadConsoleOutputCharacter(hConsoleOutput,
2567 (PVOID)lpCharacter,
2568 nLength,
2569 dwReadCoord,
2570 lpNumberOfCharsRead,
2571 TRUE);
2572 }
2573
2574
2575 /*--------------------------------------------------------------
2576 * ReadConsoleOutputAttribute
2577 *
2578 * @implemented
2579 */
2580 BOOL
2581 WINAPI
2582 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
2583 LPWORD lpAttribute,
2584 DWORD nLength,
2585 COORD dwReadCoord,
2586 LPDWORD lpNumberOfAttrsRead)
2587 {
2588 PCSR_API_MESSAGE Request;
2589 ULONG CsrRequest;
2590 NTSTATUS Status;
2591 DWORD Size;
2592
2593 if (lpNumberOfAttrsRead != NULL)
2594 *lpNumberOfAttrsRead = nLength;
2595
2596 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2597 0,
2598 max(sizeof(CSR_API_MESSAGE),
2599 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB)
2600 + min (nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2601 if (Request == NULL)
2602 {
2603 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2604 return FALSE;
2605 }
2606
2607 CsrRequest = MAKE_CSR_API(READ_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2608
2609 while (nLength != 0)
2610 {
2611 Request->Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2612 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2613
2614 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD))
2615 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB / sizeof(WCHAR);
2616 else
2617 Size = nLength;
2618
2619 Request->Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2620
2621 Status = CsrClientCallServer(Request,
2622 NULL,
2623 CsrRequest,
2624 max(sizeof(CSR_API_MESSAGE),
2625 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_READ_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2626 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Request->Status))
2627 {
2628 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2629 SetLastErrorByStatus(Status);
2630 return FALSE;
2631 }
2632
2633 memcpy(lpAttribute, Request->Data.ReadConsoleOutputAttribRequest.Attribute, Size * sizeof(WORD));
2634 lpAttribute += Size;
2635 nLength -= Size;
2636 Request->Data.ReadConsoleOutputAttribRequest.ReadCoord = Request->Data.ReadConsoleOutputAttribRequest.EndCoord;
2637 }
2638
2639 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2640
2641 return TRUE;
2642 }
2643
2644
2645 static
2646 BOOL
2647 IntWriteConsoleOutputCharacter(HANDLE hConsoleOutput,
2648 PVOID lpCharacter,
2649 DWORD nLength,
2650 COORD dwWriteCoord,
2651 LPDWORD lpNumberOfCharsWritten,
2652 BOOL bUnicode)
2653 {
2654 PCSR_API_MESSAGE Request;
2655 ULONG CsrRequest;
2656 NTSTATUS Status;
2657 ULONG SizeBytes, CharSize, nChars;
2658 DWORD Written = 0;
2659
2660 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2661
2662 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize);
2663 SizeBytes = nChars * CharSize;
2664
2665 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
2666 max(sizeof(CSR_API_MESSAGE),
2667 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR)
2668 + min (nChars, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CharSize) * CharSize));
2669 if (Request == NULL)
2670 {
2671 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2672 return FALSE;
2673 }
2674
2675 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_CHAR, CSR_CONSOLE);
2676 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2677
2678 while (nLength > 0)
2679 {
2680 DWORD BytesWrite;
2681
2682 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2683 Request->Data.WriteConsoleOutputCharRequest.Unicode = bUnicode;
2684 Request->Data.WriteConsoleOutputCharRequest.Length = (WORD)min(nLength, nChars);
2685 BytesWrite = Request->Data.WriteConsoleOutputCharRequest.Length * CharSize;
2686
2687 memcpy(Request->Data.WriteConsoleOutputCharRequest.String, lpCharacter, BytesWrite);
2688
2689 Status = CsrClientCallServer(Request,
2690 NULL,
2691 CsrRequest,
2692 max(sizeof(CSR_API_MESSAGE),
2693 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_CHAR) + BytesWrite));
2694
2695 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2696 {
2697 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2698 SetLastErrorByStatus(Status);
2699 return FALSE;
2700 }
2701
2702 nLength -= Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2703 lpCharacter = (PVOID)((ULONG_PTR)lpCharacter + (ULONG_PTR)(Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten * CharSize));
2704 Written += Request->Data.WriteConsoleOutputCharRequest.NrCharactersWritten;
2705
2706 Request->Data.WriteConsoleOutputCharRequest.Coord = Request->Data.WriteConsoleOutputCharRequest.EndCoord;
2707 }
2708
2709 if (lpNumberOfCharsWritten != NULL)
2710 {
2711 *lpNumberOfCharsWritten = Written;
2712 }
2713
2714 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2715
2716 return TRUE;
2717 }
2718
2719
2720 /*--------------------------------------------------------------
2721 * WriteConsoleOutputCharacterA
2722 *
2723 * @implemented
2724 */
2725 BOOL
2726 WINAPI
2727 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2728 LPCSTR lpCharacter,
2729 DWORD nLength,
2730 COORD dwWriteCoord,
2731 LPDWORD lpNumberOfCharsWritten)
2732 {
2733 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2734 (PVOID)lpCharacter,
2735 nLength,
2736 dwWriteCoord,
2737 lpNumberOfCharsWritten,
2738 FALSE);
2739 }
2740
2741
2742 /*--------------------------------------------------------------
2743 * WriteConsoleOutputCharacterW
2744 *
2745 * @implemented
2746 */
2747 BOOL
2748 WINAPI
2749 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2750 LPCWSTR lpCharacter,
2751 DWORD nLength,
2752 COORD dwWriteCoord,
2753 LPDWORD lpNumberOfCharsWritten)
2754 {
2755 return IntWriteConsoleOutputCharacter(hConsoleOutput,
2756 (PVOID)lpCharacter,
2757 nLength,
2758 dwWriteCoord,
2759 lpNumberOfCharsWritten,
2760 TRUE);
2761 }
2762
2763
2764 /*--------------------------------------------------------------
2765 * WriteConsoleOutputAttribute
2766 *
2767 * @implemented
2768 */
2769 BOOL
2770 WINAPI
2771 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
2772 CONST WORD *lpAttribute,
2773 DWORD nLength,
2774 COORD dwWriteCoord,
2775 LPDWORD lpNumberOfAttrsWritten)
2776 {
2777 PCSR_API_MESSAGE Request;
2778 ULONG CsrRequest;
2779 NTSTATUS Status;
2780 WORD Size;
2781
2782 Request = RtlAllocateHeap(RtlGetProcessHeap(),
2783 0,
2784 max(sizeof(CSR_API_MESSAGE),
2785 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB)
2786 + min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD)) * sizeof(WORD)));
2787 if (Request == NULL)
2788 {
2789 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2790 return FALSE;
2791 }
2792
2793 CsrRequest = MAKE_CSR_API(WRITE_CONSOLE_OUTPUT_ATTRIB, CSR_CONSOLE);
2794 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2795
2796 if (lpNumberOfAttrsWritten)
2797 *lpNumberOfAttrsWritten = nLength;
2798 while (nLength)
2799 {
2800 Size = (WORD)min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB / sizeof(WORD));
2801 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2802 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2803 memcpy(Request->Data.WriteConsoleOutputAttribRequest.Attribute, lpAttribute, Size * sizeof(WORD));
2804
2805 Status = CsrClientCallServer(Request,
2806 NULL,
2807 CsrRequest,
2808 max(sizeof(CSR_API_MESSAGE),
2809 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB) + Size * sizeof(WORD)));
2810
2811 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
2812 {
2813 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2814 SetLastErrorByStatus (Status);
2815 return FALSE;
2816 }
2817 nLength -= Size;
2818 lpAttribute += Size;
2819 Request->Data.WriteConsoleOutputAttribRequest.Coord = Request->Data.WriteConsoleOutputAttribRequest.EndCoord;
2820 }
2821
2822 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
2823
2824 return TRUE;
2825 }
2826
2827
2828 /*--------------------------------------------------------------
2829 * FillConsoleOutputAttribute
2830 *
2831 * @implemented
2832 */
2833 BOOL
2834 WINAPI
2835 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
2836 WORD wAttribute,
2837 DWORD nLength,
2838 COORD dwWriteCoord,
2839 LPDWORD lpNumberOfAttrsWritten)
2840 {
2841 CSR_API_MESSAGE Request;
2842 ULONG CsrRequest;
2843 NTSTATUS Status;
2844
2845 CsrRequest = MAKE_CSR_API(FILL_OUTPUT_ATTRIB, CSR_CONSOLE);
2846 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2847 Request.Data.FillOutputAttribRequest.Attribute = (CHAR)wAttribute;
2848 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2849 Request.Data.FillOutputAttribRequest.Length = (WORD)nLength;
2850
2851 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2852 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2853 {
2854 SetLastErrorByStatus ( Status );
2855 return FALSE;
2856 }
2857
2858 if (lpNumberOfAttrsWritten)
2859 *lpNumberOfAttrsWritten = nLength;
2860
2861 return TRUE;
2862 }
2863
2864
2865 /*--------------------------------------------------------------
2866 * GetConsoleMode
2867 *
2868 * @implemented
2869 */
2870 BOOL
2871 WINAPI
2872 GetConsoleMode(HANDLE hConsoleHandle,
2873 LPDWORD lpMode)
2874 {
2875 CSR_API_MESSAGE Request;
2876 ULONG CsrRequest;
2877 NTSTATUS Status;
2878
2879 CsrRequest = MAKE_CSR_API(GET_CONSOLE_MODE, CSR_CONSOLE);
2880 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2881
2882 Status = CsrClientCallServer( &Request, NULL, CsrRequest, sizeof( CSR_API_MESSAGE ) );
2883 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2884 {
2885 SetLastErrorByStatus ( Status );
2886 return FALSE;
2887 }
2888 *lpMode = Request.Data.GetConsoleModeRequest.ConsoleMode;
2889
2890 return TRUE;
2891 }
2892
2893
2894 /*--------------------------------------------------------------
2895 * GetNumberOfConsoleInputEvents
2896 *
2897 * @implemented
2898 */
2899 BOOL
2900 WINAPI
2901 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
2902 LPDWORD lpNumberOfEvents)
2903 {
2904 CSR_API_MESSAGE Request;
2905 ULONG CsrRequest;
2906 NTSTATUS Status;
2907
2908 if (lpNumberOfEvents == NULL)
2909 {
2910 SetLastError(ERROR_INVALID_PARAMETER);
2911 return FALSE;
2912 }
2913
2914 CsrRequest = MAKE_CSR_API(GET_NUM_INPUT_EVENTS, CSR_CONSOLE);
2915 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2916
2917 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2918 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2919 {
2920 SetLastErrorByStatus(Status);
2921 return FALSE;
2922 }
2923
2924 *lpNumberOfEvents = Request.Data.GetNumInputEventsRequest.NumInputEvents;
2925
2926 return TRUE;
2927 }
2928
2929
2930 /*--------------------------------------------------------------
2931 * GetLargestConsoleWindowSize
2932 *
2933 * @unimplemented
2934 */
2935 COORD
2936 WINAPI
2937 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
2938 {
2939 COORD Coord = {80,25};
2940 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
2941 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2942 return Coord;
2943 }
2944
2945
2946 /*--------------------------------------------------------------
2947 * GetConsoleCursorInfo
2948 *
2949 * @implemented
2950 */
2951 BOOL
2952 WINAPI
2953 GetConsoleCursorInfo(HANDLE hConsoleOutput,
2954 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
2955 {
2956 CSR_API_MESSAGE Request;
2957 ULONG CsrRequest;
2958 NTSTATUS Status;
2959
2960 if (!lpConsoleCursorInfo)
2961 {
2962 if (!hConsoleOutput)
2963 SetLastError(ERROR_INVALID_HANDLE);
2964 else
2965 SetLastError(ERROR_INVALID_ACCESS);
2966
2967 return FALSE;
2968 }
2969
2970 CsrRequest = MAKE_CSR_API(GET_CURSOR_INFO, CSR_CONSOLE);
2971 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2972
2973 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
2974
2975 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
2976 {
2977 SetLastErrorByStatus(Status);
2978 return FALSE;
2979 }
2980 *lpConsoleCursorInfo = Request.Data.GetCursorInfoRequest.Info;
2981
2982 return TRUE;
2983 }
2984
2985
2986 /*--------------------------------------------------------------
2987 * GetNumberOfConsoleMouseButtons
2988 *
2989 * @unimplemented
2990 */
2991 BOOL
2992 WINAPI
2993 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
2994 {
2995 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
2996 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2997 return FALSE;
2998 }
2999
3000
3001 /*--------------------------------------------------------------
3002 * SetConsoleMode
3003 *
3004 * @implemented
3005 */
3006 BOOL
3007 WINAPI
3008 SetConsoleMode(HANDLE hConsoleHandle,
3009 DWORD dwMode)
3010 {
3011 CSR_API_MESSAGE Request;
3012 ULONG CsrRequest;
3013 NTSTATUS Status;
3014
3015 CsrRequest = MAKE_CSR_API(SET_CONSOLE_MODE, CSR_CONSOLE);
3016 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
3017 Request.Data.SetConsoleModeRequest.Mode = dwMode;
3018
3019 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3020 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3021 {
3022 SetLastErrorByStatus ( Status );
3023 return FALSE;
3024 }
3025
3026 return TRUE;
3027 }
3028
3029
3030 /*--------------------------------------------------------------
3031 * SetConsoleActiveScreenBuffer
3032 *
3033 * @implemented
3034 */
3035 BOOL
3036 WINAPI
3037 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
3038 {
3039 CSR_API_MESSAGE Request;
3040 ULONG CsrRequest;
3041 NTSTATUS Status;
3042
3043 CsrRequest = MAKE_CSR_API(SET_SCREEN_BUFFER, CSR_CONSOLE);
3044 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
3045
3046 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3047 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3048 {
3049 SetLastErrorByStatus(Status);
3050 return FALSE;
3051 }
3052
3053 return TRUE;
3054 }
3055
3056
3057 /*--------------------------------------------------------------
3058 * FlushConsoleInputBuffer
3059 *
3060 * @implemented
3061 */
3062 BOOL
3063 WINAPI
3064 FlushConsoleInputBuffer(HANDLE hConsoleInput)
3065 {
3066 CSR_API_MESSAGE Request;
3067 ULONG CsrRequest;
3068 NTSTATUS Status;
3069
3070 CsrRequest = MAKE_CSR_API(FLUSH_INPUT_BUFFER, CSR_CONSOLE);
3071 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
3072
3073 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3074 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3075 {
3076 SetLastErrorByStatus(Status);
3077 return FALSE;
3078 }
3079
3080 return TRUE;
3081 }
3082
3083
3084 /*--------------------------------------------------------------
3085 * SetConsoleScreenBufferSize
3086 *
3087 * @unimplemented
3088 */
3089 BOOL
3090 WINAPI
3091 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
3092 COORD dwSize)
3093 {
3094 DPRINT1("SetConsoleScreenBufferSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, dwSize);
3095 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3096 return FALSE;
3097 }
3098
3099 /*--------------------------------------------------------------
3100 * SetConsoleCursorInfo
3101 *
3102 * @implemented
3103 */
3104 BOOL
3105 WINAPI
3106 SetConsoleCursorInfo(HANDLE hConsoleOutput,
3107 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
3108 {
3109 CSR_API_MESSAGE Request;
3110 ULONG CsrRequest;
3111 NTSTATUS Status;
3112
3113 CsrRequest = MAKE_CSR_API(SET_CURSOR_INFO, CSR_CONSOLE);
3114 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
3115 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
3116
3117 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3118 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3119 {
3120 SetLastErrorByStatus(Status);
3121 return FALSE;
3122 }
3123
3124 return TRUE;
3125 }
3126
3127
3128 static
3129 BOOL
3130 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
3131 const SMALL_RECT *lpScrollRectangle,
3132 const SMALL_RECT *lpClipRectangle,
3133 COORD dwDestinationOrigin,
3134 const CHAR_INFO *lpFill,
3135 BOOL bUnicode)
3136 {
3137 CSR_API_MESSAGE Request;
3138 ULONG CsrRequest;
3139 NTSTATUS Status;
3140
3141 CsrRequest = MAKE_CSR_API(SCROLL_CONSOLE_SCREEN_BUFFER, CSR_CONSOLE);
3142 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
3143 Request.Data.ScrollConsoleScreenBufferRequest.Unicode = bUnicode;
3144 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
3145
3146 if (lpClipRectangle != NULL)
3147 {
3148 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
3149 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
3150 }
3151 else
3152 {
3153 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
3154 }
3155
3156 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
3157 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
3158
3159 Status = CsrClientCallServer(&Request,
3160 NULL,
3161 CsrRequest,
3162 sizeof(CSR_API_MESSAGE));
3163
3164 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3165 {
3166 SetLastErrorByStatus(Status);
3167 return FALSE;
3168 }
3169
3170 return TRUE;
3171 }
3172
3173
3174 /*--------------------------------------------------------------
3175 * ScrollConsoleScreenBufferA
3176 *
3177 * @implemented
3178 */
3179 BOOL
3180 WINAPI
3181 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
3182 CONST SMALL_RECT *lpScrollRectangle,
3183 CONST SMALL_RECT *lpClipRectangle,
3184 COORD dwDestinationOrigin,
3185 CONST CHAR_INFO *lpFill)
3186 {
3187 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3188 (PSMALL_RECT)lpScrollRectangle,
3189 (PSMALL_RECT)lpClipRectangle,
3190 dwDestinationOrigin,
3191 (PCHAR_INFO)lpFill,
3192 FALSE);
3193 }
3194
3195
3196 /*--------------------------------------------------------------
3197 * ScrollConsoleScreenBufferW
3198 *
3199 * @implemented
3200 */
3201 BOOL
3202 WINAPI
3203 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
3204 CONST SMALL_RECT *lpScrollRectangle,
3205 CONST SMALL_RECT *lpClipRectangle,
3206 COORD dwDestinationOrigin,
3207 CONST CHAR_INFO *lpFill)
3208 {
3209 return IntScrollConsoleScreenBuffer(hConsoleOutput,
3210 lpScrollRectangle,
3211 lpClipRectangle,
3212 dwDestinationOrigin,
3213 lpFill,
3214 TRUE);
3215 }
3216
3217
3218 /*--------------------------------------------------------------
3219 * SetConsoleWindowInfo
3220 *
3221 * @unimplemented
3222 */
3223 BOOL
3224 WINAPI
3225 SetConsoleWindowInfo(HANDLE hConsoleOutput,
3226 BOOL bAbsolute,
3227 CONST SMALL_RECT *lpConsoleWindow)
3228 {
3229 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
3230 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3231 return FALSE;
3232 }
3233
3234
3235 /*--------------------------------------------------------------
3236 * SetConsoleTextAttribute
3237 *
3238 * @implemented
3239 */
3240 BOOL
3241 WINAPI
3242 SetConsoleTextAttribute(HANDLE hConsoleOutput,
3243 WORD wAttributes)
3244 {
3245 CSR_API_MESSAGE Request;
3246 ULONG CsrRequest;
3247 NTSTATUS Status;
3248
3249 CsrRequest = MAKE_CSR_API(SET_ATTRIB, CSR_CONSOLE);
3250 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
3251 Request.Data.SetAttribRequest.Attrib = wAttributes;
3252
3253 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3254 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3255 {
3256 SetLastErrorByStatus(Status);
3257 return FALSE;
3258 }
3259
3260 return TRUE;
3261 }
3262
3263
3264 static
3265 BOOL
3266 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3267 {
3268 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
3269
3270 if (HandlerRoutine == NULL)
3271 {
3272 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
3273 return TRUE;
3274 }
3275
3276 if (NrCtrlHandlers == NrAllocatedHandlers)
3277 {
3278 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
3279 0,
3280 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
3281 if (NewCtrlHandlers == NULL)
3282 {
3283 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3284 return FALSE;
3285 }
3286
3287 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
3288
3289 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
3290
3291 CtrlHandlers = NewCtrlHandlers;
3292 NrAllocatedHandlers += 4;
3293 }
3294
3295 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
3296
3297 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
3298 return TRUE;
3299 }
3300
3301
3302 static
3303 BOOL
3304 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
3305 {
3306 ULONG i;
3307
3308 if (HandlerRoutine == NULL)
3309 {
3310 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
3311 return TRUE;
3312 }
3313
3314 for (i = 0; i < NrCtrlHandlers; i++)
3315 {
3316 if (CtrlHandlers[i] == HandlerRoutine)
3317 {
3318 if (i < (NrCtrlHandlers - 1))
3319 {
3320 memmove(&CtrlHandlers[i],
3321 &CtrlHandlers[i+1],
3322 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
3323 }
3324
3325 NrCtrlHandlers--;
3326 return TRUE;
3327 }
3328 }
3329
3330 SetLastError(ERROR_INVALID_PARAMETER);
3331 return FALSE;
3332 }
3333
3334
3335 /*
3336 * @implemented
3337 */
3338 BOOL
3339 WINAPI
3340 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
3341 BOOL Add)
3342 {
3343 BOOL Ret;
3344
3345 RtlEnterCriticalSection(&DllLock);
3346 if (Add)
3347 {
3348 Ret = AddConsoleCtrlHandler(HandlerRoutine);
3349 }
3350 else
3351 {
3352 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
3353 }
3354
3355 RtlLeaveCriticalSection(&DllLock);
3356 return(Ret);
3357 }
3358
3359
3360 /*--------------------------------------------------------------
3361 * GenerateConsoleCtrlEvent
3362 *
3363 * @implemented
3364 */
3365 BOOL
3366 WINAPI
3367 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
3368 DWORD dwProcessGroupId)
3369 {
3370 CSR_API_MESSAGE Request;
3371 ULONG CsrRequest;
3372 NTSTATUS Status;
3373
3374 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
3375 {
3376 SetLastError(ERROR_INVALID_PARAMETER);
3377 return FALSE;
3378 }
3379
3380 CsrRequest = MAKE_CSR_API(GENERATE_CTRL_EVENT, CSR_CONSOLE);
3381 Request.Data.GenerateCtrlEvent.Event = dwCtrlEvent;
3382 Request.Data.GenerateCtrlEvent.ProcessGroup = dwProcessGroupId;
3383
3384 Status = CsrClientCallServer(&Request,
3385 NULL,
3386 CsrRequest,
3387 sizeof(CSR_API_MESSAGE));
3388 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request.Status)))
3389 {
3390 SetLastErrorByStatus(Status);
3391 return FALSE;
3392 }
3393
3394 return TRUE;
3395 }
3396
3397
3398 /*--------------------------------------------------------------
3399 * GetConsoleTitleW
3400 *
3401 * @implemented
3402 */
3403 DWORD
3404 WINAPI
3405 GetConsoleTitleW(LPWSTR lpConsoleTitle,
3406 DWORD nSize)
3407 {
3408 PCSR_API_MESSAGE Request;
3409 ULONG CsrRequest;
3410 NTSTATUS Status;
3411
3412 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3413 0,
3414 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3415 if (Request == NULL)
3416 {
3417 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3418 return FALSE;
3419 }
3420
3421 CsrRequest = MAKE_CSR_API(GET_TITLE, CSR_CONSOLE);
3422
3423 Status = CsrClientCallServer(Request,
3424 NULL,
3425 CsrRequest,
3426 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_TITLE) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
3427 if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Request->Status)))
3428 {
3429 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3430 SetLastErrorByStatus(Status);
3431 return 0;
3432 }
3433
3434 if (nSize * sizeof(WCHAR) <= Request->Data.GetTitleRequest.Length)
3435 {
3436 nSize--;
3437 }
3438 else
3439 {
3440 nSize = Request->Data.GetTitleRequest.Length / sizeof (WCHAR);
3441 }
3442 memcpy(lpConsoleTitle, Request->Data.GetTitleRequest.Title, nSize * sizeof(WCHAR));
3443 lpConsoleTitle[nSize] = L'\0';
3444
3445 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3446
3447 return nSize;
3448 }
3449
3450
3451 /*--------------------------------------------------------------
3452 * GetConsoleTitleA
3453 *
3454 * 19990306 EA
3455 *
3456 * @implemented
3457 */
3458 DWORD
3459 WINAPI
3460 GetConsoleTitleA(LPSTR lpConsoleTitle,
3461 DWORD nSize)
3462 {
3463 WCHAR WideTitle [CSRSS_MAX_TITLE_LENGTH + 1];
3464 DWORD nWideTitle = CSRSS_MAX_TITLE_LENGTH + 1;
3465 DWORD nWritten;
3466
3467 if (!lpConsoleTitle || !nSize) return 0;
3468 nWideTitle = GetConsoleTitleW((LPWSTR) WideTitle, nWideTitle);
3469 if (!nWideTitle) return 0;
3470
3471 if ((nWritten = WideCharToMultiByte(CP_ACP, // ANSI code page
3472 0, // performance and mapping flags
3473 (LPWSTR) WideTitle, // address of wide-character string
3474 nWideTitle, // number of characters in string
3475 lpConsoleTitle, // address of buffer for new string
3476 nSize - 1, // size of buffer
3477 NULL, // FAST
3478 NULL))) // FAST
3479 {
3480 lpConsoleTitle[nWritten] = '\0';
3481 return nWritten;
3482 }
3483
3484 return 0;
3485 }
3486
3487
3488 /*--------------------------------------------------------------
3489 * SetConsoleTitleW
3490 *
3491 * @implemented
3492 */
3493 BOOL
3494 WINAPI
3495 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
3496 {
3497 PCSR_API_MESSAGE Request;
3498 ULONG CsrRequest;
3499 NTSTATUS Status;
3500 unsigned int c;
3501
3502 Request = RtlAllocateHeap(RtlGetProcessHeap(), 0,
3503 max(sizeof(CSR_API_MESSAGE),
3504 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3505 min(wcslen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3506 if (Request == NULL)
3507 {
3508 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3509 return FALSE;
3510 }
3511
3512 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3513
3514 for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++)
3515 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3516
3517 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3518 Status = CsrClientCallServer(Request,
3519 NULL,
3520 CsrRequest,
3521 max(sizeof(CSR_API_MESSAGE),
3522 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3523 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3524 {
3525 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3526 SetLastErrorByStatus(Status);
3527 return(FALSE);
3528 }
3529
3530 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3531
3532 return TRUE;
3533 }
3534
3535
3536 /*--------------------------------------------------------------
3537 * SetConsoleTitleA
3538 *
3539 * 19990204 EA Added
3540 *
3541 * @implemented
3542 */
3543 BOOL
3544 WINAPI
3545 SetConsoleTitleA(LPCSTR lpConsoleTitle)
3546 {
3547 PCSR_API_MESSAGE Request;
3548 ULONG CsrRequest;
3549 NTSTATUS Status;
3550 unsigned int c;
3551
3552 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3553 0,
3554 max(sizeof(CSR_API_MESSAGE),
3555 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) +
3556 min(strlen(lpConsoleTitle), CSRSS_MAX_TITLE_LENGTH) * sizeof(WCHAR)));
3557 if (Request == NULL)
3558 {
3559 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3560 return FALSE;
3561 }
3562
3563 CsrRequest = MAKE_CSR_API(SET_TITLE, CSR_CONSOLE);
3564
3565 for (c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++)
3566 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
3567
3568 Request->Data.SetTitleRequest.Length = c * sizeof(WCHAR);
3569 Status = CsrClientCallServer(Request,
3570 NULL,
3571 CsrRequest,
3572 max(sizeof(CSR_API_MESSAGE),
3573 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_SET_TITLE) + c * sizeof(WCHAR)));
3574 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3575 {
3576 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3577 SetLastErrorByStatus(Status);
3578 return(FALSE);
3579 }
3580
3581 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3582
3583 return TRUE;
3584 }
3585
3586
3587 /*--------------------------------------------------------------
3588 * CreateConsoleScreenBuffer
3589 *
3590 * @implemented
3591 */
3592 HANDLE
3593 WINAPI
3594 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
3595 DWORD dwShareMode,
3596 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3597 DWORD dwFlags,
3598 LPVOID lpScreenBufferData)
3599 {
3600 CSR_API_MESSAGE Request;
3601 ULONG CsrRequest;
3602 NTSTATUS Status;
3603
3604 if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)
3605 || dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)
3606 || dwFlags != CONSOLE_TEXTMODE_BUFFER)
3607 {
3608 SetLastError(ERROR_INVALID_PARAMETER);
3609 return INVALID_HANDLE_VALUE;
3610 }
3611
3612 Request.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
3613 Request.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
3614 Request.Data.CreateScreenBufferRequest.Inheritable =
3615 lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE;
3616
3617 CsrRequest = MAKE_CSR_API(CREATE_SCREEN_BUFFER, CSR_CONSOLE);
3618 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3619 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3620 {
3621 SetLastErrorByStatus(Status);
3622 return INVALID_HANDLE_VALUE;
3623 }
3624 return Request.Data.CreateScreenBufferRequest.OutputHandle;
3625 }
3626
3627
3628 /*--------------------------------------------------------------
3629 * GetConsoleCP
3630 *
3631 * @implemented
3632 */
3633 UINT
3634 WINAPI
3635 GetConsoleCP(VOID)
3636 {
3637 CSR_API_MESSAGE Request;
3638 ULONG CsrRequest;
3639 NTSTATUS Status;
3640
3641 CsrRequest = MAKE_CSR_API(GET_CONSOLE_CP, CSR_CONSOLE);
3642 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3643 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3644 {
3645 SetLastErrorByStatus (Status);
3646 return 0;
3647 }
3648
3649 return Request.Data.GetConsoleCodePage.CodePage;
3650 }
3651
3652
3653 /*--------------------------------------------------------------
3654 * SetConsoleCP
3655 *
3656 * @implemented
3657 */
3658 BOOL
3659 WINAPI
3660 SetConsoleCP(UINT wCodePageID)
3661 {
3662 CSR_API_MESSAGE Request;
3663 ULONG CsrRequest;
3664 NTSTATUS Status;
3665
3666 CsrRequest = MAKE_CSR_API(SET_CONSOLE_CP, CSR_CONSOLE);
3667 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3668
3669 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3670 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3671 {
3672 SetLastErrorByStatus(Status);
3673 }
3674
3675 return NT_SUCCESS(Status);
3676 }
3677
3678
3679 /*--------------------------------------------------------------
3680 * GetConsoleOutputCP
3681 *
3682 * @implemented
3683 */
3684 UINT
3685 WINAPI
3686 GetConsoleOutputCP(VOID)
3687 {
3688 CSR_API_MESSAGE Request;
3689 ULONG CsrRequest;
3690 NTSTATUS Status;
3691
3692 CsrRequest = MAKE_CSR_API(GET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3693 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3694 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3695 {
3696 SetLastErrorByStatus (Status);
3697 return 0;
3698 }
3699
3700 return Request.Data.GetConsoleOutputCodePage.CodePage;
3701 }
3702
3703
3704 /*--------------------------------------------------------------
3705 * SetConsoleOutputCP
3706 *
3707 * @implemented
3708 */
3709 BOOL
3710 WINAPI
3711 SetConsoleOutputCP(UINT wCodePageID)
3712 {
3713 CSR_API_MESSAGE Request;
3714 ULONG CsrRequest;
3715 NTSTATUS Status;
3716
3717 CsrRequest = MAKE_CSR_API(SET_CONSOLE_OUTPUT_CP, CSR_CONSOLE);
3718 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3719 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3720 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3721 {
3722 SetLastErrorByStatus(Status);
3723 }
3724
3725 return NT_SUCCESS(Status);
3726 }
3727
3728
3729 /*--------------------------------------------------------------
3730 * GetConsoleProcessList
3731 *
3732 * @implemented
3733 */
3734 DWORD
3735 WINAPI
3736 GetConsoleProcessList(LPDWORD lpdwProcessList,
3737 DWORD dwProcessCount)
3738 {
3739 PCSR_API_MESSAGE Request;
3740 ULONG CsrRequest;
3741 ULONG nProcesses;
3742 NTSTATUS Status;
3743
3744 if (lpdwProcessList == NULL || dwProcessCount == 0)
3745 {
3746 SetLastError(ERROR_INVALID_PARAMETER);
3747 return 0;
3748 }
3749
3750 Request = RtlAllocateHeap(RtlGetProcessHeap(),
3751 0,
3752 max(sizeof(CSR_API_MESSAGE),
3753 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3754 + min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD)) * sizeof(DWORD)));
3755 if (Request == NULL)
3756 {
3757 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3758 return FALSE;
3759 }
3760
3761 CsrRequest = MAKE_CSR_API(GET_PROCESS_LIST, CSR_CONSOLE);
3762 Request->Data.GetProcessListRequest.nMaxIds = min (dwProcessCount, CSRSS_MAX_GET_PROCESS_LIST / sizeof(DWORD));
3763
3764 Status = CsrClientCallServer(Request,
3765 NULL,
3766 CsrRequest,
3767 max(sizeof(CSR_API_MESSAGE),
3768 CSR_API_MESSAGE_HEADER_SIZE(CSRSS_GET_PROCESS_LIST)
3769 + Request->Data.GetProcessListRequest.nMaxIds * sizeof(DWORD)));
3770 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request->Status))
3771 {
3772 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3773 SetLastErrorByStatus (Status);
3774 nProcesses = 0;
3775 }
3776 else
3777 {
3778 nProcesses = Request->Data.GetProcessListRequest.nProcessIdsCopied;
3779 if (dwProcessCount >= nProcesses)
3780 {
3781 memcpy(lpdwProcessList, Request->Data.GetProcessListRequest.ProcessId, nProcesses * sizeof(DWORD));
3782 }
3783 }
3784
3785 RtlFreeHeap(RtlGetProcessHeap(), 0, Request);
3786
3787 return nProcesses;
3788 }
3789
3790
3791
3792 /*--------------------------------------------------------------
3793 * GetConsoleSelectionInfo
3794 *
3795 * @unimplemented
3796 */
3797 BOOL
3798 WINAPI
3799 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3800 {
3801 DPRINT1("GetConsoleSelectionInfo(0x%x) UNIMPLEMENTED!\n", lpConsoleSelectionInfo);
3802 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3803 return FALSE;
3804 }
3805
3806
3807
3808 /*--------------------------------------------------------------
3809 * AttachConsole
3810 *
3811 * @unimplemented
3812 */
3813 BOOL
3814 WINAPI
3815 AttachConsole(DWORD dwProcessId)
3816 {
3817 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
3818 return TRUE;
3819 }
3820
3821 /*--------------------------------------------------------------
3822 * GetConsoleWindow
3823 *
3824 * @implemented
3825 */
3826 HWND
3827 WINAPI
3828 GetConsoleWindow(VOID)
3829 {
3830 CSR_API_MESSAGE Request;
3831 ULONG CsrRequest;
3832 NTSTATUS Status;
3833
3834 CsrRequest = MAKE_CSR_API(GET_CONSOLE_WINDOW, CSR_CONSOLE);
3835 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3836 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Request.Status))
3837 {
3838 SetLastErrorByStatus(Status);
3839 return (HWND) NULL;
3840 }
3841
3842 return Request.Data.GetConsoleWindowRequest.WindowHandle;
3843 }
3844
3845
3846 /*--------------------------------------------------------------
3847 * SetConsoleIcon
3848 *
3849 * @implemented
3850 */
3851 BOOL
3852 WINAPI
3853 SetConsoleIcon(HICON hicon)
3854 {
3855 CSR_API_MESSAGE Request;
3856 ULONG CsrRequest;
3857 NTSTATUS Status;
3858
3859 CsrRequest = MAKE_CSR_API(SET_CONSOLE_ICON, CSR_CONSOLE);
3860 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3861
3862 Status = CsrClientCallServer(&Request, NULL, CsrRequest, sizeof(CSR_API_MESSAGE));
3863 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
3864 {
3865 SetLastErrorByStatus(Status);
3866 return FALSE;
3867 }
3868
3869 return NT_SUCCESS(Status);
3870 }
3871
3872
3873 /******************************************************************************
3874 * \name SetConsoleInputExeNameW
3875 * \brief Sets the console input file name from a unicode string.
3876 * \param lpInputExeName Pointer to a unicode string with the name.
3877 * \return TRUE if successful, FALSE if unsuccsedful.
3878 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
3879 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
3880 */
3881 BOOL
3882 WINAPI
3883 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
3884 {
3885 int lenName;
3886
3887 if (!lpInputExeName
3888 || (lenName = lstrlenW(lpInputExeName)) == 0
3889 || lenName > INPUTEXENAME_BUFLEN - 1)
3890 {
3891 /* Fail if string is empty or too long */
3892 SetLastError(ERROR_INVALID_PARAMETER);
3893 return FALSE;
3894 }
3895
3896 RtlEnterCriticalSection(&ConsoleLock);
3897 _SEH2_TRY
3898 {
3899 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
3900 InputExeName[lenName] = L'\0';
3901 }
3902 _SEH2_FINALLY
3903 {
3904 RtlLeaveCriticalSection(&ConsoleLock);
3905 }
3906 _SEH2_END;
3907
3908 return TRUE;
3909 }
3910
3911
3912 /******************************************************************************
3913 * \name SetConsoleInputExeNameA
3914 * \brief Sets the console input file name from an ansi string.
3915 * \param lpInputExeName Pointer to an ansi string with the name.
3916 * \return TRUE if successful, FALSE if unsuccsedful.
3917 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
3918 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
3919 */
3920 BOOL
3921 WINAPI
3922 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
3923 {
3924 WCHAR Buffer[INPUTEXENAME_BUFLEN];
3925 ANSI_STRING InputExeNameA;
3926 UNICODE_STRING InputExeNameU;
3927 NTSTATUS Status;
3928 BOOL Ret;
3929
3930 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
3931
3932 if(InputExeNameA.Length == 0 ||
3933 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
3934 {
3935 /* Fail if string is empty or too long */
3936 SetLastError(ERROR_INVALID_PARAMETER);
3937 return FALSE;
3938 }
3939
3940 InputExeNameU.Buffer = Buffer;
3941 InputExeNameU.MaximumLength = sizeof(Buffer);
3942 InputExeNameU.Length = 0;
3943 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
3944 if(NT_SUCCESS(Status))
3945 {
3946 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
3947 }
3948 else
3949 {
3950 SetLastErrorByStatus(Status);
3951 Ret = FALSE;
3952 }
3953
3954 return Ret;
3955 }
3956
3957
3958 /******************************************************************************
3959 * \name GetConsoleInputExeNameW
3960 * \brief Retrieves the console input file name as unicode string.
3961 * \param nBufferLength Length of the buffer in WCHARs.
3962 * Specify 0 to recieve the needed buffer length.
3963 * \param lpBuffer Pointer to a buffer that recieves the string.
3964 * \return Needed buffer size if \p nBufferLength is 0.
3965 * Otherwise 1 if successful, 2 if buffer is too small.
3966 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
3967 * is not big enough.
3968 */
3969 DWORD
3970 WINAPI
3971 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
3972 {
3973 int lenName = lstrlenW(InputExeName);
3974
3975 if (nBufferLength == 0)
3976 {
3977 /* Buffer size is requested, return it */
3978 return lenName + 1;
3979 }
3980
3981 if(lenName + 1 > nBufferLength)
3982 {
3983 /* Buffer is not large enough! */
3984 SetLastError(ERROR_BUFFER_OVERFLOW);
3985 return 2;
3986 }
3987
3988 RtlEnterCriticalSection(&ConsoleLock);
3989 _SEH2_TRY
3990 {
3991 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
3992 lpBuffer[lenName] = '\0';
3993 }
3994 _SEH2_FINALLY
3995 {
3996 RtlLeaveCriticalSection(&ConsoleLock);
3997 }
3998 _SEH2_END;
3999
4000 /* Success, return 1 */
4001 return 1;
4002 }
4003
4004
4005 /******************************************************************************
4006 * \name GetConsoleInputExeNameA
4007 * \brief Retrieves the console input file name as ansi string.
4008 * \param nBufferLength Length of the buffer in CHARs.
4009 * \param lpBuffer Pointer to a buffer that recieves the string.
4010 * \return 1 if successful, 2 if buffer is too small.
4011 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
4012 * is not big enough. The buffer recieves as much characters as fit.
4013 */
4014 DWORD
4015 WINAPI
4016 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
4017 {
4018 WCHAR Buffer[INPUTEXENAME_BUFLEN];
4019 DWORD Ret;
4020 UNICODE_STRING BufferU;
4021 ANSI_STRING BufferA;
4022
4023 /* Get the unicode name */
4024 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
4025
4026 /* Initialize strings for conversion */
4027 RtlInitUnicodeString(&BufferU, Buffer);
4028 BufferA.Length = 0;
4029 BufferA.MaximumLength = nBufferLength;
4030 BufferA.Buffer = lpBuffer;
4031
4032 /* Convert unicode name to ansi, copying as much chars as fit */
4033 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
4034
4035 /* Error handling */
4036 if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
4037 {
4038 SetLastError(ERROR_BUFFER_OVERFLOW);
4039 return 2;
4040 }
4041
4042 return Ret;
4043 }
4044
4045
4046 /*--------------------------------------------------------------
4047 * GetConsoleHistoryInfo
4048 *
4049 * @unimplemented
4050 */
4051 BOOL
4052 WINAPI
4053 GetConsoleHistoryInfo(PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
4054 {
4055 DPRINT1("GetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
4056 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4057 return FALSE;
4058 }
4059
4060
4061 /*--------------------------------------------------------------
4062 * SetConsoleHistoryInfo
4063 *
4064 * @unimplemented
4065 */
4066 BOOL
4067 WINAPI
4068 SetConsoleHistoryInfo(IN PCONSOLE_HISTORY_INFO lpConsoleHistoryInfo)
4069 {
4070 DPRINT1("SetConsoleHistoryInfo(0x%p) UNIMPLEMENTED!\n", lpConsoleHistoryInfo);
4071 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4072 return FALSE;
4073 }
4074
4075
4076 /*--------------------------------------------------------------
4077 * GetConsoleOriginalTitleW
4078 *
4079 * @unimplemented
4080 */
4081 DWORD
4082 WINAPI
4083 GetConsoleOriginalTitleW(OUT LPWSTR lpConsoleTitle,
4084 IN DWORD nSize)
4085 {
4086 DPRINT1("GetConsoleOriginalTitleW(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4087 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4088 return 0;
4089 }
4090
4091
4092 /*--------------------------------------------------------------
4093 * GetConsoleOriginalTitleA
4094 *
4095 * @unimplemented
4096 */
4097 DWORD
4098 WINAPI
4099 GetConsoleOriginalTitleA(OUT LPSTR lpConsoleTitle,
4100 IN DWORD nSize)
4101 {
4102 DPRINT1("GetConsoleOriginalTitleA(0x%p, 0x%x) UNIMPLEMENTED!\n", lpConsoleTitle, nSize);
4103 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4104 return 0;
4105 }
4106
4107
4108 /*--------------------------------------------------------------
4109 * GetConsoleScreenBufferInfoEx
4110 *
4111 * @unimplemented
4112 */
4113 BOOL
4114 WINAPI
4115 GetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4116 OUT PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4117 {
4118 DPRINT1("GetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4119 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4120 return FALSE;
4121 }
4122
4123
4124 /*--------------------------------------------------------------
4125 * SetConsoleScreenBufferInfoEx
4126 *
4127 * @unimplemented
4128 */
4129 BOOL
4130 WINAPI
4131 SetConsoleScreenBufferInfoEx(IN HANDLE hConsoleOutput,
4132 IN PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx)
4133 {
4134 DPRINT1("SetConsoleScreenBufferInfoEx(0x%p, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, lpConsoleScreenBufferInfoEx);
4135 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4136 return FALSE;
4137 }
4138
4139
4140 /*--------------------------------------------------------------
4141 * GetCurrentConsoleFontEx
4142 *
4143 * @unimplemented
4144 */
4145 BOOL
4146 WINAPI
4147 GetCurrentConsoleFontEx(IN HANDLE hConsoleOutput,
4148 IN BOOL bMaximumWindow,
4149 OUT PCONSOLE_FONT_INFOEX lpConsoleCurrentFontEx)
4150 {
4151 DPRINT1("GetCurrentConsoleFontEx(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFontEx);
4152 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4153 return FALSE;
4154 }
4155
4156 /* EOF */