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