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