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